From 71685cb7ffe381d3c9ae45b29c4e6bcda2cfa58a Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 3 Sep 2024 16:47:22 -0600 Subject: [PATCH 1/7] stylus: charge for wasm length in arbos v32 --- arbitrator/jit/src/program.rs | 5 +++-- arbitrator/prover/src/programs/mod.rs | 11 ++++++++--- arbitrator/stylus/src/lib.rs | 5 +++-- arbitrator/stylus/src/native.rs | 5 +++-- .../wasm-libraries/user-host/src/link.rs | 5 +++-- arbos/programs/native.go | 18 +++++++++++++----- arbos/programs/programs.go | 4 ++-- arbos/programs/wasm.go | 9 ++++++--- arbos/programs/wasmstorehelper.go | 9 ++++++--- precompiles/ArbWasm.go | 3 ++- 10 files changed, 49 insertions(+), 25 deletions(-) diff --git a/arbitrator/jit/src/program.rs b/arbitrator/jit/src/program.rs index c608a3cf85..22c4e418cb 100644 --- a/arbitrator/jit/src/program.rs +++ b/arbitrator/jit/src/program.rs @@ -25,7 +25,8 @@ pub fn activate( asm_estimate_ptr: GuestPtr, init_cost_ptr: GuestPtr, cached_init_cost_ptr: GuestPtr, - version: u16, + stylus_version: u16, + arbos_version: u64, debug: u32, codehash: GuestPtr, module_hash_ptr: GuestPtr, @@ -40,7 +41,7 @@ pub fn activate( let page_limit = mem.read_u16(pages_ptr); let gas_left = &mut mem.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, version, page_limit, debug, gas_left) { + match Module::activate(&wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas_left) { Ok((module, data)) => { mem.write_u64(gas_ptr, *gas_left); mem.write_u16(pages_ptr, data.footprint); diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index 5c02e9c11a..6873cf9f50 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -28,6 +28,8 @@ use { wasmer_types::{MemoryIndex, ModuleInfo}, }; +const ARBOS_VERSION_CHARGE_WASM_LEN: u64 = 32; + pub mod config; pub mod counter; pub mod depth; @@ -419,7 +421,8 @@ impl Module { pub fn activate( wasm: &[u8], codehash: &Bytes32, - version: u16, + stylus_version: u16, + arbos_version: u64, page_limit: u16, debug: bool, gas: &mut u64, @@ -446,9 +449,11 @@ impl Module { // pay for wasm let wasm_len = wasm.len() as u64; - pay!(wasm_len.saturating_mul(31_733 / 100_000)); + if arbos_version >= ARBOS_VERSION_CHARGE_WASM_LEN { + pay!(wasm_len.saturating_mul(31_733) / 100_000); + } - let compile = CompileConfig::version(version, debug); + let compile = CompileConfig::version(stylus_version, debug); let (bin, stylus_data) = WasmBinary::parse_user(wasm, page_limit, &compile, codehash) .wrap_err("failed to parse wasm")?; diff --git a/arbitrator/stylus/src/lib.rs b/arbitrator/stylus/src/lib.rs index a252b60a01..b3876affe7 100644 --- a/arbitrator/stylus/src/lib.rs +++ b/arbitrator/stylus/src/lib.rs @@ -139,7 +139,8 @@ impl RustBytes { pub unsafe extern "C" fn stylus_activate( wasm: GoSliceData, page_limit: u16, - version: u16, + stylus_version: u16, + arbos_version: u64, debug: bool, output: *mut RustBytes, codehash: *const Bytes32, @@ -153,7 +154,7 @@ pub unsafe extern "C" fn stylus_activate( let codehash = &*codehash; let gas = &mut *gas; - let (module, info) = match native::activate(wasm, codehash, version, page_limit, debug, gas) { + let (module, info) = match native::activate(wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas) { Ok(val) => val, Err(err) => return output.write_err(err), }; diff --git a/arbitrator/stylus/src/native.rs b/arbitrator/stylus/src/native.rs index 7a82314fbc..55cee9fce0 100644 --- a/arbitrator/stylus/src/native.rs +++ b/arbitrator/stylus/src/native.rs @@ -351,13 +351,14 @@ pub fn module(wasm: &[u8], compile: CompileConfig, target: Target) -> Result Result<(ProverModule, StylusData)> { let (module, stylus_data) = - ProverModule::activate(wasm, codehash, version, page_limit, debug, gas)?; + ProverModule::activate(wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas)?; Ok((module, stylus_data)) } diff --git a/arbitrator/wasm-libraries/user-host/src/link.rs b/arbitrator/wasm-libraries/user-host/src/link.rs index 428611167d..8e98f1d5a6 100644 --- a/arbitrator/wasm-libraries/user-host/src/link.rs +++ b/arbitrator/wasm-libraries/user-host/src/link.rs @@ -44,7 +44,8 @@ pub unsafe extern "C" fn programs__activate( asm_estimate_ptr: GuestPtr, init_cost_ptr: GuestPtr, cached_init_cost_ptr: GuestPtr, - version: u16, + stylus_version: u16, + arbos_version: u64, debug: u32, codehash: GuestPtr, module_hash_ptr: GuestPtr, @@ -58,7 +59,7 @@ pub unsafe extern "C" fn programs__activate( let page_limit = STATIC_MEM.read_u16(pages_ptr); let gas_left = &mut STATIC_MEM.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, version, page_limit, debug, gas_left) { + match Module::activate(&wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas_left) { Ok((module, data)) => { STATIC_MEM.write_u64(gas_ptr, *gas_left); STATIC_MEM.write_u16(pages_ptr, data.footprint); diff --git a/arbos/programs/native.go b/arbos/programs/native.go index 377e25a31e..d143c41879 100644 --- a/arbos/programs/native.go +++ b/arbos/programs/native.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbos/burn" "github.com/offchainlabs/nitro/arbos/util" "github.com/offchainlabs/nitro/arbutil" @@ -51,11 +52,12 @@ func activateProgram( codehash common.Hash, wasm []byte, page_limit uint16, - version uint16, + stylusVersion uint16, + arbosVersion uint64, debug bool, burner burn.Burner, ) (*activationInfo, error) { - info, asmMap, err := activateProgramInternal(db, program, codehash, wasm, page_limit, version, debug, burner.GasLeft()) + info, asmMap, err := activateProgramInternal(db, program, codehash, wasm, page_limit, stylusVersion, arbosVersion, debug, burner.GasLeft()) if err != nil { return nil, err } @@ -69,7 +71,8 @@ func activateProgramInternal( codehash common.Hash, wasm []byte, page_limit uint16, - version uint16, + stylusVersion uint16, + arbosVersion uint64, debug bool, gasLeft *uint64, ) (*activationInfo, map[ethdb.WasmTarget][]byte, error) { @@ -81,7 +84,8 @@ func activateProgramInternal( status_mod := userStatus(C.stylus_activate( goSlice(wasm), u16(page_limit), - u16(version), + u16(stylusVersion), + u64(arbosVersion), cbool(debug), output, &codeHash, @@ -168,9 +172,13 @@ func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging c return nil, fmt.Errorf("failed to reactivate program address: %v err: %w", addressForLogging, err) } + // gas used for activation charging, which doesn't matter here unlimitedGas := uint64(0xffffffffffff) + // arbosVersion used only for charging, which won't happen here so doesn't matter + arbosVersion := params.ArbosVersion_StylusActivationFix + // we know program is activated, so it must be in correct version and not use too much memory - info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, arbosVersion, debugMode, &unlimitedGas) if err != nil { log.Error("failed to reactivate program", "address", addressForLogging, "expected moduleHash", moduleHash, "err", err) return nil, fmt.Errorf("failed to reactivate program address: %v err: %w", addressForLogging, err) diff --git a/arbos/programs/programs.go b/arbos/programs/programs.go index 12102bac84..f397b67783 100644 --- a/arbos/programs/programs.go +++ b/arbos/programs/programs.go @@ -82,7 +82,7 @@ func (p Programs) CacheManagers() *addressSet.AddressSet { return p.cacheManagers } -func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, runMode core.MessageRunMode, debugMode bool) ( +func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVersion uint64, runMode core.MessageRunMode, debugMode bool) ( uint16, common.Hash, common.Hash, *big.Int, bool, error, ) { statedb := evm.StateDB @@ -116,7 +116,7 @@ func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, runMode c // require the program's footprint not exceed the remaining memory budget pageLimit := am.SaturatingUSub(params.PageLimit, statedb.GetStylusPagesOpen()) - info, err := activateProgram(statedb, address, codeHash, wasm, pageLimit, stylusVersion, debugMode, burner) + info, err := activateProgram(statedb, address, codeHash, wasm, pageLimit, stylusVersion, arbosVersion, debugMode, burner) if err != nil { return 0, codeHash, common.Hash{}, nil, true, err } diff --git a/arbos/programs/wasm.go b/arbos/programs/wasm.go index f7191dca8f..a3209d9ac5 100644 --- a/arbos/programs/wasm.go +++ b/arbos/programs/wasm.go @@ -44,7 +44,8 @@ func programActivate( asm_estimation_ptr unsafe.Pointer, init_gas_ptr unsafe.Pointer, cached_init_gas_ptr unsafe.Pointer, - version uint32, + stylusVersion uint32, + arbosVersion uint64, debug uint32, codehash unsafe.Pointer, module_hash_ptr unsafe.Pointer, @@ -59,7 +60,8 @@ func activateProgram( codehash common.Hash, wasm []byte, pageLimit u16, - version u16, + stylusVersion u16, + arbosVersion uint64, debug bool, burner burn.Burner, ) (*activationInfo, error) { @@ -79,7 +81,8 @@ func activateProgram( unsafe.Pointer(&asmEstimate), unsafe.Pointer(&initGas), unsafe.Pointer(&cachedInitGas), - uint32(version), + uint32(stylusVersion), + arbosVersion, debugMode, arbutil.SliceToUnsafePointer(codehash[:]), arbutil.SliceToUnsafePointer(moduleHash[:]), diff --git a/arbos/programs/wasmstorehelper.go b/arbos/programs/wasmstorehelper.go index 434820dd9c..15a4c8f31b 100644 --- a/arbos/programs/wasmstorehelper.go +++ b/arbos/programs/wasmstorehelper.go @@ -13,16 +13,17 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" ) // SaveActiveProgramToWasmStore is used to save active stylus programs to wasm store during rebuilding func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash common.Hash, code []byte, time uint64, debugMode bool, rebuildingStartBlockTime uint64) error { - params, err := p.Params() + progParams, err := p.Params() if err != nil { return err } - program, err := p.getActiveProgram(codeHash, time, params) + program, err := p.getActiveProgram(codeHash, time, progParams) if err != nil { // The program is not active so return early log.Info("program is not active, getActiveProgram returned error, hence do not include in rebuilding", "err", err) @@ -56,10 +57,12 @@ func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash return fmt.Errorf("failed to reactivate program while rebuilding wasm store: %w", err) } + // nothing is charged, so gas and arbosVersion don't matter unlimitedGas := uint64(0xffffffffffff) + arbosVersion := params.ArbosVersion_StylusActivationFix // We know program is activated, so it must be in correct version and not use too much memory // Empty program address is supplied because we dont have access to this during rebuilding of wasm store - info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, params.PageLimit, program.version, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, arbosVersion, debugMode, &unlimitedGas) if err != nil { log.Error("failed to reactivate program while rebuilding wasm store", "expected moduleHash", moduleHash, "err", err) return fmt.Errorf("failed to reactivate program while rebuilding wasm store: %w", err) diff --git a/precompiles/ArbWasm.go b/precompiles/ArbWasm.go index 9f42cacb5a..36093f58db 100644 --- a/precompiles/ArbWasm.go +++ b/precompiles/ArbWasm.go @@ -32,12 +32,13 @@ func (con ArbWasm) ActivateProgram(c ctx, evm mech, value huge, program addr) (u debug := evm.ChainConfig().DebugMode() runMode := c.txProcessor.RunMode() programs := c.State.Programs() + arbosVersion := c.State.ArbOSVersion() // charge a fixed cost up front to begin activation if err := c.Burn(1659168); err != nil { return 0, nil, err } - version, codeHash, moduleHash, dataFee, takeAllGas, err := programs.ActivateProgram(evm, program, runMode, debug) + version, codeHash, moduleHash, dataFee, takeAllGas, err := programs.ActivateProgram(evm, program, arbosVersion, runMode, debug) if takeAllGas { _ = c.BurnOut() } From 92ff55fc06155fab68b81ad0f7df83dafe8f97fb Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 3 Sep 2024 17:22:24 -0600 Subject: [PATCH 2/7] rename arbos_version param in activate and accept zero --- arbitrator/jit/src/program.rs | 4 +- arbitrator/prover/src/programs/mod.rs | 46 ++++++++++--------- arbitrator/stylus/src/lib.rs | 4 +- arbitrator/stylus/src/native.rs | 4 +- .../wasm-libraries/user-host/src/link.rs | 4 +- arbos/programs/native.go | 13 ++---- arbos/programs/wasmstorehelper.go | 5 +- 7 files changed, 39 insertions(+), 41 deletions(-) diff --git a/arbitrator/jit/src/program.rs b/arbitrator/jit/src/program.rs index 22c4e418cb..47227f117f 100644 --- a/arbitrator/jit/src/program.rs +++ b/arbitrator/jit/src/program.rs @@ -26,7 +26,7 @@ pub fn activate( init_cost_ptr: GuestPtr, cached_init_cost_ptr: GuestPtr, stylus_version: u16, - arbos_version: u64, + arbos_version_for_gas: u64, debug: u32, codehash: GuestPtr, module_hash_ptr: GuestPtr, @@ -41,7 +41,7 @@ pub fn activate( let page_limit = mem.read_u16(pages_ptr); let gas_left = &mut mem.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas_left) { + match Module::activate(&wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas_left) { Ok((module, data)) => { mem.write_u64(gas_ptr, *gas_left); mem.write_u16(pages_ptr, data.footprint); diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index 6873cf9f50..5f314dbf87 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -422,7 +422,7 @@ impl Module { wasm: &[u8], codehash: &Bytes32, stylus_version: u16, - arbos_version: u64, + arbos_version_for_gas: u64, // must only be used for activation gas page_limit: u16, debug: bool, gas: &mut u64, @@ -447,35 +447,37 @@ impl Module { }; } - // pay for wasm - let wasm_len = wasm.len() as u64; - if arbos_version >= ARBOS_VERSION_CHARGE_WASM_LEN { - pay!(wasm_len.saturating_mul(31_733) / 100_000); - } - let compile = CompileConfig::version(stylus_version, debug); let (bin, stylus_data) = WasmBinary::parse_user(wasm, page_limit, &compile, codehash) .wrap_err("failed to parse wasm")?; - // pay for funcs - let funcs = bin.functions.len() as u64; - pay!(funcs.saturating_mul(17_263) / 100_000); + // pay for wasm + if arbos_version_for_gas >= ARBOS_VERSION_CHARGE_WASM_LEN { + let wasm_len = wasm.len() as u64; + pay!(wasm_len.saturating_mul(31_733) / 100_000); + } - // pay for data - let data = bin.datas.iter().map(|x| x.data.len()).saturating_sum() as u64; - pay!(data.saturating_mul(17_376) / 100_000); + if arbos_version_for_gas > 0 { + // pay for funcs + let funcs = bin.functions.len() as u64; + pay!(funcs.saturating_mul(17_263) / 100_000); - // pay for elements - let elems = bin.elements.iter().map(|x| x.range.len()).saturating_sum() as u64; - pay!(elems.saturating_mul(17_376) / 100_000); + // pay for data + let data = bin.datas.iter().map(|x| x.data.len()).saturating_sum() as u64; + pay!(data.saturating_mul(17_376) / 100_000); - // pay for memory - let mem = bin.memories.first().map(|x| x.initial).unwrap_or_default(); - pay!(mem.saturating_mul(2217)); + // pay for elements + let elems = bin.elements.iter().map(|x| x.range.len()).saturating_sum() as u64; + pay!(elems.saturating_mul(17_376) / 100_000); - // pay for code - let code = bin.codes.iter().map(|x| x.expr.len()).saturating_sum() as u64; - pay!(code.saturating_mul(535) / 1_000); + // pay for memory + let mem = bin.memories.first().map(|x| x.initial).unwrap_or_default(); + pay!(mem.saturating_mul(2217)); + + // pay for code + let code = bin.codes.iter().map(|x| x.expr.len()).saturating_sum() as u64; + pay!(code.saturating_mul(535) / 1_000); + } let module = Self::from_user_binary(&bin, compile.debug.debug_funcs, Some(stylus_data)) .wrap_err("failed to build user module")?; diff --git a/arbitrator/stylus/src/lib.rs b/arbitrator/stylus/src/lib.rs index b3876affe7..c53d1a663b 100644 --- a/arbitrator/stylus/src/lib.rs +++ b/arbitrator/stylus/src/lib.rs @@ -140,7 +140,7 @@ pub unsafe extern "C" fn stylus_activate( wasm: GoSliceData, page_limit: u16, stylus_version: u16, - arbos_version: u64, + arbos_version_for_gas: u64, debug: bool, output: *mut RustBytes, codehash: *const Bytes32, @@ -154,7 +154,7 @@ pub unsafe extern "C" fn stylus_activate( let codehash = &*codehash; let gas = &mut *gas; - let (module, info) = match native::activate(wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas) { + let (module, info) = match native::activate(wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas) { Ok(val) => val, Err(err) => return output.write_err(err), }; diff --git a/arbitrator/stylus/src/native.rs b/arbitrator/stylus/src/native.rs index 55cee9fce0..f2f63fe216 100644 --- a/arbitrator/stylus/src/native.rs +++ b/arbitrator/stylus/src/native.rs @@ -352,13 +352,13 @@ pub fn activate( wasm: &[u8], codehash: &Bytes32, stylus_version: u16, - arbos_version: u64, + arbos_version_for_gas: u64, page_limit: u16, debug: bool, gas: &mut u64, ) -> Result<(ProverModule, StylusData)> { let (module, stylus_data) = - ProverModule::activate(wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas)?; + ProverModule::activate(wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas)?; Ok((module, stylus_data)) } diff --git a/arbitrator/wasm-libraries/user-host/src/link.rs b/arbitrator/wasm-libraries/user-host/src/link.rs index 8e98f1d5a6..6c2d3c6c62 100644 --- a/arbitrator/wasm-libraries/user-host/src/link.rs +++ b/arbitrator/wasm-libraries/user-host/src/link.rs @@ -45,7 +45,7 @@ pub unsafe extern "C" fn programs__activate( init_cost_ptr: GuestPtr, cached_init_cost_ptr: GuestPtr, stylus_version: u16, - arbos_version: u64, + arbos_version_for_gas: u64, debug: u32, codehash: GuestPtr, module_hash_ptr: GuestPtr, @@ -59,7 +59,7 @@ pub unsafe extern "C" fn programs__activate( let page_limit = STATIC_MEM.read_u16(pages_ptr); let gas_left = &mut STATIC_MEM.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, stylus_version, arbos_version, page_limit, debug, gas_left) { + match Module::activate(&wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas_left) { Ok((module, data)) => { STATIC_MEM.write_u64(gas_ptr, *gas_left); STATIC_MEM.write_u16(pages_ptr, data.footprint); diff --git a/arbos/programs/native.go b/arbos/programs/native.go index d143c41879..2c39e96652 100644 --- a/arbos/programs/native.go +++ b/arbos/programs/native.go @@ -29,7 +29,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbos/burn" "github.com/offchainlabs/nitro/arbos/util" "github.com/offchainlabs/nitro/arbutil" @@ -53,11 +52,11 @@ func activateProgram( wasm []byte, page_limit uint16, stylusVersion uint16, - arbosVersion uint64, + arbosVersionForGas uint64, debug bool, burner burn.Burner, ) (*activationInfo, error) { - info, asmMap, err := activateProgramInternal(db, program, codehash, wasm, page_limit, stylusVersion, arbosVersion, debug, burner.GasLeft()) + info, asmMap, err := activateProgramInternal(db, program, codehash, wasm, page_limit, stylusVersion, arbosVersionForGas, debug, burner.GasLeft()) if err != nil { return nil, err } @@ -72,7 +71,7 @@ func activateProgramInternal( wasm []byte, page_limit uint16, stylusVersion uint16, - arbosVersion uint64, + arbosVersionForGas uint64, debug bool, gasLeft *uint64, ) (*activationInfo, map[ethdb.WasmTarget][]byte, error) { @@ -85,7 +84,7 @@ func activateProgramInternal( goSlice(wasm), u16(page_limit), u16(stylusVersion), - u64(arbosVersion), + u64(arbosVersionForGas), cbool(debug), output, &codeHash, @@ -174,11 +173,9 @@ func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging c // gas used for activation charging, which doesn't matter here unlimitedGas := uint64(0xffffffffffff) - // arbosVersion used only for charging, which won't happen here so doesn't matter - arbosVersion := params.ArbosVersion_StylusActivationFix // we know program is activated, so it must be in correct version and not use too much memory - info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, arbosVersion, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, 0, debugMode, &unlimitedGas) if err != nil { log.Error("failed to reactivate program", "address", addressForLogging, "expected moduleHash", moduleHash, "err", err) return nil, fmt.Errorf("failed to reactivate program address: %v err: %w", addressForLogging, err) diff --git a/arbos/programs/wasmstorehelper.go b/arbos/programs/wasmstorehelper.go index 15a4c8f31b..d7bafe7fbc 100644 --- a/arbos/programs/wasmstorehelper.go +++ b/arbos/programs/wasmstorehelper.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" ) // SaveActiveProgramToWasmStore is used to save active stylus programs to wasm store during rebuilding @@ -59,10 +58,10 @@ func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash // nothing is charged, so gas and arbosVersion don't matter unlimitedGas := uint64(0xffffffffffff) - arbosVersion := params.ArbosVersion_StylusActivationFix + // We know program is activated, so it must be in correct version and not use too much memory // Empty program address is supplied because we dont have access to this during rebuilding of wasm store - info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, arbosVersion, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, 0, debugMode, &unlimitedGas) if err != nil { log.Error("failed to reactivate program while rebuilding wasm store", "expected moduleHash", moduleHash, "err", err) return fmt.Errorf("failed to reactivate program while rebuilding wasm store: %w", err) From c909f75dbdc6a587fd3180f1f52f2da052b11b3b Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 12 Sep 2024 20:11:55 -0600 Subject: [PATCH 3/7] tempfix: stylus_version --- arbos/programs/native.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbos/programs/native.go b/arbos/programs/native.go index 2c39e96652..7ac96baf5e 100644 --- a/arbos/programs/native.go +++ b/arbos/programs/native.go @@ -119,7 +119,7 @@ func activateProgramInternal( output := &rustBytes{} status_asm := C.stylus_compile( goSlice(wasm), - u16(version), + u16(stylusVersion), cbool(debug), goSlice([]byte(target)), output, From 8cd3a85954b65d71d979fbc089a67742b7fc9aa2 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 12 Sep 2024 20:16:16 -0600 Subject: [PATCH 4/7] lint and reviewer input --- arbitrator/jit/src/program.rs | 10 +++- arbitrator/prover/src/programs/mod.rs | 52 +++++++++---------- arbitrator/stylus/src/lib.rs | 10 +++- arbitrator/stylus/src/native.rs | 11 +++- .../wasm-libraries/user-host/src/link.rs | 10 +++- arbos/programs/native.go | 7 +-- arbos/programs/wasmstorehelper.go | 7 +-- 7 files changed, 70 insertions(+), 37 deletions(-) diff --git a/arbitrator/jit/src/program.rs b/arbitrator/jit/src/program.rs index 47227f117f..72c7541c0d 100644 --- a/arbitrator/jit/src/program.rs +++ b/arbitrator/jit/src/program.rs @@ -41,7 +41,15 @@ pub fn activate( let page_limit = mem.read_u16(pages_ptr); let gas_left = &mut mem.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas_left) { + match Module::activate( + &wasm, + codehash, + stylus_version, + arbos_version_for_gas, + page_limit, + debug, + gas_left, + ) { Ok((module, data)) => { mem.write_u64(gas_ptr, *gas_left); mem.write_u16(pages_ptr, data.footprint); diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index 5f314dbf87..c03fbf8248 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -427,37 +427,37 @@ impl Module { debug: bool, gas: &mut u64, ) -> Result<(Self, StylusData)> { - // converts a number of microseconds to gas - // TODO: collapse to a single value after finalizing factors - let us_to_gas = |us: u64| { - let fudge = 2; - let sync_rate = 1_000_000 / 2; - let speed = 7_000_000; - us.saturating_mul(fudge * speed) / sync_rate - }; - - macro_rules! pay { - ($us:expr) => { - let amount = us_to_gas($us); - if *gas < amount { - *gas = 0; - bail!("out of gas"); - } - *gas -= amount; - }; - } - let compile = CompileConfig::version(stylus_version, debug); let (bin, stylus_data) = WasmBinary::parse_user(wasm, page_limit, &compile, codehash) .wrap_err("failed to parse wasm")?; - // pay for wasm - if arbos_version_for_gas >= ARBOS_VERSION_CHARGE_WASM_LEN { - let wasm_len = wasm.len() as u64; - pay!(wasm_len.saturating_mul(31_733) / 100_000); - } - if arbos_version_for_gas > 0 { + // converts a number of microseconds to gas + // TODO: collapse to a single value after finalizing factors + let us_to_gas = |us: u64| { + let fudge = 2; + let sync_rate = 1_000_000 / 2; + let speed = 7_000_000; + us.saturating_mul(fudge * speed) / sync_rate + }; + + macro_rules! pay { + ($us:expr) => { + let amount = us_to_gas($us); + if *gas < amount { + *gas = 0; + bail!("out of gas"); + } + *gas -= amount; + }; + } + + // pay for wasm + if arbos_version_for_gas >= ARBOS_VERSION_CHARGE_WASM_LEN { + let wasm_len = wasm.len() as u64; + pay!(wasm_len.saturating_mul(31_733) / 100_000); + } + // pay for funcs let funcs = bin.functions.len() as u64; pay!(funcs.saturating_mul(17_263) / 100_000); diff --git a/arbitrator/stylus/src/lib.rs b/arbitrator/stylus/src/lib.rs index c53d1a663b..052bfc7229 100644 --- a/arbitrator/stylus/src/lib.rs +++ b/arbitrator/stylus/src/lib.rs @@ -154,7 +154,15 @@ pub unsafe extern "C" fn stylus_activate( let codehash = &*codehash; let gas = &mut *gas; - let (module, info) = match native::activate(wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas) { + let (module, info) = match native::activate( + wasm, + codehash, + stylus_version, + arbos_version_for_gas, + page_limit, + debug, + gas, + ) { Ok(val) => val, Err(err) => return output.write_err(err), }; diff --git a/arbitrator/stylus/src/native.rs b/arbitrator/stylus/src/native.rs index f2f63fe216..7507d27467 100644 --- a/arbitrator/stylus/src/native.rs +++ b/arbitrator/stylus/src/native.rs @@ -357,8 +357,15 @@ pub fn activate( debug: bool, gas: &mut u64, ) -> Result<(ProverModule, StylusData)> { - let (module, stylus_data) = - ProverModule::activate(wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas)?; + let (module, stylus_data) = ProverModule::activate( + wasm, + codehash, + stylus_version, + arbos_version_for_gas, + page_limit, + debug, + gas, + )?; Ok((module, stylus_data)) } diff --git a/arbitrator/wasm-libraries/user-host/src/link.rs b/arbitrator/wasm-libraries/user-host/src/link.rs index 6c2d3c6c62..f6e7dfad39 100644 --- a/arbitrator/wasm-libraries/user-host/src/link.rs +++ b/arbitrator/wasm-libraries/user-host/src/link.rs @@ -59,7 +59,15 @@ pub unsafe extern "C" fn programs__activate( let page_limit = STATIC_MEM.read_u16(pages_ptr); let gas_left = &mut STATIC_MEM.read_u64(gas_ptr); - match Module::activate(&wasm, codehash, stylus_version, arbos_version_for_gas, page_limit, debug, gas_left) { + match Module::activate( + &wasm, + codehash, + stylus_version, + arbos_version_for_gas, + page_limit, + debug, + gas_left, + ) { Ok((module, data)) => { STATIC_MEM.write_u64(gas_ptr, *gas_left); STATIC_MEM.write_u16(pages_ptr, data.footprint); diff --git a/arbos/programs/native.go b/arbos/programs/native.go index 7ac96baf5e..acc0ad41e6 100644 --- a/arbos/programs/native.go +++ b/arbos/programs/native.go @@ -171,11 +171,12 @@ func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging c return nil, fmt.Errorf("failed to reactivate program address: %v err: %w", addressForLogging, err) } - // gas used for activation charging, which doesn't matter here - unlimitedGas := uint64(0xffffffffffff) + // don't charge gas + zeroArbosVersion := uint64(0) + zeroGas := uint64(0) // we know program is activated, so it must be in correct version and not use too much memory - info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, 0, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, addressForLogging, codeHash, wasm, pagelimit, program.version, zeroArbosVersion, debugMode, &zeroGas) if err != nil { log.Error("failed to reactivate program", "address", addressForLogging, "expected moduleHash", moduleHash, "err", err) return nil, fmt.Errorf("failed to reactivate program address: %v err: %w", addressForLogging, err) diff --git a/arbos/programs/wasmstorehelper.go b/arbos/programs/wasmstorehelper.go index d7bafe7fbc..c2d1aa65b0 100644 --- a/arbos/programs/wasmstorehelper.go +++ b/arbos/programs/wasmstorehelper.go @@ -56,12 +56,13 @@ func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash return fmt.Errorf("failed to reactivate program while rebuilding wasm store: %w", err) } - // nothing is charged, so gas and arbosVersion don't matter - unlimitedGas := uint64(0xffffffffffff) + // don't charge gas + zeroArbosVersion := uint64(0) + zeroGas := uint64(0) // We know program is activated, so it must be in correct version and not use too much memory // Empty program address is supplied because we dont have access to this during rebuilding of wasm store - info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, 0, debugMode, &unlimitedGas) + info, asmMap, err := activateProgramInternal(statedb, common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, zeroArbosVersion, debugMode, &zeroGas) if err != nil { log.Error("failed to reactivate program while rebuilding wasm store", "expected moduleHash", moduleHash, "err", err) return fmt.Errorf("failed to reactivate program while rebuilding wasm store: %w", err) From 48e447038e5ca7b65fe1ef49d5f4f3191a273384 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 12 Sep 2024 21:26:30 -0600 Subject: [PATCH 5/7] stylus: use new constant for arbos version --- arbitrator/prover/src/programs/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index c03fbf8248..cd1a6d4214 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -28,8 +28,6 @@ use { wasmer_types::{MemoryIndex, ModuleInfo}, }; -const ARBOS_VERSION_CHARGE_WASM_LEN: u64 = 32; - pub mod config; pub mod counter; pub mod depth; @@ -453,7 +451,7 @@ impl Module { } // pay for wasm - if arbos_version_for_gas >= ARBOS_VERSION_CHARGE_WASM_LEN { + if arbos_version_for_gas >= ARBOS_VERSION_STYLUS_CHARGING_FIXES { let wasm_len = wasm.len() as u64; pay!(wasm_len.saturating_mul(31_733) / 100_000); } From 42e69a6109d13e151326ff47bea127da8a5a37f0 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 13 Sep 2024 15:08:24 -0600 Subject: [PATCH 6/7] compilatio fix for constant change --- arbitrator/prover/src/programs/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index cec8d6ec6e..e83b1359fa 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -8,7 +8,7 @@ use crate::{ programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; -use arbutil::{math::SaturatingSum, Bytes32, Color}; +use arbutil::{math::SaturatingSum, Bytes32, Color, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES}; use eyre::{bail, eyre, Report, Result, WrapErr}; use fnv::FnvHashMap as HashMap; use std::fmt::Debug; From c5bff799993deab44faec3b1e6586f3a2058da9c Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 13 Sep 2024 15:17:29 -0600 Subject: [PATCH 7/7] cargo fmt --- arbitrator/prover/src/programs/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrator/prover/src/programs/mod.rs b/arbitrator/prover/src/programs/mod.rs index e83b1359fa..d8717c9f7d 100644 --- a/arbitrator/prover/src/programs/mod.rs +++ b/arbitrator/prover/src/programs/mod.rs @@ -8,7 +8,7 @@ use crate::{ programs::config::CompileConfig, value::{FunctionType as ArbFunctionType, Value}, }; -use arbutil::{math::SaturatingSum, Bytes32, Color, evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES}; +use arbutil::{evm::ARBOS_VERSION_STYLUS_CHARGING_FIXES, math::SaturatingSum, Bytes32, Color}; use eyre::{bail, eyre, Report, Result, WrapErr}; use fnv::FnvHashMap as HashMap; use std::fmt::Debug;