diff --git a/core/rawdb/accessors_state_arbitrum.go b/core/rawdb/accessors_state_arbitrum.go index 32ccb1c94d..393917dc1d 100644 --- a/core/rawdb/accessors_state_arbitrum.go +++ b/core/rawdb/accessors_state_arbitrum.go @@ -22,15 +22,82 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// Stores the activated asm and module for a given codeHash -func WriteActivation(db ethdb.KeyValueWriter, moduleHash common.Hash, asm, module []byte) { - key := ActivatedAsmKey(moduleHash) +const ( + AsmArm = "arm" + AsmX86 = "x86" + AsmHost = "host" +) + +// Stores the activated module for a given moduleHash +func WriteActivatedModule(db ethdb.KeyValueWriter, moduleHash common.Hash, module []byte) { + key := activatedKey(activatedModulePrefix, moduleHash) + if err := db.Put(key[:], module); err != nil { + log.Crit("Failed to store activated wasm module", "err", err) + } +} + +func ReadActivatedModule(db ethdb.KeyValueReader, moduleHash common.Hash) []byte { + key := activatedKey(activatedModulePrefix, moduleHash) + module, err := db.Get(key[:]) + if err != nil { + return nil + } + return module +} + +// Stores the activated asm for a given arch and moduleHash +func WriteActivatedAsm(db ethdb.KeyValueWriter, arch string, moduleHash common.Hash, asm []byte) { + var prefix []byte + switch arch { + case AsmArm: + prefix = activatedAsmArmPrefix + case AsmX86: + prefix = activatedAsmX86Prefix + case AsmHost: + prefix = activatedAsmHostPrefix + default: + log.Crit("Failed to store activated wasm asm, invalid arch specified", "arch", arch) + } + key := activatedKey(prefix, moduleHash) if err := db.Put(key[:], asm); err != nil { log.Crit("Failed to store activated wasm asm", "err", err) } +} - key = ActivatedModuleKey(moduleHash) - if err := db.Put(key[:], module); err != nil { - log.Crit("Failed to store activated wasm module", "err", err) +func ReadActivatedAsm(db ethdb.KeyValueReader, arch string, moduleHash common.Hash) []byte { + var prefix []byte + switch arch { + case AsmArm: + prefix = activatedAsmArmPrefix + case AsmX86: + prefix = activatedAsmX86Prefix + case AsmHost: + prefix = activatedAsmHostPrefix + default: + log.Crit("Failed to store activated wasm asm, invalid arch specified", "arch", arch) + } + key := activatedKey(prefix, moduleHash) + asm, err := db.Get(key[:]) + if err != nil { + return nil + } + return asm +} + +// Stores wasm schema version +func WriteWasmSchemaVersion(db ethdb.KeyValueWriter) { + if err := db.Put(wasmSchemaVersionKey, []byte{wasmSchemaVersion}); err != nil { + log.Crit("Failed to store wasm schema version", "err", err) + } +} + +// Retrieves wasm schema version, if the correspoding key is not foud returns version 0 +func ReadWasmSchemaVersion(db ethdb.KeyValueReader) byte { + version, err := db.Get(wasmSchemaVersionKey) + if err != nil || len(version) == 0 { + return 0 + } else if len(version) != 1 { + log.Crit("Invalid wasm schema version in database", "version", version) } + return version[0] } diff --git a/core/rawdb/schema_arbitrum.go b/core/rawdb/schema_arbitrum.go index 72a3f755bb..9ebe5dc342 100644 --- a/core/rawdb/schema_arbitrum.go +++ b/core/rawdb/schema_arbitrum.go @@ -19,48 +19,30 @@ package rawdb import ( - "bytes" - "github.com/ethereum/go-ethereum/common" ) +const wasmSchemaVersion byte = 0x01 + var ( - activatedAsmPrefix = []byte{0x00, 'w', 'a'} // (prefix, moduleHash) -> stylus asm - activatedModulePrefix = []byte{0x00, 'w', 'm'} // (prefix, moduleHash) -> stylus module + wasmSchemaVersionKey = []byte("WasmSchemaVersion") + + // TODO do we need 0x00 prefix? or even: do we need also 'w' there? + activatedAsmArmPrefix = []byte{0x00, 'w', 'r'} // (prefix, moduleHash) -> stylus asm for ARM system + activatedAsmX86Prefix = []byte{0x00, 'w', 'x'} // (prefix, moduleHash) -> stylus asm for x86 system + activatedAsmHostPrefix = []byte{0x00, 'w', 'h'} // (prefix, moduleHash) -> stylus asm for system other then ARM and x86 + activatedModulePrefix = []byte{0x00, 'w', 'm'} // (prefix, moduleHash) -> stylus module ) // WasmKeyLen = CompiledWasmCodePrefix + moduleHash -const WasmKeyLen = 3 + 32 +const WasmKeyLen = 3 + common.HashLength type WasmKey = [WasmKeyLen]byte -func ActivatedAsmKey(moduleHash common.Hash) WasmKey { - return newWasmKey(activatedAsmPrefix, moduleHash) -} - -func ActivatedModuleKey(moduleHash common.Hash) WasmKey { - return newWasmKey(activatedModulePrefix, moduleHash) -} - // key = prefix + moduleHash -func newWasmKey(prefix []byte, moduleHash common.Hash) WasmKey { +func activatedKey(prefix []byte, moduleHash common.Hash) WasmKey { var key WasmKey copy(key[:3], prefix) copy(key[3:], moduleHash[:]) return key } - -func IsActivatedAsmKey(key []byte) (bool, common.Hash) { - return extractWasmKey(activatedAsmPrefix, key) -} - -func IsActivatedModuleKey(key []byte) (bool, common.Hash) { - return extractWasmKey(activatedModulePrefix, key) -} - -func extractWasmKey(prefix, key []byte) (bool, common.Hash) { - if !bytes.HasPrefix(key, prefix) || len(key) != WasmKeyLen { - return false, common.Hash{} - } - return true, common.BytesToHash(key[len(prefix):]) -} diff --git a/core/state/database.go b/core/state/database.go index aa671be038..942fce89f7 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -52,7 +52,7 @@ const ( // Database wraps access to tries and contract code. type Database interface { // Arbitrum: Read activated Stylus contracts - ActivatedAsm(moduleHash common.Hash) (asm []byte, err error) + ActivatedAsm(arch string, moduleHash common.Hash) (asm []byte, err error) ActivatedModule(moduleHash common.Hash) (module []byte, err error) WasmStore() ethdb.KeyValueStore WasmCacheTag() uint32 @@ -196,6 +196,7 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database { type cachingDB struct { // Arbitrum + // asm cache caches only asm compiled for the machine architecture activatedAsmCache *lru.SizeConstrainedCache[common.Hash, []byte] activatedModuleCache *lru.SizeConstrainedCache[common.Hash, []byte] wasmTag uint32 diff --git a/core/state/database_arbitrum.go b/core/state/database_arbitrum.go index 6171b4cd10..e9270b8fbf 100644 --- a/core/state/database_arbitrum.go +++ b/core/state/database_arbitrum.go @@ -7,16 +7,11 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" ) -func (db *cachingDB) ActivatedAsm(moduleHash common.Hash) ([]byte, error) { +func (db *cachingDB) ActivatedAsm(arch string, moduleHash common.Hash) ([]byte, error) { if asm, _ := db.activatedAsmCache.Get(moduleHash); len(asm) > 0 { return asm, nil } - wasmKey := rawdb.ActivatedAsmKey(moduleHash) - asm, err := db.wasmdb.Get(wasmKey[:]) - if err != nil { - return nil, err - } - if len(asm) > 0 { + if asm := rawdb.ReadActivatedAsm(arch, moduleHash); len(asm) > 0 { db.activatedAsmCache.Add(moduleHash, asm) return asm, nil } @@ -27,12 +22,7 @@ func (db *cachingDB) ActivatedModule(moduleHash common.Hash) ([]byte, error) { if module, _ := db.activatedModuleCache.Get(moduleHash); len(module) > 0 { return module, nil } - wasmKey := rawdb.ActivatedModuleKey(moduleHash) - module, err := db.wasmdb.Get(wasmKey[:]) - if err != nil { - return nil, err - } - if len(module) > 0 { + if module := rawdb.ReadActivatedModule(db.wasmdb, moduleHash); len(module) > 0 { db.activatedModuleCache.Add(moduleHash, module) return module, nil } diff --git a/core/state/statedb_arbitrum.go b/core/state/statedb_arbitrum.go index e459ad4570..87c5b376e9 100644 --- a/core/state/statedb_arbitrum.go +++ b/core/state/statedb_arbitrum.go @@ -50,7 +50,7 @@ var ( ) type ActivatedWasm struct { - Asm []byte + Asm map[string][]byte Module []byte }