Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use MessageRunMode struct #2779

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7cc9e05
use MessageRunMode struct draft
magicxyyz Nov 8, 2024
c5d4115
Merge branch 'master' into run-mode-struct
magicxyyz Nov 8, 2024
fc96b34
Merge branch 'ondemand-module-compile' into run-mode-struct
magicxyyz Nov 8, 2024
8fce23e
rename MessageRunMode -> MessageRunContext
magicxyyz Nov 8, 2024
0c13d46
use WasmCacheTag from MessageRunContext
magicxyyz Nov 13, 2024
583eaaf
update geth pin
magicxyyz Nov 13, 2024
5aadada
update geth pin
magicxyyz Nov 13, 2024
a68cb01
update geth pin
magicxyyz Nov 13, 2024
702df72
Merge branch 'ondemand-module-compile' into run-mode-struct
magicxyyz Nov 13, 2024
a8dfeb6
Merge branch 'ondemand-module-compile' into run-mode-struct
magicxyyz Nov 13, 2024
4fb1df6
use new MessageRunContext method names
magicxyyz Nov 14, 2024
a795adf
system_tests: cleanup wasmCacheTag from common_test
magicxyyz Nov 14, 2024
b9cf390
update WasmTarget package
magicxyyz Nov 15, 2024
071e2dc
Merge branch 'master' into run-mode-struct
magicxyyz Nov 15, 2024
0f68d39
Merge branch 'ondemand-module-compile' into run-mode-struct
magicxyyz Nov 15, 2024
69c6268
cleanup .orig files
magicxyyz Nov 15, 2024
e030bf0
update geth
magicxyyz Jan 10, 2025
101e349
Merge branch 'master' into run-mode-struct
magicxyyz Jan 10, 2025
9225564
update geth
magicxyyz Jan 10, 2025
d43e8a8
update geth
magicxyyz Jan 13, 2025
a931091
update geth
magicxyyz Jan 21, 2025
3e2af88
Merge branch 'master' into run-mode-struct
magicxyyz Jan 21, 2025
47e01b0
update geth
magicxyyz Feb 11, 2025
cffc87d
Merge branch 'master' into run-mode-struct
magicxyyz Feb 11, 2025
a6aa547
Merge branch 'master' into run-mode-struct
magicxyyz Feb 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions arbnode/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/core/rawdb"

"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/staker"
Expand Down Expand Up @@ -59,7 +59,7 @@ func (a *BlockValidatorDebugAPI) ValidateMessageNumber(
return result, err
}

func (a *BlockValidatorDebugAPI) ValidationInputsAt(ctx context.Context, msgNum hexutil.Uint64, target ethdb.WasmTarget,
func (a *BlockValidatorDebugAPI) ValidationInputsAt(ctx context.Context, msgNum hexutil.Uint64, target rawdb.WasmTarget,
) (server_api.InputJSON, error) {
return a.val.ValidationInputsAt(ctx, arbutil.MessageIndex(msgNum), target)
}
Expand Down
8 changes: 4 additions & 4 deletions arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func ProduceBlock(
chainContext core.ChainContext,
chainConfig *params.ChainConfig,
isMsgForPrefetch bool,
runMode core.MessageRunMode,
runCtx *core.MessageRunContext,
) (*types.Block, types.Receipts, error) {
txes, err := ParseL2Transactions(message, chainConfig.ChainID)
if err != nil {
Expand All @@ -156,7 +156,7 @@ func ProduceBlock(

hooks := NoopSequencingHooks()
return ProduceBlockAdvanced(
message.Header, txes, delayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, hooks, isMsgForPrefetch, runMode,
message.Header, txes, delayedMessagesRead, lastBlockHeader, statedb, chainContext, chainConfig, hooks, isMsgForPrefetch, runCtx,
)
}

Expand All @@ -171,7 +171,7 @@ func ProduceBlockAdvanced(
chainConfig *params.ChainConfig,
sequencingHooks *SequencingHooks,
isMsgForPrefetch bool,
runMode core.MessageRunMode,
runCtx *core.MessageRunContext,
) (*types.Block, types.Receipts, error) {

arbState, err := arbosState.OpenSystemArbosState(statedb, nil, true)
Expand Down Expand Up @@ -322,7 +322,7 @@ func ProduceBlockAdvanced(
tx,
&header.GasUsed,
vm.Config{},
runMode,
runCtx,
func(result *core.ExecutionResult) error {
return hooks.PostTxFilter(header, statedb, arbState, tx, sender, dataGas, result)
},
Expand Down
2 changes: 1 addition & 1 deletion arbos/l1pricing/l1pricing.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ func makeFakeTxForMessage(message *core.Message) *types.Transaction {
}
// During gas estimation, we don't want the gas limit variability to change the L1 cost.
gas := message.GasLimit
if gas == 0 || message.TxRunMode == core.MessageGasEstimationMode {
if gas == 0 || message.TxRunContext.IsGasEstimation() {
gas = RandomGas
}
return types.NewTx(&types.DynamicFeeTx{
Expand Down
47 changes: 23 additions & 24 deletions arbos/programs/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"

Expand Down Expand Up @@ -71,10 +70,10 @@ func activateProgram(
arbosVersionForGas uint64,
debug bool,
burner burn.Burner,
runCtx *core.MessageRunContext,
) (*activationInfo, error) {
targets := db.Database().WasmTargets()
moduleActivationMandatory := true
info, asmMap, err := activateProgramInternal(program, codehash, wasm, page_limit, stylusVersion, arbosVersionForGas, debug, burner.GasLeft(), targets, moduleActivationMandatory)
info, asmMap, err := activateProgramInternal(program, codehash, wasm, page_limit, stylusVersion, arbosVersionForGas, debug, burner.GasLeft(), runCtx, moduleActivationMandatory)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -134,7 +133,7 @@ func compileNative(
wasm []byte,
stylusVersion uint16,
debug bool,
target ethdb.WasmTarget,
target rawdb.WasmTarget,
) ([]byte, error) {
output := &rustBytes{}
status_asm := C.stylus_compile(
Expand All @@ -160,11 +159,12 @@ func activateProgramInternal(
arbosVersionForGas uint64,
debug bool,
gasLeft *uint64,
targets []ethdb.WasmTarget,
runCtx *core.MessageRunContext,
moduleActivationMandatory bool,
) (*activationInfo, map[ethdb.WasmTarget][]byte, error) {
) (*activationInfo, map[rawdb.WasmTarget][]byte, error) {
targets := runCtx.WasmTargets()
var wavmFound bool
var nativeTargets []ethdb.WasmTarget
var nativeTargets []rawdb.WasmTarget
for _, target := range targets {
if target == rawdb.TargetWavm {
wavmFound = true
Expand All @@ -173,14 +173,14 @@ func activateProgramInternal(
}
}
type result struct {
target ethdb.WasmTarget
target rawdb.WasmTarget
asm []byte
err error
}
results := make(chan result)
// info will be set in separate thread, make sure to wait before reading
var info *activationInfo
asmMap := make(map[ethdb.WasmTarget][]byte, len(nativeTargets)+1)
asmMap := make(map[rawdb.WasmTarget][]byte, len(nativeTargets)+1)
if moduleActivationMandatory || wavmFound {
go func() {
var err error
Expand Down Expand Up @@ -233,7 +233,7 @@ func activateProgramInternal(
return info, asmMap, err
}

func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging common.Address, code []byte, codehash common.Hash, pagelimit uint16, time uint64, debugMode bool, program Program) ([]byte, error) {
func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging common.Address, code []byte, codehash common.Hash, pagelimit uint16, time uint64, debugMode bool, program Program, runCtx *core.MessageRunContext) ([]byte, error) {
localTarget := rawdb.LocalTarget()
localAsm, err := statedb.TryGetActivatedAsm(localTarget, moduleHash)
if err == nil && len(localAsm) > 0 {
Expand All @@ -251,10 +251,9 @@ func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging c
zeroArbosVersion := uint64(0)
zeroGas := uint64(0)

targets := statedb.Database().WasmTargets()
// we know program is activated, so it must be in correct version and not use too much memory
moduleActivationMandatory := false
info, asmMap, err := activateProgramInternal(addressForLogging, codehash, wasm, pagelimit, program.version, zeroArbosVersion, debugMode, &zeroGas, targets, moduleActivationMandatory)
info, asmMap, err := activateProgramInternal(addressForLogging, codehash, wasm, pagelimit, program.version, zeroArbosVersion, debugMode, &zeroGas, runCtx, moduleActivationMandatory)
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)
Expand All @@ -281,7 +280,7 @@ func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging c
}
asm, exists := asmMap[localTarget]
if !exists {
var availableTargets []ethdb.WasmTarget
var availableTargets []rawdb.WasmTarget
for target := range asmMap {
availableTargets = append(availableTargets, target)
}
Expand All @@ -302,7 +301,7 @@ func callProgram(
evmData *EvmData,
stylusParams *ProgParams,
memoryModel *MemoryModel,
arbos_tag uint32,
runCtx *core.MessageRunContext,
) ([]byte, error) {
db := interpreter.Evm().StateDB
debug := stylusParams.DebugMode
Expand All @@ -313,7 +312,7 @@ func callProgram(
}

if stateDb, ok := db.(*state.StateDB); ok {
stateDb.RecordProgram(db.Database().WasmTargets(), moduleHash)
stateDb.RecordProgram(runCtx.WasmTargets(), moduleHash)
}

evmApi := newApi(interpreter, tracingInfo, scope, memoryModel)
Expand All @@ -329,7 +328,7 @@ func callProgram(
cbool(debug),
output,
(*u64)(&scope.Contract.Gas),
u32(arbos_tag),
u32(runCtx.WasmCacheTag()),
))

depth := interpreter.Depth()
Expand All @@ -356,24 +355,24 @@ func handleReqImpl(apiId usize, req_type u32, data *rustSlice, costPtr *u64, out

// Caches a program in Rust. We write a record so that we can undo on revert.
// For gas estimation and eth_call, we ignore permanent updates and rely on Rust's LRU.
func cacheProgram(db vm.StateDB, module common.Hash, program Program, addressForLogging common.Address, code []byte, codehash common.Hash, params *StylusParams, debug bool, time uint64, runMode core.MessageRunMode) {
if runMode == core.MessageCommitMode {
func cacheProgram(db vm.StateDB, module common.Hash, program Program, addressForLogging common.Address, code []byte, codeHash common.Hash, params *StylusParams, debug bool, time uint64, runCtx *core.MessageRunContext) {
if runCtx.IsCommitMode() {
// address is only used for logging
asm, err := getLocalAsm(db, module, addressForLogging, code, codehash, params.PageLimit, time, debug, program)
asm, err := getLocalAsm(db, module, addressForLogging, code, codeHash, params.PageLimit, time, debug, program, runCtx)
if err != nil {
panic("unable to recreate wasm")
}
tag := db.Database().WasmCacheTag()
tag := runCtx.WasmCacheTag()
state.CacheWasmRust(asm, module, program.version, tag, debug)
db.RecordCacheWasm(state.CacheWasm{ModuleHash: module, Version: program.version, Tag: tag, Debug: debug})
}
}

// Evicts a program in Rust. We write a record so that we can undo on revert, unless we don't need to (e.g. expired)
// For gas estimation and eth_call, we ignore permanent updates and rely on Rust's LRU.
func evictProgram(db vm.StateDB, module common.Hash, version uint16, debug bool, runMode core.MessageRunMode, forever bool) {
if runMode == core.MessageCommitMode {
tag := db.Database().WasmCacheTag()
func evictProgram(db vm.StateDB, module common.Hash, version uint16, debug bool, runCtx *core.MessageRunContext, forever bool) {
if runCtx.IsCommitMode() {
tag := runCtx.WasmCacheTag()
state.EvictWasmRust(module, version, tag, debug)
if !forever {
db.RecordEvictWasm(state.EvictWasm{ModuleHash: module, Version: version, Tag: tag, Debug: debug})
Expand Down Expand Up @@ -463,7 +462,7 @@ func GetEntrySizeEstimateBytes(module []byte, version uint16, debug bool) uint64
const DefaultTargetDescriptionArm = "arm64-linux-unknown+neon"
const DefaultTargetDescriptionX86 = "x86_64-linux-unknown+sse4.2+lzcnt+bmi"

func SetTarget(name ethdb.WasmTarget, description string, native bool) error {
func SetTarget(name rawdb.WasmTarget, description string, native bool) error {
output := &rustBytes{}
status := userStatus(C.stylus_target_set(
goSlice([]byte(name)),
Expand Down
46 changes: 13 additions & 33 deletions arbos/programs/programs.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (p Programs) CacheManagers() *addressSet.AddressSet {
return p.cacheManagers
}

func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVersion uint64, runMode core.MessageRunMode, debugMode bool) (
func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVersion uint64, runCtx *core.MessageRunContext, debugMode bool) (
uint16, common.Hash, common.Hash, *big.Int, bool, error,
) {
statedb := evm.StateDB
Expand Down Expand Up @@ -118,7 +118,7 @@ func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVers
// 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, arbosVersion, debugMode, burner)
info, err := activateProgram(statedb, address, codeHash, wasm, pageLimit, stylusVersion, arbosVersion, debugMode, burner, runCtx)
if err != nil {
return 0, codeHash, common.Hash{}, nil, true, err
}
Expand All @@ -130,7 +130,7 @@ func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVers
return 0, codeHash, common.Hash{}, nil, true, err
}

evictProgram(statedb, oldModuleHash, currentVersion, debugMode, runMode, expired)
evictProgram(statedb, oldModuleHash, currentVersion, debugMode, runCtx, expired)
}
if err := p.moduleHashes.Set(codeHash, info.moduleHash); err != nil {
return 0, codeHash, common.Hash{}, nil, true, err
Expand Down Expand Up @@ -158,27 +158,12 @@ func (p Programs) ActivateProgram(evm *vm.EVM, address common.Address, arbosVers
// replace the cached asm
if cached {
code := statedb.GetCode(address)
cacheProgram(statedb, info.moduleHash, programData, address, code, codeHash, params, debugMode, time, runMode)
cacheProgram(statedb, info.moduleHash, programData, address, code, codeHash, params, debugMode, time, runCtx)
}

return stylusVersion, codeHash, info.moduleHash, dataFee, false, p.setProgram(codeHash, programData)
}

func runModeToString(runMode core.MessageRunMode) string {
switch runMode {
case core.MessageCommitMode:
return "commit_runmode"
case core.MessageGasEstimationMode:
return "gas_estimation_runmode"
case core.MessageEthcallMode:
return "eth_call_runmode"
case core.MessageReplayMode:
return "replay_runmode"
default:
return "unknown_runmode"
}
}

func (p Programs) CallProgram(
scope *vm.ScopeContext,
statedb vm.StateDB,
Expand All @@ -187,7 +172,7 @@ func (p Programs) CallProgram(
tracingInfo *util.TracingInfo,
calldata []byte,
reentrant bool,
runMode core.MessageRunMode,
runCtx *core.MessageRunContext,
) ([]byte, error) {
evm := interpreter.Evm()
contract := scope.Contract
Expand Down Expand Up @@ -233,7 +218,7 @@ func (p Programs) CallProgram(
statedb.AddStylusPages(program.footprint)
defer statedb.SetStylusPagesOpen(open)

localAsm, err := getLocalAsm(statedb, moduleHash, contract.Address(), contract.Code, contract.CodeHash, params.PageLimit, evm.Context.Time, debugMode, program)
localAsm, err := getLocalAsm(statedb, moduleHash, contract.Address(), contract.Code, contract.CodeHash, params.PageLimit, evm.Context.Time, debugMode, program, runCtx)
if err != nil {
panic("failed to get local wasm for activated program: " + contract.Address().Hex())
}
Expand Down Expand Up @@ -261,27 +246,22 @@ func (p Programs) CallProgram(
if contract.CodeAddr != nil {
address = *contract.CodeAddr
}
var arbos_tag uint32
if runMode == core.MessageCommitMode {
arbos_tag = statedb.Database().WasmCacheTag()
}

metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/program_calls/%s", runModeToString(runMode)), nil).Inc(1)
ret, err := callProgram(address, moduleHash, localAsm, scope, interpreter, tracingInfo, calldata, evmData, goParams, model, arbos_tag)
metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/program_calls/%s", runCtx.RunModeMetricName()), nil).Inc(1)
ret, err := callProgram(address, moduleHash, localAsm, scope, interpreter, tracingInfo, calldata, evmData, goParams, model, runCtx)
if len(ret) > 0 && arbosVersion >= gethParams.ArbosVersion_StylusFixes {
// Ensure that return data costs as least as much as it would in the EVM.
evmCost := evmMemoryCost(uint64(len(ret)))
if startingGas < evmCost {
contract.Gas = 0
// #nosec G115
metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/gas_used/%s", runModeToString(runMode)), nil).Inc(int64(startingGas))
metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/gas_used/%s", runCtx.RunModeMetricName()), nil).Inc(int64(startingGas))
return nil, vm.ErrOutOfGas
}
maxGasToReturn := startingGas - evmCost
contract.Gas = am.MinInt(contract.Gas, maxGasToReturn)
}
// #nosec G115
metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/gas_used/%s", runModeToString(runMode)), nil).Inc(int64(startingGas - contract.Gas))
metrics.GetOrRegisterCounter(fmt.Sprintf("arb/arbos/stylus/gas_used/%s", runCtx.RunModeMetricName()), nil).Inc(int64(startingGas - contract.Gas))
return ret, err
}

Expand Down Expand Up @@ -419,7 +399,7 @@ func (p Programs) SetProgramCached(
cache bool,
time uint64,
params *StylusParams,
runMode core.MessageRunMode,
runCtx *core.MessageRunContext,
debug bool,
) error {
program, err := p.getProgram(codeHash, time)
Expand Down Expand Up @@ -455,9 +435,9 @@ func (p Programs) SetProgramCached(
if err != nil {
return err
}
cacheProgram(db, moduleHash, program, address, code, codeHash, params, debug, time, runMode)
cacheProgram(db, moduleHash, program, address, code, codeHash, params, debug, time, runCtx)
} else {
evictProgram(db, moduleHash, program.version, debug, runMode, expired)
evictProgram(db, moduleHash, program.version, debug, runCtx, expired)
}
program.cached = cache
return p.setProgram(codeHash, program)
Expand Down
9 changes: 5 additions & 4 deletions arbos/programs/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func activateProgram(
arbosVersion uint64,
debug bool,
burner burn.Burner,
runCtx *core.MessageRunContext,
) (*activationInfo, error) {
errBuf := make([]byte, 1024)
debugMode := arbmath.BoolToUint32(debug)
Expand Down Expand Up @@ -98,9 +99,9 @@ func activateProgram(
}

// stub any non-consensus, Rust-side caching updates
func cacheProgram(db vm.StateDB, module common.Hash, program Program, addressForLogging common.Address, code []byte, codeHash common.Hash, params *StylusParams, debug bool, time uint64, runMode core.MessageRunMode) {
func cacheProgram(db vm.StateDB, module common.Hash, program Program, addressForLogging common.Address, code []byte, codeHash common.Hash, params *StylusParams, debug bool, time uint64, runCtx *core.MessageRunContext) {
}
func evictProgram(db vm.StateDB, module common.Hash, version uint16, debug bool, mode core.MessageRunMode, forever bool) {
func evictProgram(db vm.StateDB, module common.Hash, version uint16, debug bool, runCtx *core.MessageRunContext, forever bool) {
}

//go:wasmimport programs new_program
Expand Down Expand Up @@ -131,7 +132,7 @@ func startProgram(module uint32) uint32
//go:wasmimport programs send_response
func sendResponse(req_id uint32) uint32

func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging common.Address, code []byte, codeHash common.Hash, pagelimit uint16, time uint64, debugMode bool, program Program) ([]byte, error) {
func getLocalAsm(statedb vm.StateDB, moduleHash common.Hash, addressForLogging common.Address, code []byte, codeHash common.Hash, pagelimit uint16, time uint64, debugMode bool, program Program, runCtx *core.MessageRunContext) ([]byte, error) {
return nil, nil
}

Expand All @@ -146,7 +147,7 @@ func callProgram(
evmData *EvmData,
params *ProgParams,
memoryModel *MemoryModel,
_arbos_tag uint32,
runCtx *core.MessageRunContext,
) ([]byte, error) {
reqHandler := newApiClosures(interpreter, tracingInfo, scope, memoryModel)
gasLeft, retData, err := CallProgramLoop(moduleHash, calldata, scope.Contract.Gas, evmData, params, reqHandler)
Expand Down
Loading
Loading