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 16 commits into
base: ondemand-module-compile
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -7,7 +7,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 @@ -58,7 +58,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)
}
8 changes: 4 additions & 4 deletions arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,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 @@ -154,7 +154,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 @@ -169,7 +169,7 @@ func ProduceBlockAdvanced(
chainConfig *params.ChainConfig,
sequencingHooks *SequencingHooks,
isMsgForPrefetch bool,
runMode core.MessageRunMode,
runCtx *core.MessageRunContext,
) (*types.Block, types.Receipts, error) {

state, err := arbosState.OpenSystemArbosState(statedb, nil, true)
Expand Down Expand Up @@ -320,7 +320,7 @@ func ProduceBlockAdvanced(
tx,
&header.GasUsed,
vm.Config{},
runMode,
runCtx,
func(result *core.ExecutionResult) error {
return hooks.PostTxFilter(header, state, 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 @@ -559,7 +559,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
45 changes: 22 additions & 23 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,9 +159,10 @@ 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
for _, target := range targets {
if target == rawdb.TargetWavm {
Expand All @@ -171,11 +171,11 @@ func activateProgramInternal(
}
}
type result struct {
target ethdb.WasmTarget
target rawdb.WasmTarget
asm []byte
err error
}
asmMap := make(map[ethdb.WasmTarget][]byte, len(targets))
asmMap := make(map[rawdb.WasmTarget][]byte, len(targets))

// info can be set in separate thread, make sure to wait before reading
var info *activationInfo
Expand Down Expand Up @@ -252,7 +252,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 @@ -270,10 +270,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 := true // TODO: refactor the parameter, always set to true
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 @@ -300,7 +299,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 @@ -321,7 +320,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 @@ -332,7 +331,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 @@ -348,7 +347,7 @@ func callProgram(
cbool(debug),
output,
(*u64)(&scope.Contract.Gas),
u32(arbos_tag),
u32(runCtx.WasmCacheTag()),
))

depth := interpreter.Depth()
Expand All @@ -375,24 +374,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 @@ -482,7 +481,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
24 changes: 10 additions & 14 deletions arbos/programs/programs.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,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 @@ -117,7 +117,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 @@ -129,7 +129,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 @@ -157,7 +157,7 @@ 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)
Expand All @@ -171,7 +171,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 @@ -217,7 +217,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 {
log.Crit("failed to get local wasm for activated program", "program", contract.Address())
return nil, err
Expand Down Expand Up @@ -246,11 +246,7 @@ func (p Programs) CallProgram(
if contract.CodeAddr != nil {
address = *contract.CodeAddr
}
var arbos_tag uint32
if runMode == core.MessageCommitMode {
arbos_tag = statedb.Database().WasmCacheTag()
}
ret, err := callProgram(address, moduleHash, localAsm, scope, interpreter, tracingInfo, calldata, evmData, goParams, model, arbos_tag)
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)))
Expand Down Expand Up @@ -398,7 +394,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 @@ -434,9 +430,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
8 changes: 4 additions & 4 deletions arbos/programs/wasmstorehelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/log"
)

// 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 {
func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash common.Hash, code []byte, time uint64, debugMode bool, rebuildingStartBlockTime uint64, targets []rawdb.WasmTarget) error {
progParams, err := p.Params()
if err != nil {
return err
Expand All @@ -43,7 +44,6 @@ func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash
return err
}

targets := statedb.Database().WasmTargets()
// If already in wasm store then return early
_, err = statedb.TryGetActivatedAsmMap(targets, moduleHash)
if err == nil {
Expand All @@ -63,13 +63,13 @@ func (p Programs) SaveActiveProgramToWasmStore(statedb *state.StateDB, codeHash
// 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
moduleActivationMandatory := false
info, asmMap, err := activateProgramInternal(common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, zeroArbosVersion, debugMode, &zeroGas, targets, moduleActivationMandatory)
info, asmMap, err := activateProgramInternal(common.Address{}, codeHash, wasm, progParams.PageLimit, program.version, zeroArbosVersion, debugMode, &zeroGas, core.NewMessageReplayContext(targets), moduleActivationMandatory)
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)
}

if info.moduleHash != moduleHash {
if info != nil && info.moduleHash != moduleHash {
log.Error("failed to reactivate program while rebuilding wasm store", "expected moduleHash", moduleHash, "got", info.moduleHash)
return fmt.Errorf("failed to reactivate program while rebuilding wasm store, expected ModuleHash: %v", moduleHash)
}
Expand Down
Loading
Loading