arb_stylus/
config.rs

1use crate::ink::Ink;
2
3use super::ink::Gas;
4
5/// Runtime configuration for a Stylus program execution.
6#[derive(Clone, Copy, Debug)]
7pub struct StylusConfig {
8    /// Version the program was compiled against.
9    pub version: u16,
10    /// Maximum stack depth in words.
11    pub max_depth: u32,
12    /// Pricing parameters for ink/gas conversion.
13    pub pricing: PricingParams,
14}
15
16impl Default for StylusConfig {
17    fn default() -> Self {
18        Self {
19            version: 0,
20            max_depth: u32::MAX,
21            pricing: PricingParams::default(),
22        }
23    }
24}
25
26impl StylusConfig {
27    pub const fn new(version: u16, max_depth: u32, ink_price: u32) -> Self {
28        Self {
29            version,
30            max_depth,
31            pricing: PricingParams::new(ink_price),
32        }
33    }
34}
35
36/// Pricing parameters for ink/gas conversion.
37#[derive(Clone, Copy, Debug)]
38pub struct PricingParams {
39    /// The price of ink, measured in bips of an EVM gas.
40    pub ink_price: u32,
41}
42
43impl Default for PricingParams {
44    fn default() -> Self {
45        Self { ink_price: 1 }
46    }
47}
48
49impl PricingParams {
50    pub const fn new(ink_price: u32) -> Self {
51        Self { ink_price }
52    }
53
54    /// Convert EVM gas to ink.
55    pub fn gas_to_ink(&self, gas: Gas) -> Ink {
56        Ink(gas.0.saturating_mul(self.ink_price as u64))
57    }
58
59    /// Convert ink to EVM gas.
60    pub fn ink_to_gas(&self, ink: Ink) -> Gas {
61        Gas(ink.0 / self.ink_price as u64)
62    }
63}
64
65/// Compile-time configuration for WASM module compilation.
66#[derive(Clone, Debug, Default)]
67pub struct CompileConfig {
68    /// Version of the compiler to use.
69    pub version: u16,
70    /// Pricing parameters for metering.
71    pub pricing: CompilePricingParams,
72    /// Memory bounds.
73    pub bounds: CompileMemoryParams,
74    /// Debug parameters.
75    pub debug: CompileDebugParams,
76}
77
78/// Memory bounds for WASM compilation.
79#[derive(Clone, Copy, Debug)]
80pub struct CompileMemoryParams {
81    /// Maximum number of WASM pages a program may start with.
82    pub heap_bound: u32,
83    /// Maximum size of a stack frame in words.
84    pub max_frame_size: u32,
85    /// Maximum overlapping value lifetimes in a frame.
86    pub max_frame_contention: u16,
87}
88
89impl Default for CompileMemoryParams {
90    fn default() -> Self {
91        Self {
92            heap_bound: u32::MAX / 65536, // Pages(u32::MAX / WASM_PAGE_SIZE)
93            max_frame_size: u32::MAX,
94            max_frame_contention: u16::MAX,
95        }
96    }
97}
98
99/// Pricing parameters for WASM compilation.
100#[derive(Clone, Debug, Default)]
101pub struct CompilePricingParams {
102    /// Cost of checking the amount of ink left.
103    pub ink_header_cost: u64,
104    /// Per-byte MemoryFill cost.
105    pub memory_fill_ink: u64,
106    /// Per-byte MemoryCopy cost.
107    pub memory_copy_ink: u64,
108}
109
110/// Debug parameters for WASM compilation.
111#[derive(Clone, Debug, Default)]
112pub struct CompileDebugParams {
113    /// Allow debug functions (console.log, etc.).
114    pub debug_funcs: bool,
115    /// Retain debug info in compiled modules.
116    pub debug_info: bool,
117    /// Add instrumentation to count opcode executions.
118    pub count_ops: bool,
119}
120
121impl CompileConfig {
122    /// Create a versioned compile config.
123    pub fn version(version: u16, debug_chain: bool) -> Self {
124        let mut config = Self {
125            version,
126            debug: CompileDebugParams {
127                debug_funcs: debug_chain,
128                debug_info: debug_chain,
129                ..Default::default()
130            },
131            ..Default::default()
132        };
133
134        match version {
135            0 => {}
136            1 | 2 => {
137                config.bounds.heap_bound = 128; // 128 pages = 8 MB
138                config.bounds.max_frame_size = 10 * 1024;
139                config.bounds.max_frame_contention = 4096;
140                config.pricing = CompilePricingParams {
141                    ink_header_cost: 2450,
142                    memory_fill_ink: 800 / 8,
143                    memory_copy_ink: 800 / 8,
144                };
145            }
146            _ => unreachable!("unsupported Stylus version {version}"),
147        }
148
149        config
150    }
151}