//! Shared primitive types, syscall indices, and constants used across the Fluentbase stack.
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

pub mod bincode;
mod block_fuel;
mod bytecode;
mod crypto_api;
mod curves;
mod eip2935;
mod exit_code;
pub mod fd;
mod genesis;
mod import_linker;
mod native_api;
#[cfg(target_arch = "wasm32")]
mod rwasm_context;
mod sys_func_idx;
mod syscall;
pub mod system;

pub use alloy_primitives::*;
pub use block_fuel::*;
pub use bytecode::*;
pub use byteorder;
pub use crypto_api::*;
pub use curves::*;
pub use eip2935::*;
pub use exit_code::*;
pub use genesis::*;
pub use hashbrown::{self, hash_map, hash_set, HashMap, HashSet};
pub use import_linker::*;
pub use native_api::*;
pub use paste;
#[cfg(target_arch = "wasm32")]
pub use rwasm_context::{bindings, RwasmContext};
pub use sys_func_idx::*;
pub use syscall::*;

pub const KECCAK_EMPTY: B256 =
    b256!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
pub const POSEIDON_EMPTY: B256 =
    b256!("2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864");

/// keccak256 of "Transfer(address,address,uint256)" that notifies
/// about native transfer of eth
pub const NATIVE_TRANSFER_KECCAK: B256 =
    b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
pub const NATIVE_TRANSFER_ADDRESS: Address = address!("0000000000000000000000000000000000000000");

pub const SYSTEM_ADDRESS: Address = address!("0xfffffffffffffffffffffffffffffffffffffffe");

pub const STATE_MAIN: u32 = 0;
pub const STATE_DEPLOY: u32 = 1;

pub const CALL_DEPTH_ROOT: u32 = 0;

/// A relation between fuel and gas,
/// according to our benchmarks, average WebAssembly instruction is ~20 times faster than average EVM
/// instruction.
///
/// The value can be changed in the future.
pub const FUEL_DENOM_RATE: u64 = 20;

/// The maximum allowed value for the `x` parameter used in linear gas cost calculation
/// of builtins.
/// This limit ensures:
/// 1. Runtime: all intermediate i32 operations do not overflow (WASM constraint)
/// 2. Compile-time: final fuel value fits in u32
///
/// Formula:
/// words = (x + 31) / 32
/// fuel = base_cost + word_cost × words
///
/// Derivation:
/// The bottleneck is I32Mul: words × word_cost ≤ i32::MAX
///
/// words ≈ x / 32, so:
/// (x / 32) × word_cost ≤ 2^31
/// x ≤ (2^31 × 32) / word_cost_max
///
/// Worst case (DEBUG_LOG with FUEL_DENOM_RATE = 20):
/// - word_cost_max = 16 × 20 = 320
///
/// x ≤ (2^31 × 32) / 320 = 214,748,364 bytes (~204 MB)
///
/// We use 128 MB as a safe limit within the theoretical maximum:
pub const FUEL_MAX_LINEAR_X: u32 = 134_217_728; // 128 MB (2^27)

/// The maximum allowed value for the `x` parameter used in quadratic gas cost calculation
/// of builtins.
/// This limit ensures:
/// 1. Runtime: words × words does not overflow i32 (WASM constraint)
/// 2. Compile-time: final fuel value fits in u32
///
/// Formula:
/// words = (x + 31) / 32
/// fuel = (word_cost × words + words² / divisor) × FUEL_DENOM_RATE
///
/// Derivation:
/// words × words must not overflow i32:
/// words² ≤ i32::MAX (2,147,483,647)
/// words ≤ 46,340
/// x ≤ 46,340 × 32 = 1,482,880 bytes (~1.4 MB)
///
/// We use 1.25 MB as a safe limit within the theoretical maximum:
pub const FUEL_MAX_QUADRATIC_X: u32 = 1_310_720; // 1.25 MB (2^20 + 2^18)

// Quadratic fuel constants (EVM memory expansion formula)
pub const QUADRATIC_WORD_FUEL_COST: u32 = 3;
pub const QUADRATIC_DIVISOR: u32 = 512;

/// A max rWasm call stack limit
pub const CALL_STACK_LIMIT: u32 = 1024;

/// WASM max code size
///
/// This value is temporary for testing purposes, requires recalculation.
/// The limit is equal to 2Mb.
pub const WASM_MAX_CODE_SIZE: usize = 0x100000;
#[cfg(feature = "svm")]
pub const SVM_MAX_CODE_SIZE: usize = 0x200000;

/// rWasm max code size
///
/// This limit is required to limit the number of bytes produced after Wasm binary compilation.
/// There are several attack vectors on this that produces abnormal amount of instructions.
pub const RWASM_MAX_CODE_SIZE: usize = 12 * 1024 * 1024;

/// WebAssembly magic bytes
///
/// These values are equal to \0ASM
pub const WASM_MAGIC_BYTES: [u8; 4] = [0x00, 0x61, 0x73, 0x6d];
/// Solana magic bytes
#[cfg(feature = "svm")]
pub const SVM_ELF_MAGIC_BYTES: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46];
/// ERC20 magic bytes: as char codes for "ERC" and the number 0x20
pub const UNIVERSAL_TOKEN_MAGIC_BYTES: [u8; 4] = [0x45, 0x52, 0x43, 0x20];

/// EIP-170: Contract code size limit
///
/// By default, the limit is `0x6000` (~25kb)
pub const EVM_MAX_CODE_SIZE: usize = 0x6000;

/// EIP-3860: Limit and meter initcode
///
/// Limit of maximum initcode size is `2 * WASM_MAX_CODE_SIZE`.
pub const EVM_MAX_INITCODE_SIZE: usize = 2 * EVM_MAX_CODE_SIZE;

pub const EIP7702_SIG_LEN: usize = 2;
/// rWASM binary format signature:
/// - 0xef 0x00 - EIP-3540 compatible prefix
/// - 0x52 - rWASM version number (equal to 'R')
pub const EIP7702_SIG: [u8; EIP7702_SIG_LEN] = [0xef, 0x01];

pub const WASM_SIG_LEN: usize = 4;
/// WebAssembly signature (\00ASM)
pub const WASM_SIG: [u8; WASM_SIG_LEN] = [0x00, 0x61, 0x73, 0x6d];

pub const RWASM_SIG_LEN: usize = 2;
/// rWASM binary format signature:
/// - 0xef 0x00 - EIP-3540 compatible prefix
/// - 0x52 - rWASM version number (equal to 'R')
pub const RWASM_SIG: [u8; RWASM_SIG_LEN] = [0xef, 0x52];

/// A maximum allowed bytes to be copied using EXT_CODE_COPY instruction
///
/// Technically we can't store a binary that exceeds rWasm module size (12MiB)
pub const EXT_CODE_COPY_MAX_COPY_SIZE: usize = RWASM_MAX_CODE_SIZE;
