From 1bca17f6f3b832c3dc6ea55edeefac9d72313714 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 8 May 2024 17:37:13 -0600 Subject: [PATCH 01/11] ethDB: support a separate wasmDatabase --- core/rawdb/database.go | 24 ++++++++++++++++++++++++ core/rawdb/table.go | 4 ++++ ethdb/database.go | 5 +++++ ethdb/remotedb/remotedb.go | 4 ++++ node/node.go | 28 ++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 27a9ec7412..1aad8226a6 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -40,6 +40,15 @@ type freezerdb struct { ancientRoot string ethdb.KeyValueStore ethdb.AncientStore + wasmDB ethdb.KeyValueStore +} + +// AncientDatadir returns the path of root ancient directory. +func (frdb *freezerdb) WasmDataBase() ethdb.KeyValueStore { + if frdb.wasmDB == nil { + return frdb + } + return frdb.wasmDB } // AncientDatadir returns the path of root ancient directory. @@ -165,6 +174,11 @@ func (db *nofreezedb) AncientDatadir() (string, error) { return "", errNotSupported } +// AncientDatadir returns the path of root ancient directory. +func (db *nofreezedb) WasmDataBase() ethdb.KeyValueStore { + return db +} + // NewDatabase creates a high level database on top of a given key-value data // store without a freezer moving immutable chain segments into cold storage. func NewDatabase(db ethdb.KeyValueStore) ethdb.Database { @@ -360,6 +374,7 @@ type OpenOptions struct { Directory string // the datadir AncientsDirectory string // the ancients-dir Namespace string // the namespace for database relevant metrics + WasmDirectory string // the wasm-dir Cache int // the capacity(in megabytes) of the data caching Handles int // number of files to be open simultaneously ReadOnly bool @@ -416,6 +431,15 @@ func Open(o OpenOptions) (ethdb.Database, error) { kvdb.Close() return nil, err } + if len(o.WasmDirectory) != 0 { + wasmOptions := o + wasmOptions.Directory = o.WasmDirectory + wasmDb, err := openKeyValueDatabase(wasmOptions) + if err != nil { + return nil, err + } + frdb.(*freezerdb).wasmDB = wasmDb + } return frdb, nil } diff --git a/core/rawdb/table.go b/core/rawdb/table.go index 19e4ed5b5c..1c7b572899 100644 --- a/core/rawdb/table.go +++ b/core/rawdb/table.go @@ -40,6 +40,10 @@ func (t *table) Close() error { return nil } +func (t *table) WasmDataBase() ethdb.KeyValueStore { + return t.db.WasmDataBase() +} + // Has retrieves if a prefixed version of a key is present in the database. func (t *table) Has(key []byte) (bool, error) { return t.db.Has(append([]byte(t.prefix), key...)) diff --git a/ethdb/database.go b/ethdb/database.go index 4d4817daf2..66b736a13b 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -178,6 +178,10 @@ type AncientStore interface { io.Closer } +type WasmDataBaseRetriever interface { + WasmDataBase() KeyValueStore +} + // Database contains all the methods required by the high level database to not // only access the key-value data store but also the chain freezer. type Database interface { @@ -189,4 +193,5 @@ type Database interface { Compacter Snapshotter io.Closer + WasmDataBaseRetriever } diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index c1c803caf2..9add7672f2 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -39,6 +39,10 @@ func (db *Database) Has(key []byte) (bool, error) { return true, nil } +func (t *Database) WasmDataBase() ethdb.KeyValueStore { + return t +} + func (db *Database) Get(key []byte) ([]byte, error) { var resp hexutil.Bytes err := db.remote.Call(&resp, "debug_dbGet", hexutil.Bytes(key)) diff --git a/node/node.go b/node/node.go index 8b6d28e769..9b35c685ba 100644 --- a/node/node.go +++ b/node/node.go @@ -797,6 +797,34 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient ReadOnly: readonly, }) } + if err == nil { + db = n.wrapDatabase(db) + } + return db, err +} + +func (n *Node) OpenDatabaseWithFreezerAndWasm(name string, wasmPath string, cache, handles int, ancient string, namespace string, readonly bool) (ethdb.Database, error) { + n.lock.Lock() + defer n.lock.Unlock() + if n.state == closedState { + return nil, ErrNodeStopped + } + var db ethdb.Database + var err error + if n.config.DataDir == "" { + db = rawdb.NewMemoryDatabase() + } else { + db, err = rawdb.Open(rawdb.OpenOptions{ + Type: n.config.DBEngine, + Directory: n.ResolvePath(name), + AncientsDirectory: n.ResolveAncient(name, ancient), + Namespace: namespace, + WasmDirectory: n.ResolvePath(wasmPath), + Cache: cache, + Handles: handles, + ReadOnly: readonly, + }) + } if err == nil { db = n.wrapDatabase(db) From 74a5816e661c88080a479a0db875052b14e14651 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 8 May 2024 19:22:14 -0600 Subject: [PATCH 02/11] stateDataBase: add support for wasmDB and use it --- core/state/database.go | 8 ++++++++ core/state/database_arbitrum.go | 4 ++-- core/state/statedb.go | 8 +++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/state/database.go b/core/state/database.go index 48022d0e99..1ad1c6b3e5 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -54,6 +54,7 @@ type Database interface { // Arbitrum: Read activated Stylus contracts ActivatedAsm(moduleHash common.Hash) (asm []byte, err error) ActivatedModule(moduleHash common.Hash) (module []byte, err error) + WasmStore() ethdb.KeyValueStore // OpenTrie opens the main account trie. OpenTrie(root common.Hash) (Trie, error) @@ -164,6 +165,7 @@ func NewDatabaseWithConfig(db ethdb.Database, config *trie.Config) Database { activatedModuleCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize), disk: db, + wasmdb: db.WasmDataBase(), codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), triedb: trie.NewDatabase(db, config), @@ -179,6 +181,7 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database { activatedModuleCache: lru.NewSizeConstrainedCache[common.Hash, []byte](activatedWasmCacheSize), disk: db, + wasmdb: db.WasmDataBase(), codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), triedb: triedb, @@ -192,11 +195,16 @@ type cachingDB struct { activatedModuleCache *lru.SizeConstrainedCache[common.Hash, []byte] disk ethdb.KeyValueStore + wasmdb ethdb.KeyValueStore codeSizeCache *lru.Cache[common.Hash, int] codeCache *lru.SizeConstrainedCache[common.Hash, []byte] triedb *trie.Database } +func (db *cachingDB) WasmStore() ethdb.KeyValueStore { + return db.wasmdb +} + // OpenTrie opens the main account trie at a specific root hash. func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { if db.triedb.IsVerkle() { diff --git a/core/state/database_arbitrum.go b/core/state/database_arbitrum.go index 6e545eb0a0..6171b4cd10 100644 --- a/core/state/database_arbitrum.go +++ b/core/state/database_arbitrum.go @@ -12,7 +12,7 @@ func (db *cachingDB) ActivatedAsm(moduleHash common.Hash) ([]byte, error) { return asm, nil } wasmKey := rawdb.ActivatedAsmKey(moduleHash) - asm, err := db.disk.Get(wasmKey[:]) + asm, err := db.wasmdb.Get(wasmKey[:]) if err != nil { return nil, err } @@ -28,7 +28,7 @@ func (db *cachingDB) ActivatedModule(moduleHash common.Hash) ([]byte, error) { return module, nil } wasmKey := rawdb.ActivatedModuleKey(moduleHash) - module, err := db.disk.Get(wasmKey[:]) + module, err := db.wasmdb.Get(wasmKey[:]) if err != nil { return nil, err } diff --git a/core/state/statedb.go b/core/state/statedb.go index 28c6aeb2c2..6dc72f88e6 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1249,6 +1249,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er storageTrieNodesDeleted int nodes = trienode.NewMergedNodeSet() codeWriter = s.db.DiskDB().NewBatch() + wasmCodeWriter = s.db.WasmStore().NewBatch() ) // Handle all state deletions first incomplete, err := s.handleDestruction(nodes) @@ -1286,7 +1287,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er // Arbitrum: write Stylus programs to disk for moduleHash, info := range s.arbExtraData.activatedWasms { - rawdb.WriteActivation(codeWriter, moduleHash, info.Asm, info.Module) + rawdb.WriteActivation(wasmCodeWriter, moduleHash, info.Asm, info.Module) } if len(s.arbExtraData.activatedWasms) > 0 { s.arbExtraData.activatedWasms = make(map[common.Hash]*ActivatedWasm) @@ -1297,6 +1298,11 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er log.Crit("Failed to commit dirty codes", "error", err) } } + if wasmCodeWriter.ValueSize() > 0 { + if err := wasmCodeWriter.Write(); err != nil { + log.Crit("Failed to commit dirty stylus codes", "error", err) + } + } // Write the account trie changes, measuring the amount of wasted time var start time.Time if metrics.EnabledExpensive { From 0380e226019f83919c5e10e7bd696a6dec08e02a Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Wed, 8 May 2024 19:22:58 -0600 Subject: [PATCH 03/11] recordingDB: use wasmStore --- arbitrum/recordingdb.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arbitrum/recordingdb.go b/arbitrum/recordingdb.go index 6da71a497e..a944ce2f90 100644 --- a/arbitrum/recordingdb.go +++ b/arbitrum/recordingdb.go @@ -32,12 +32,13 @@ var ( type RecordingKV struct { inner *trie.Database diskDb ethdb.KeyValueStore + wasmDb ethdb.KeyValueStore readDbEntries map[common.Hash][]byte enableBypass bool } -func newRecordingKV(inner *trie.Database, diskDb ethdb.KeyValueStore) *RecordingKV { - return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), false} +func newRecordingKV(inner *trie.Database, diskDb ethdb.KeyValueStore, wasmDb ethdb.KeyValueStore) *RecordingKV { + return &RecordingKV{inner, diskDb, wasmDb, make(map[common.Hash][]byte), false} } func (db *RecordingKV) Has(key []byte) (bool, error) { @@ -57,10 +58,10 @@ func (db *RecordingKV) Get(key []byte) ([]byte, error) { res, err = db.diskDb.Get(key) } else if ok, _ := rawdb.IsActivatedAsmKey(key); ok { // Arbitrum: the asm is non-consensus - return db.diskDb.Get(key) + return db.wasmDb.Get(key) } else if ok, _ := rawdb.IsActivatedModuleKey(key); ok { // Arbitrum: the module is non-consensus (only its hash is) - return db.diskDb.Get(key) + return db.wasmDb.Get(key) } else { err = fmt.Errorf("recording KV attempted to access non-hash key %v", hex.EncodeToString(key)) } @@ -273,7 +274,7 @@ func (r *RecordingDatabase) PrepareRecording(ctx context.Context, lastBlockHeade } finalDereference := lastBlockHeader // dereference in case of error defer func() { r.Dereference(finalDereference) }() - recordingKeyValue := newRecordingKV(r.db.TrieDB(), r.db.DiskDB()) + recordingKeyValue := newRecordingKV(r.db.TrieDB(), r.db.DiskDB(), r.db.WasmStore()) recordingStateDatabase := state.NewDatabase(rawdb.NewDatabase(recordingKeyValue)) var prevRoot common.Hash From 515e912285850776bd29eccda65d63607aec2dec Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 9 May 2024 16:23:12 -0600 Subject: [PATCH 04/11] StateDB: add TryGetActivatedWasm If not found in db - returns an error instead of marking state for revertion --- core/state/statedb_arbitrum.go | 10 +++++++--- core/vm/interface.go | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/state/statedb_arbitrum.go b/core/state/statedb_arbitrum.go index 0d769f8f56..3f751f6e39 100644 --- a/core/state/statedb_arbitrum.go +++ b/core/state/statedb_arbitrum.go @@ -89,12 +89,16 @@ func (s *StateDB) ActivateWasm(moduleHash common.Hash, asm, module []byte) { }) } -func (s *StateDB) GetActivatedAsm(moduleHash common.Hash) []byte { +func (s *StateDB) TryGetActivatedAsm(moduleHash common.Hash) ([]byte, error) { info, exists := s.arbExtraData.activatedWasms[moduleHash] if exists { - return info.Asm + return info.Asm, nil } - asm, err := s.db.ActivatedAsm(moduleHash) + return s.db.ActivatedAsm(moduleHash) +} + +func (s *StateDB) GetActivatedAsm(moduleHash common.Hash) []byte { + asm, err := s.TryGetActivatedAsm(moduleHash) if err != nil { s.setError(fmt.Errorf("failed to load asm for %x: %v", moduleHash, err)) } diff --git a/core/vm/interface.go b/core/vm/interface.go index d94d9cfcec..b16bbc2e62 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -31,6 +31,7 @@ type StateDB interface { // Arbitrum: manage Stylus wasms ActivateWasm(moduleHash common.Hash, asm, module []byte) GetActivatedAsm(moduleHash common.Hash) (asm []byte) + TryGetActivatedAsm(moduleHash common.Hash) (asm []byte, err error) GetActivatedModule(moduleHash common.Hash) (module []byte) RecordCacheWasm(wasm state.CacheWasm) RecordEvictWasm(wasm state.EvictWasm) From 37b6489382bb884dd1216dcb0f6a224ce2ca5fe2 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Thu, 9 May 2024 19:09:14 -0600 Subject: [PATCH 05/11] stateOverride: don't allow arbOS --- internal/ethapi/api.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 70bf80881c..53013335fc 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -962,12 +962,17 @@ type OverrideAccount struct { // StateOverride is the collection of overridden accounts. type StateOverride map[common.Address]OverrideAccount +var arbStorageAddress = common.HexToAddress("0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + // Apply overrides the fields of specified accounts into the given state. func (diff *StateOverride) Apply(state *state.StateDB) error { if diff == nil { return nil } for addr, account := range *diff { + if addr == arbStorageAddress { + return errors.New("overriding 0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF not allowed") + } // Override account nonce. if account.Nonce != nil { state.SetNonce(addr, uint64(*account.Nonce)) From 45145108b11e39ea57ee5b0a1238440edd1fa3ab Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 10 May 2024 10:32:05 -0600 Subject: [PATCH 06/11] wasm database: extract to a separate wrap --- core/rawdb/database.go | 16 +------------ node/node.go | 51 ++++++++++++++++++------------------------ 2 files changed, 23 insertions(+), 44 deletions(-) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 1aad8226a6..9dbff40239 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -40,15 +40,11 @@ type freezerdb struct { ancientRoot string ethdb.KeyValueStore ethdb.AncientStore - wasmDB ethdb.KeyValueStore } // AncientDatadir returns the path of root ancient directory. func (frdb *freezerdb) WasmDataBase() ethdb.KeyValueStore { - if frdb.wasmDB == nil { - return frdb - } - return frdb.wasmDB + return frdb } // AncientDatadir returns the path of root ancient directory. @@ -374,7 +370,6 @@ type OpenOptions struct { Directory string // the datadir AncientsDirectory string // the ancients-dir Namespace string // the namespace for database relevant metrics - WasmDirectory string // the wasm-dir Cache int // the capacity(in megabytes) of the data caching Handles int // number of files to be open simultaneously ReadOnly bool @@ -431,15 +426,6 @@ func Open(o OpenOptions) (ethdb.Database, error) { kvdb.Close() return nil, err } - if len(o.WasmDirectory) != 0 { - wasmOptions := o - wasmOptions.Directory = o.WasmDirectory - wasmDb, err := openKeyValueDatabase(wasmOptions) - if err != nil { - return nil, err - } - frdb.(*freezerdb).wasmDB = wasmDb - } return frdb, nil } diff --git a/node/node.go b/node/node.go index 9b35c685ba..7bf2db7cc9 100644 --- a/node/node.go +++ b/node/node.go @@ -803,35 +803,6 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient return db, err } -func (n *Node) OpenDatabaseWithFreezerAndWasm(name string, wasmPath string, cache, handles int, ancient string, namespace string, readonly bool) (ethdb.Database, error) { - n.lock.Lock() - defer n.lock.Unlock() - if n.state == closedState { - return nil, ErrNodeStopped - } - var db ethdb.Database - var err error - if n.config.DataDir == "" { - db = rawdb.NewMemoryDatabase() - } else { - db, err = rawdb.Open(rawdb.OpenOptions{ - Type: n.config.DBEngine, - Directory: n.ResolvePath(name), - AncientsDirectory: n.ResolveAncient(name, ancient), - Namespace: namespace, - WasmDirectory: n.ResolvePath(wasmPath), - Cache: cache, - Handles: handles, - ReadOnly: readonly, - }) - } - - if err == nil { - db = n.wrapDatabase(db) - } - return db, err -} - // ResolvePath returns the absolute path of a resource in the instance directory. func (n *Node) ResolvePath(x string) string { return n.config.ResolvePath(x) @@ -848,6 +819,28 @@ func (n *Node) ResolveAncient(name string, ancient string) string { return ancient } +type dbWithWasmEntry struct { + ethdb.Database + wasmDb ethdb.KeyValueStore +} + +func (db *dbWithWasmEntry) WasmDataBase() ethdb.KeyValueStore { + return db.wasmDb +} + +func (db *dbWithWasmEntry) Close() error { + dbErr := db.Database.Close() + wasmErr := db.wasmDb.Close() + if dbErr != nil { + return dbErr + } + return wasmErr +} + +func (n *Node) WrapDatabaseWithWasm(db ethdb.Database, wasm ethdb.KeyValueStore) ethdb.Database { + return &dbWithWasmEntry{db, wasm} +} + // closeTrackingDB wraps the Close method of a database. When the database is closed by the // service, the wrapper removes it from the node's database map. This ensures that Node // won't auto-close the database if it is closed by the service that opened it. From 8d94d2b164ea3b277a1e87dcdc6f61c5beeaefd8 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 10 May 2024 15:23:14 -0600 Subject: [PATCH 07/11] remove GetActivatedASM --- core/state/journal_arbitrum.go | 7 +++++-- core/state/statedb_arbitrum.go | 15 ++++++--------- core/vm/interface.go | 1 - 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/core/state/journal_arbitrum.go b/core/state/journal_arbitrum.go index 804a308ec2..c092fc7640 100644 --- a/core/state/journal_arbitrum.go +++ b/core/state/journal_arbitrum.go @@ -41,8 +41,11 @@ type EvictWasm struct { } func (ch EvictWasm) revert(s *StateDB) { - asm := s.GetActivatedAsm(ch.ModuleHash) // only happens in native mode - CacheWasmRust(asm, ch.ModuleHash, ch.Version, ch.Debug) + asm, err := s.TryGetActivatedAsm(ch.ModuleHash) // only happens in native mode + if err == nil && len(asm) == 0 { + //if we failed to get it - it's not in the current rust cache + CacheWasmRust(asm, ch.ModuleHash, ch.Version, ch.Debug) + } } func (ch EvictWasm) dirtied() *common.Address { diff --git a/core/state/statedb_arbitrum.go b/core/state/statedb_arbitrum.go index 3f751f6e39..e459ad4570 100644 --- a/core/state/statedb_arbitrum.go +++ b/core/state/statedb_arbitrum.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -97,14 +98,6 @@ func (s *StateDB) TryGetActivatedAsm(moduleHash common.Hash) ([]byte, error) { return s.db.ActivatedAsm(moduleHash) } -func (s *StateDB) GetActivatedAsm(moduleHash common.Hash) []byte { - asm, err := s.TryGetActivatedAsm(moduleHash) - if err != nil { - s.setError(fmt.Errorf("failed to load asm for %x: %v", moduleHash, err)) - } - return asm -} - func (s *StateDB) GetActivatedModule(moduleHash common.Hash) []byte { info, exists := s.arbExtraData.activatedWasms[moduleHash] if exists { @@ -241,9 +234,13 @@ func (s *StateDB) StartRecording() { } func (s *StateDB) RecordProgram(moduleHash common.Hash) { + asm, err := s.TryGetActivatedAsm(moduleHash) + if err != nil { + log.Crit("can't find activated wasm while recording", "modulehash", moduleHash) + } if s.arbExtraData.userWasms != nil { s.arbExtraData.userWasms[moduleHash] = ActivatedWasm{ - Asm: s.GetActivatedAsm(moduleHash), + Asm: asm, Module: s.GetActivatedModule(moduleHash), } } diff --git a/core/vm/interface.go b/core/vm/interface.go index b16bbc2e62..43393b54f7 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -30,7 +30,6 @@ import ( type StateDB interface { // Arbitrum: manage Stylus wasms ActivateWasm(moduleHash common.Hash, asm, module []byte) - GetActivatedAsm(moduleHash common.Hash) (asm []byte) TryGetActivatedAsm(moduleHash common.Hash) (asm []byte, err error) GetActivatedModule(moduleHash common.Hash) (module []byte) RecordCacheWasm(wasm state.CacheWasm) From e9b2c953d99fe50f9b673d11a1c07ec2d10f0a93 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 10 May 2024 16:19:20 -0600 Subject: [PATCH 08/11] move dbWithWasm to rawdb --- core/rawdb/database.go | 22 ++++++++++++++++++++++ node/node.go | 22 ---------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 9dbff40239..fd011d884f 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -181,6 +181,28 @@ func NewDatabase(db ethdb.KeyValueStore) ethdb.Database { return &nofreezedb{KeyValueStore: db} } +type dbWithWasmEntry struct { + ethdb.Database + wasmDb ethdb.KeyValueStore +} + +func (db *dbWithWasmEntry) WasmDataBase() ethdb.KeyValueStore { + return db.wasmDb +} + +func (db *dbWithWasmEntry) Close() error { + dbErr := db.Database.Close() + wasmErr := db.wasmDb.Close() + if dbErr != nil { + return dbErr + } + return wasmErr +} + +func WrapDatabaseWithWasm(db ethdb.Database, wasm ethdb.KeyValueStore) ethdb.Database { + return &dbWithWasmEntry{db, wasm} +} + // resolveChainFreezerDir is a helper function which resolves the absolute path // of chain freezer by considering backward compatibility. func resolveChainFreezerDir(ancient string) string { diff --git a/node/node.go b/node/node.go index bdcbeefe5c..20aad14e90 100644 --- a/node/node.go +++ b/node/node.go @@ -821,28 +821,6 @@ func (n *Node) ResolveAncient(name string, ancient string) string { return ancient } -type dbWithWasmEntry struct { - ethdb.Database - wasmDb ethdb.KeyValueStore -} - -func (db *dbWithWasmEntry) WasmDataBase() ethdb.KeyValueStore { - return db.wasmDb -} - -func (db *dbWithWasmEntry) Close() error { - dbErr := db.Database.Close() - wasmErr := db.wasmDb.Close() - if dbErr != nil { - return dbErr - } - return wasmErr -} - -func (n *Node) WrapDatabaseWithWasm(db ethdb.Database, wasm ethdb.KeyValueStore) ethdb.Database { - return &dbWithWasmEntry{db, wasm} -} - // closeTrackingDB wraps the Close method of a database. When the database is closed by the // service, the wrapper removes it from the node's database map. This ensures that Node // won't auto-close the database if it is closed by the service that opened it. From f8917436fcfa6a6a2b15c0ec7e6f318687491a8c Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Fri, 10 May 2024 16:19:36 -0600 Subject: [PATCH 09/11] recordingKV uses separate wasmDB --- arbitrum/recordingdb.go | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/arbitrum/recordingdb.go b/arbitrum/recordingdb.go index a944ce2f90..fff22db43f 100644 --- a/arbitrum/recordingdb.go +++ b/arbitrum/recordingdb.go @@ -32,13 +32,12 @@ var ( type RecordingKV struct { inner *trie.Database diskDb ethdb.KeyValueStore - wasmDb ethdb.KeyValueStore readDbEntries map[common.Hash][]byte enableBypass bool } -func newRecordingKV(inner *trie.Database, diskDb ethdb.KeyValueStore, wasmDb ethdb.KeyValueStore) *RecordingKV { - return &RecordingKV{inner, diskDb, wasmDb, make(map[common.Hash][]byte), false} +func newRecordingKV(inner *trie.Database, diskDb ethdb.KeyValueStore) *RecordingKV { + return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), false} } func (db *RecordingKV) Has(key []byte) (bool, error) { @@ -56,12 +55,6 @@ func (db *RecordingKV) Get(key []byte) ([]byte, error) { // Retrieving code copy(hash[:], key[len(rawdb.CodePrefix):]) res, err = db.diskDb.Get(key) - } else if ok, _ := rawdb.IsActivatedAsmKey(key); ok { - // Arbitrum: the asm is non-consensus - return db.wasmDb.Get(key) - } else if ok, _ := rawdb.IsActivatedModuleKey(key); ok { - // Arbitrum: the module is non-consensus (only its hash is) - return db.wasmDb.Get(key) } else { err = fmt.Errorf("recording KV attempted to access non-hash key %v", hex.EncodeToString(key)) } @@ -274,9 +267,9 @@ func (r *RecordingDatabase) PrepareRecording(ctx context.Context, lastBlockHeade } finalDereference := lastBlockHeader // dereference in case of error defer func() { r.Dereference(finalDereference) }() - recordingKeyValue := newRecordingKV(r.db.TrieDB(), r.db.DiskDB(), r.db.WasmStore()) + recordingKeyValue := newRecordingKV(r.db.TrieDB(), r.db.DiskDB()) - recordingStateDatabase := state.NewDatabase(rawdb.NewDatabase(recordingKeyValue)) + recordingStateDatabase := state.NewDatabase(rawdb.WrapDatabaseWithWasm(rawdb.NewDatabase(recordingKeyValue), r.db.WasmStore())) var prevRoot common.Hash if lastBlockHeader != nil { prevRoot = lastBlockHeader.Root From c68494d0ee7ecb96e21575f8da663f35ad7d48a8 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 14 May 2024 19:09:49 -0600 Subject: [PATCH 10/11] fix evictWasm revert --- core/state/journal_arbitrum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state/journal_arbitrum.go b/core/state/journal_arbitrum.go index c092fc7640..ef35454121 100644 --- a/core/state/journal_arbitrum.go +++ b/core/state/journal_arbitrum.go @@ -42,7 +42,7 @@ type EvictWasm struct { func (ch EvictWasm) revert(s *StateDB) { asm, err := s.TryGetActivatedAsm(ch.ModuleHash) // only happens in native mode - if err == nil && len(asm) == 0 { + if err == nil && len(asm) != 0 { //if we failed to get it - it's not in the current rust cache CacheWasmRust(asm, ch.ModuleHash, ch.Version, ch.Debug) } From 8048ac4bed2eda18284e3c022ea5ee4cce771134 Mon Sep 17 00:00:00 2001 From: Tsahi Zidenberg Date: Tue, 14 May 2024 19:10:16 -0600 Subject: [PATCH 11/11] api: use ArbosStateAddress directly --- internal/ethapi/api.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0629e238b4..1223441b98 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -962,16 +962,14 @@ type OverrideAccount struct { // StateOverride is the collection of overridden accounts. type StateOverride map[common.Address]OverrideAccount -var arbStorageAddress = common.HexToAddress("0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") - // Apply overrides the fields of specified accounts into the given state. func (diff *StateOverride) Apply(state *state.StateDB) error { if diff == nil { return nil } for addr, account := range *diff { - if addr == arbStorageAddress { - return errors.New("overriding 0xA4B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF not allowed") + if addr == types.ArbosStateAddress { + return fmt.Errorf("overriding address %v not allowed", types.ArbosStateAddress) } // Override account nonce. if account.Nonce != nil {