From 786263c0b827388bb0d84716936d6ec9d2284c20 Mon Sep 17 00:00:00 2001 From: Jordan Hrycaj Date: Wed, 11 Oct 2023 20:09:11 +0100 Subject: [PATCH] Core db update api and fix tracer methods (#1816) * CoreDB: Re-org API details: Legacy API internally uses vertex ID for root node abstraction * Cosmetics: Move some unit test helpers to common sub-directory * Extract constant from `accouns_cache.nim` => `constants.nim` * Fix tracer methods why: Logger dump data were wrongly dumped from the production database. This caused an assert exception when iterating over the persistent database (instead of the memory logger.) This event in turn was enabled after fixing another inconsistency which just set up an empty iterator. Unit tests failed to detect that. --- nimbus/constants.nim | 5 + nimbus/db/accounts_cache.nim | 9 +- nimbus/db/core_db/{ => backend}/legacy_db.nim | 288 ++++++++++----- .../core_db/{ => backend}/legacy_rocksdb.nim | 15 +- nimbus/db/core_db/base.nim | 345 +++++++++++------- nimbus/db/core_db/base/base_desc.nim | 177 ++++++--- nimbus/db/core_db/base/validate.nim | 68 ++-- nimbus/db/core_db/memory_only.nim | 26 +- nimbus/db/core_db/persistent.nim | 17 +- nimbus/db/state_db.nim | 2 +- nimbus/evm/interpreter_dispatch.nim | 2 +- nimbus/sync/handlers/snap.nim | 2 +- nimbus/sync/snap/worker/db/snapdb_desc.nim | 2 +- .../sync/snap/worker/db/snapdb_persistent.nim | 3 +- nimbus/tracer.nim | 2 +- tests/replay/xcheck.nim | 50 +++ tests/test_aristo/test_backend.nim | 1 + tests/test_aristo/test_filter.nim | 1 + tests/test_aristo/test_helpers.nim | 33 -- tests/test_aristo/test_misc.nim | 1 + tests/test_aristo/test_tx.nim | 1 + tests/test_coredb/test_helpers.nim | 33 -- tests/test_coredb/test_legacy.nim | 2 +- tests/test_rocksdb_timing.nim | 2 +- tests/test_rocksdb_timing/test_db_timing.nim | 2 +- tests/test_sync_snap.nim | 2 +- tests/test_sync_snap/test_syncdb.nim | 2 +- 27 files changed, 681 insertions(+), 412 deletions(-) rename nimbus/db/core_db/{ => backend}/legacy_db.nim (53%) rename nimbus/db/core_db/{ => backend}/legacy_rocksdb.nim (91%) create mode 100644 tests/replay/xcheck.nim diff --git a/nimbus/constants.nim b/nimbus/constants.nim index 33a5c85ae..62c2fdfb7 100644 --- a/nimbus/constants.nim +++ b/nimbus/constants.nim @@ -92,4 +92,9 @@ const # SystemAddress is where the system-transaction is sent from as per EIP-4788 SystemAddress* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe") + RIPEMD_ADDR* = block: + proc initAddress(x: int): EthAddress {.compileTime.} = + result[19] = x.byte + initAddress(3) + # End diff --git a/nimbus/db/accounts_cache.nim b/nimbus/db/accounts_cache.nim index e2e4458e3..653cb68b9 100644 --- a/nimbus/db/accounts_cache.nim +++ b/nimbus/db/accounts_cache.nim @@ -81,11 +81,6 @@ const NewlyCreated } - ripemdAddr* = block: - proc initAddress(x: int): EthAddress {.compileTime.} = - result[19] = x.byte - initAddress(3) - when debugAccountsCache: import stew/byteutils @@ -105,7 +100,7 @@ proc beginSavepoint*(ac: var AccountsCache): SavePoint {.gcsafe.} proc rawTrie*(ac: AccountsCache): AccountsTrie = ac.trie func db(ac: AccountsCache): CoreDbRef = ac.trie.db -func kvt(ac: AccountsCache): CoreDbKvtRef = ac.db.kvt +proc kvt(ac: AccountsCache): CoreDbKvtRef = ac.db.kvt # The AccountsCache is modeled after TrieDatabase for it's transaction style proc init*(x: typedesc[AccountsCache], db: CoreDbRef, @@ -560,7 +555,7 @@ proc clearEmptyAccounts(ac: AccountsCache) = # https://github.com/ethereum/EIPs/issues/716 if ac.ripemdSpecial: - ac.deleteEmptyAccount(ripemdAddr) + ac.deleteEmptyAccount(RIPEMD_ADDR) ac.ripemdSpecial = false proc persist*(ac: AccountsCache, diff --git a/nimbus/db/core_db/legacy_db.nim b/nimbus/db/core_db/backend/legacy_db.nim similarity index 53% rename from nimbus/db/core_db/legacy_db.nim rename to nimbus/db/core_db/backend/legacy_db.nim index 33d439b8d..d1fc78055 100644 --- a/nimbus/db/core_db/legacy_db.nim +++ b/nimbus/db/core_db/backend/legacy_db.nim @@ -14,24 +14,40 @@ import std/options, eth/[common, rlp, trie/db, trie/hexary], results, - ../../errors, - "."/[base, base/base_desc] + ../../../errors, + ".."/[base, base/base_desc] type LegacyApiRlpError* = object of CoreDbApiError ## For re-routing exceptions in iterator closure - LegacyDbRef* = ref object of CoreDbRef - tdb: TrieDatabaseRef # copy of descriptor reference captured with closures + # ----------- - HexaryTrieRef = ref object - trie: HexaryTrie # needed for descriptor capturing with closures + LegacyDbRef* = ref object of CoreDbRef + kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor + tdb: TrieDatabaseRef ## Copy of descriptor reference captured with closures + + LegacyDbClose* = proc() {.gcsafe, raises: [].} + ## Custom destructor + + HexaryChildDbRef = ref object + trie: HexaryTrie ## needed for descriptor capturing with closures RecorderRef = ref object of RootRef flags: set[CoreDbCaptFlags] parent: TrieDatabaseRef - recorder: TrieDatabaseRef - appDb: CoreDbRef + logger: LegacyDbRef + appDb: LegacyDbRef + + LegacyCoreDbVid* = ref object of CoreDbVidRef + vHash: Hash256 ## Hash key + + LegacyCoreDbError = ref object of CoreDbErrorRef + ctx: string ## Context where the exception or error occured + name: string ## name of exception + msg: string ## Exception info + + # ------------ LegacyCoreDbBE = ref object of CoreDbBackendRef base: LegacyDbRef @@ -42,15 +58,14 @@ type LegacyCoreDbMptBE = ref object of CoreDbMptBackendRef mpt: HexaryTrie - LegacyCoreDbError = ref object of CoreDbErrorRef - ctx: string ## Context where the exception or error occured - name: string ## name of exception - msg: string ## Exception info + LegacyCoreDbAccBE = ref object of CoreDbAccBackendRef + mpt: HexaryTrie proc init*( db: LegacyDbRef; dbType: CoreDbType; tdb: TrieDatabaseRef; + closeDb = LegacyDbClose(nil); ): CoreDbRef {.gcsafe.} @@ -62,11 +77,11 @@ template mapRlpException(db: LegacyDbRef; info: static[string]; code: untyped) = try: code except RlpError as e: - var w = LegacyCoreDbError( - ctx: info, - name: $e.name, - msg: e.msg) - return err(db.bless w) + return err(db.bless LegacyCoreDbError( + error: RlpException, + ctx: info, + name: $e.name, + msg: e.msg)) template reraiseRlpException(info: static[string]; code: untyped) = try: @@ -75,92 +90,91 @@ template reraiseRlpException(info: static[string]; code: untyped) = let msg = info & ", name=\"" & $e.name & "\", msg=\"" & e.msg & "\"" raise (ref LegacyApiRlpError)(msg: msg) +# ------------------------------------------------------------------------------ +# Private helpers, other functions +# ------------------------------------------------------------------------------ + +proc errorPrint(e: CoreDbErrorRef): string = + if not e.isNil: + let e = e.LegacyCoreDbError + result &= "ctx=\"" & $e.ctx & "\"" + if e.name != "": + result &= ", name=\"" & $e.name & "\"" + if e.msg != "": + result &= ", msg=\"" & $e.msg & "\"" + +func lvHash(vid: CoreDbVidRef): Hash256 = + if not vid.isNil and vid.ready: + return vid.LegacyCoreDbVid.vHash + EMPTY_ROOT_HASH + +proc toCoreDbAccount( + data: Blob; + db: LegacyDbRef; + ): CoreDbAccount + {.gcsafe, raises: [RlpError].} = + let acc = rlp.decode(data, Account) + CoreDbAccount( + nonce: acc.nonce, + balance: acc.balance, + codeHash: acc.codeHash, + storageVid: db.bless LegacyCoreDbVid(vHash: acc.storageRoot)) + +proc toAccount( + account: CoreDbAccount + ): Account = + ## Fast rewrite of `recast()` from base which reures to `vidHashFn()` + Account( + nonce: account.nonce, + balance: account.balance, + codeHash: account.codeHash, + storageRoot: account.storageVid.lvHash) + # ------------------------------------------------------------------------------ # Private mixin methods for `trieDB` (backport from capturedb/tracer sources) # ------------------------------------------------------------------------------ proc get(db: RecorderRef, key: openArray[byte]): Blob = ## Mixin for `trieDB()` - result = db.recorder.get(key) + result = db.logger.tdb.get(key) if result.len == 0: result = db.parent.get(key) if result.len != 0: - db.recorder.put(key, result) + db.logger.tdb.put(key, result) proc put(db: RecorderRef, key, value: openArray[byte]) = ## Mixin for `trieDB()` - db.recorder.put(key, value) + db.logger.tdb.put(key, value) if PersistPut in db.flags: db.parent.put(key, value) proc contains(db: RecorderRef, key: openArray[byte]): bool = ## Mixin for `trieDB()` result = db.parent.contains(key) - doAssert(db.recorder.contains(key) == result) + doAssert(db.logger.tdb.contains(key) == result) proc del(db: RecorderRef, key: openArray[byte]) = ## Mixin for `trieDB()` - db.recorder.del(key) + db.logger.tdb.del(key) if PersistDel in db.flags: db.parent.del(key) proc newRecorderRef( tdb: TrieDatabaseRef; + dbType: CoreDbType, flags: set[CoreDbCaptFlags]; ): RecorderRef = ## Capture constuctor, uses `mixin` values from above result = RecorderRef( flags: flags, parent: tdb, - recorder: newMemoryDB()) - result.appDb = LegacyDbRef().init(LegacyDbMemory, trieDB result) + logger: LegacyDbRef().init(LegacyDbMemory, newMemoryDB()).LegacyDbRef) + result.appDb = LegacyDbRef().init(dbType, trieDB result).LegacyDbRef # ------------------------------------------------------------------------------ # Private database method function tables # ------------------------------------------------------------------------------ -proc miscMethods(db: LegacyDbRef): CoreDbMiscFns = - CoreDbMiscFns( - backendFn: proc(): CoreDbBackendRef = - db.bless(LegacyCoreDbBE(base: db)), - - errorPrintFn: proc(e: CoreDbErrorRef): string = - if not e.isNil: - let e = e.LegacyCoreDbError - result &= "ctx=\"" & $e.ctx & "\"" & " , " - result &= "name=\"" & $e.name & "\"" & ", " - result &= "msg=\"" & $e.msg & "\"" - discard, - - legacySetupFn: proc() = - db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8])) - -proc kvtHandlers(db: LegacyDbRef): CoreDxKvtRef = - ## Key-value database table handlers - let tdb = db.tdb - CoreDxKvtRef( - methods: CoreDbKvtFns( - backendFn: proc(): CoreDbKvtBackendRef = - db.bless(LegacyCoreDbKvtBE(tdb: tdb)), - - getFn: proc(k: openArray[byte]): CoreDbRc[Blob] = - ok(tdb.get(k)), - - delFn: proc(k: openArray[byte]): CoreDbRc[void] = - tdb.del(k) - ok(), - - putFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = - tdb.put(k,v) - ok(), - - containsFn: proc(k: openArray[byte]): CoreDbRc[bool] = - ok(tdb.contains(k)), - - pairsIt: iterator(): (Blob, Blob) = - for k,v in tdb.pairsInMemoryDB: - yield (k,v))) - proc kvtMethods(db: LegacyDbRef): CoreDbKvtFns = ## Key-value database table handlers let tdb = db.tdb @@ -186,23 +200,23 @@ proc kvtMethods(db: LegacyDbRef): CoreDbKvtFns = for k,v in tdb.pairsInMemoryDB: yield (k,v)) -proc mptMethods(mpt: HexaryTrieRef; db: LegacyDbRef): CoreDbMptFns = +proc mptMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbMptFns = ## Hexary trie database handlers CoreDbMptFns( backendFn: proc(): CoreDbMptBackendRef = db.bless(LegacyCoreDbMptBE(mpt: mpt.trie)), - getFn: proc(k: openArray[byte]): CoreDbRc[Blob] = + fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] = db.mapRlpException("legacy/mpt/get()"): return ok(mpt.trie.get(k)) discard, - delFn: proc(k: openArray[byte]): CoreDbRc[void] = + deleteFn: proc(k: openArray[byte]): CoreDbRc[void] = db.mapRlpException("legacy/mpt/del()"): mpt.trie.del(k) ok(), - putFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = + mergeFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = db.mapRlpException("legacy/mpt/put()"): mpt.trie.put(k,v) ok(), @@ -212,24 +226,57 @@ proc mptMethods(mpt: HexaryTrieRef; db: LegacyDbRef): CoreDbMptFns = return ok(mpt.trie.contains(k)) discard, - rootHashFn: proc(): CoreDbRc[Hash256] = - ok(mpt.trie.rootHash), + rootVidFn: proc(): CoreDbVidRef = + db.bless(LegacyCoreDbVid(vHash: mpt.trie.rootHash)), isPruningFn: proc(): bool = mpt.trie.isPruning, - pairsIt: iterator(): (Blob, Blob) {.gcsafe, raises: [CoreDbApiError].} = + pairsIt: iterator: (Blob,Blob) {.gcsafe, raises: [LegacyApiRlpError].} = reraiseRlpException("legacy/mpt/pairs()"): for k,v in mpt.trie.pairs(): yield (k,v) discard, - replicateIt: iterator(): (Blob, Blob) {.gcsafe, raises: [CoreDbApiError].} = + replicateIt: iterator: (Blob,Blob) {.gcsafe, raises: [LegacyApiRlpError].} = reraiseRlpException("legacy/mpt/replicate()"): for k,v in mpt.trie.replicate(): yield (k,v) discard) +proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns = + ## Hexary trie database handlers + CoreDbAccFns( + backendFn: proc(): CoreDbAccBackendRef = + db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)), + + fetchFn: proc(k: EthAddress): CoreDbRc[CoreDbAccount] = + const info = "legacy/mpt/getAccount()" + db.mapRlpException info: + return ok mpt.trie.get(k.keccakHash.data).toCoreDbAccount(db) + return err(db.bless LegacyCoreDbError(error: MptNotFound, ctx: info)), + + deleteFn: proc(k: EthAddress): CoreDbRc[void] = + db.mapRlpException("legacy/mpt/del()"): + mpt.trie.del(k.keccakHash.data) + ok(), + + mergeFn: proc(k: EthAddress; v: CoreDbAccount): CoreDbRc[void] = + db.mapRlpException("legacy/mpt/put()"): + mpt.trie.put(k.keccakHash.data, rlp.encode v.toAccount) + ok(), + + containsFn: proc(k: EthAddress): CoreDbRc[bool] = + db.mapRlpException("legacy/mpt/put()"): + return ok(mpt.trie.contains k.keccakHash.data) + discard, + + rootVidFn: proc(): CoreDbVidRef = + db.bless(LegacyCoreDbVid(vHash: mpt.trie.rootHash)), + + isPruningFn: proc(): bool = + mpt.trie.isPruning) + proc txMethods(tx: DbTransaction): CoreDbTxFns = CoreDbTxFns( commitFn: proc(applyDeletes: bool): CoreDbRc[void] = @@ -259,37 +306,72 @@ proc cptMethods(cpt: RecorderRef): CoreDbCaptFns = recorderFn: proc(): CoreDbRc[CoreDbRef] = ok(cpt.appDb), + logDbFn: proc(): CoreDbRc[CoreDbRef] = + ok(cpt.logger), + getFlagsFn: proc(): set[CoreDbCaptFlags] = cpt.flags) # ------------------------------------------------------------------------------ -# Private constructor functions table +# Private base methods (including constructors) # ------------------------------------------------------------------------------ -proc constructors(db: LegacyDbRef): CoreDbConstructorFns = +proc baseMethods( + db: LegacyDbRef; + dbType: CoreDbType; + closeDb: LegacyDbClose; + ): CoreDbBaseFns = let tdb = db.tdb - CoreDbConstructorFns( - mptFn: proc(root: Hash256): CoreDbRc[CoreDxMptRef] = - let mpt = HexaryTrieRef(trie: initHexaryTrie(tdb, root, false)) - var dsc = CoreDxMptRef(methods: mpt.mptMethods(db)) - ok(db.bless dsc), + CoreDbBaseFns( + backendFn: proc(): CoreDbBackendRef = + db.bless(LegacyCoreDbBE(base: db)), - legacyMptFn: proc(root: Hash256; prune: bool): CoreDbRc[CoreDxMptRef] = - let mpt = HexaryTrieRef(trie: initHexaryTrie(tdb, root, prune)) - var dsc = CoreDxMptRef(methods: mpt.mptMethods(db)) - ok(db.bless dsc), + destroyFn: proc(ignore: bool) = + if not closeDb.isNil: + closeDb() + discard, + + vidHashFn: proc(vid: CoreDbVidRef): Result[Hash256,void] = + ok(vid.lvHash), + + errorPrintFn: proc(e: CoreDbErrorRef): string = + e.errorPrint(), + + legacySetupFn: proc() = + db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]), + + getRootFn: proc(root: Hash256; createOk: bool): CoreDbRc[CoreDbVidRef] = + if root == EMPTY_CODE_HASH: + return ok(db.bless LegacyCoreDbVid(vHash: EMPTY_CODE_HASH)) + + # Due to the way it is used for creating a ne root node, `createOk` must + # be checked before `contains()` is run. Otherwise it might bail out in + # the assertion of the above trace/recorder mixin `contains()` function. + if createOk or tdb.contains(root.data): + return ok(db.bless LegacyCoreDbVid(vHash: root)) + + err(db.bless LegacyCoreDbError(error: RootNotFound, ctx: "getRoot()")), + + newKvtFn: proc(): CoreDxKvtRef = + db.kvt, + + newMptFn: proc(root: CoreDbVidRef, prune: bool): CoreDbRc[CoreDxMptRef] = + let mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, root.lvHash, prune)) + ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)), + + newAccFn: proc(root: CoreDbVidRef, prune: bool): CoreDbRc[CoreDxAccRef] = + let mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, root.lvHash, prune)) + ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)), getIdFn: proc(): CoreDbRc[CoreDxTxID] = - var dsc = CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb)) - ok(db.bless dsc), + ok(db.bless CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb))), beginFn: proc(): CoreDbRc[CoreDxTxRef] = - var dsc = CoreDxTxRef(methods: tdb.beginTransaction.txMethods) - ok(db.bless dsc), + ok(db.bless CoreDxTxRef(methods: tdb.beginTransaction.txMethods)), - captureFn: proc(flags: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] = - var dsc = CoreDxCaptRef(methods: newRecorderRef(tdb, flags).cptMethods) - ok(db.bless dsc)) + captureFn: proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] = + let fns = newRecorderRef(tdb, dbtype, flgs).cptMethods + ok(db.bless CoreDxCaptRef(methods: fns))) # ------------------------------------------------------------------------------ # Public constructor helpers @@ -299,14 +381,18 @@ proc init*( db: LegacyDbRef; dbType: CoreDbType; tdb: TrieDatabaseRef; + closeDb = LegacyDbClose(nil); ): CoreDbRef = + ## Constructor helper + + # Local extensions db.tdb = tdb - db.init( - dbType = dbType, - dbMethods = db.miscMethods, - kvtMethods = db.kvtMethods, - newSubMod = db.constructors) - db + db.kvt = db.bless CoreDxKvtRef(methods: db.kvtMethods()) + + # Base descriptor + db.dbType = dbType + db.methods = db.baseMethods(dbType, closeDb) + db.bless # ------------------------------------------------------------------------------ # Public constructor and low level data retrieval, storage & transation frame @@ -336,7 +422,11 @@ func toLegacy*(be: CoreDbKvtBackendRef): TrieDatabaseRef = func toLegacy*(be: CoreDbMptBackendRef): HexaryTrie = if be.parent.isLegacy: return be.LegacyCoreDbMptBE.mpt - + +func toLegacy*(be: CoreDbAccBackendRef): HexaryTrie = + if be.parent.isLegacy: + return be.LegacyCoreDbAccBE.mpt + # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/nimbus/db/core_db/legacy_rocksdb.nim b/nimbus/db/core_db/backend/legacy_rocksdb.nim similarity index 91% rename from nimbus/db/core_db/legacy_rocksdb.nim rename to nimbus/db/core_db/backend/legacy_rocksdb.nim index d9cd81330..a30dcdec3 100644 --- a/nimbus/db/core_db/legacy_rocksdb.nim +++ b/nimbus/db/core_db/backend/legacy_rocksdb.nim @@ -12,13 +12,18 @@ import eth/trie/db, - ../select_backend, - "."/[base, legacy_db] + rocksdb, + "../.."/select_backend, + ../base, + ./legacy_db type LegaPersDbRef = ref object of LegacyDbRef rdb: RocksStoreRef # for backend access with legacy mode +# No other backend supported +doAssert nimbus_db_backend == "rocksdb" + # ------------------------------------------------------------------------------ # Public constructor and low level data retrieval, storage & transation frame # ------------------------------------------------------------------------------ @@ -41,7 +46,11 @@ proc newLegacyPersistentCoreDbRef*(path: string): CoreDbRef = except CatchableError as e: let msg = "DB initialisation error(" & $e.name & "): " & e.msg raise (ref ResultDefect)(msg: msg) - LegaPersDbRef(rdb: backend.rdb).init(LegacyDbPersistent, backend.trieDB) + + proc done() = + backend.rdb.store.close() + + LegaPersDbRef(rdb: backend.rdb).init(LegacyDbPersistent, backend.trieDB, done) # ------------------------------------------------------------------------------ # Public helper for direct backend access diff --git a/nimbus/db/core_db/base.nim b/nimbus/db/core_db/base.nim index cda474a76..ed90bb168 100644 --- a/nimbus/db/core_db/base.nim +++ b/nimbus/db/core_db/base.nim @@ -19,13 +19,19 @@ import ./base/[base_desc, validate] export + CoreDbAccount, + CoreDbApiError, CoreDbBackendRef, CoreDbCaptFlags, + CoreDbErrorCode, CoreDbErrorRef, + CoreDbAccBackendRef, CoreDbKvtBackendRef, CoreDbMptBackendRef, CoreDbRef, CoreDbType, + CoreDbVidRef, + CoreDxAccRef, CoreDxCaptRef, CoreDxKvtRef, CoreDxMptRef, @@ -52,7 +58,7 @@ const when ProvideCoreDbLegacyAPI: type TxWrapperApiError* = object of CoreDbApiError - ## For re-routing exceptions in iterator closure + ## For re-routing exception on tx/action template CoreDbKvtRef* = distinct CoreDxKvtRef ## Let methods defect on error CoreDbMptRef* = distinct CoreDxMptRef ## ... @@ -61,22 +67,27 @@ when ProvideCoreDbLegacyAPI: CoreDbTxID* = distinct CoreDxTxID CoreDbCaptRef* = distinct CoreDxCaptRef - CoreDbTrieRef* = CoreDbMptRef | CoreDbPhkRef + CoreDbTrieRefs* = CoreDbMptRef | CoreDbPhkRef ## Shortcut, *MPT* modules for (legacy API) - CoreDbChldRef* = CoreDbKvtRef | CoreDbTrieRef | CoreDbTxRef | CoreDbTxID | - CoreDbCaptRef - ## Shortcut, all modules with a `parent` (for legacy API) + CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbTxID | + CoreDbCaptRef + ## Shortcut, all modules with a `parent` entry (for legacy API) type - CoreDxTrieRef* = CoreDxMptRef | CoreDxPhkRef - ## Shortcut, *MPT* modules + CoreDxTrieRefs = CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef + ## Shortcut, *MPT* descriptors - CoreDxChldRef* = CoreDxKvtRef | CoreDxTrieRef | CoreDxTxRef | CoreDxTxID | - CoreDxCaptRef | - CoreDbErrorRef | - CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef - ## Shortcut, all modules with a `parent` + CoreDxTrieRelated = CoreDxTrieRefs | CoreDxTxRef | CoreDxTxID | CoreDxCaptRef + ## Shortcut, descriptors for sub-modules running on an *MPT* + + CoreDbBackends = CoreDbBackendRef | CoreDbKvtBackendRef | + CoreDbMptBackendRef | CoreDbAccBackendRef + ## Shortcut, all backend descriptors. + + CoreDxChldRefs = CoreDxKvtRef | CoreDxTrieRelated | CoreDbBackends | + CoreDbErrorRef + ## Shortcut, all descriptors with a `parent` entry. # ------------------------------------------------------------------------------ # Private functions: helpers @@ -96,17 +107,17 @@ func toCoreDxPhkRef(mpt: CoreDxMptRef): CoreDxPhkRef = fromMpt: mpt, methods: mpt.methods) - result.methods.getFn = + result.methods.fetchFn = proc(k: openArray[byte]): CoreDbRc[Blob] = - mpt.methods.getFn(k.keccakHash.data) + mpt.methods.fetchFn(k.keccakHash.data) - result.methods.delFn = + result.methods.deleteFn = proc(k: openArray[byte]): CoreDbRc[void] = - mpt.methods.delFn(k.keccakHash.data) + mpt.methods.deleteFn(k.keccakHash.data) - result.methods.putFn = - proc(k:openArray[byte]; v:openArray[byte]): CoreDbRc[void] = - mpt.methods.putFn(k.keccakHash.data, v) + result.methods.mergeFn = + proc(k:openArray[byte]; v: openArray[byte]): CoreDbRc[void] = + mpt.methods.mergeFn(k.keccakHash.data, v) result.methods.containsFn = proc(k: openArray[byte]): CoreDbRc[bool] = @@ -128,49 +139,47 @@ func parent(phk: CoreDxPhkRef): CoreDbRef = phk.fromMpt.parent # ------------------------------------------------------------------------------ -# Public constructor +# Public constructor helper # ------------------------------------------------------------------------------ -template bless*(db: CoreDbRef; child: untyped): auto = - ## Complete sub-module descriptor, fill in `parent` +proc bless*(db: CoreDbRef): CoreDbRef = + ## Verify descriptor + when AutoValidateDescriptors: + db.validate + db + +proc bless*(db: CoreDbRef; child: CoreDbVidRef): CoreDbVidRef = + ## Complete sub-module descriptor, fill in `parent` and actvate it. child.parent = db + child.ready = true when AutoValidateDescriptors: child.validate child -proc init*( - db: CoreDbRef; # Main descriptor, locally extended - dbType: CoreDbType; # Backend symbol - dbMethods: CoreDbMiscFns; # General methods - kvtMethods: CoreDbKvtFns; # Kvt related methods - newSubMod: CoreDbConstructorFns; # Sub-module constructors - ) = - ## Base descriptor initaliser - db.dbType = dbType - db.methods = dbMethods - db.new = newSubMod - - db.kvtRef = CoreDxKvtRef( - parent: db, - methods: kvtMethods) +proc bless*(db: CoreDbRef; child: CoreDxKvtRef): CoreDxKvtRef = + ## Complete sub-module descriptor, fill in `parent` and de-actvate + ## iterator for persistent database. + child.parent = db # Disable interator for non-memory instances - if dbType in CoreDbPersistentTypes: - db.kvtRef.methods.pairsIt = iterator(): (Blob, Blob) = + if db.dbType in CoreDbPersistentTypes: + child.methods.pairsIt = iterator(): (Blob, Blob) = db.itNotImplemented "pairs/kvt" when AutoValidateDescriptors: - db.validate + child.validate + child -proc newCoreDbCaptRef*(db: CoreDbRef; methods: CoreDbCaptFns): CoreDxCaptRef = - ## Capture constructor helper. - result = CoreDxCaptRef( - parent: db, - methods: methods) - +proc bless*[T: CoreDxTrieRelated | CoreDbErrorRef | CoreDbBackends]( + db: CoreDbRef; + child: T; + ): auto = + ## Complete sub-module descriptor, fill in `parent`. + child.parent = db when AutoValidateDescriptors: - db.validate + child.validate + child # ------------------------------------------------------------------------------ # Public main descriptor methods @@ -180,32 +189,87 @@ proc dbType*(db: CoreDbRef): CoreDbType = ## Getter db.dbType -# On the persistent legacy hexary trie, this function is needed for -# bootstrapping and Genesis setup when the `purge` flag is activated. proc compensateLegacySetup*(db: CoreDbRef) = + ## On the persistent legacy hexary trie, this function is needed for + ## bootstrapping and Genesis setup when the `purge` flag is activated. + ## Otherwise the database backend may defect on an internal inconsistency. db.methods.legacySetupFn() -func parent*(cld: CoreDxChldRef): CoreDbRef = +func parent*(cld: CoreDxChldRefs): CoreDbRef = ## Getter, common method for all sub-modules cld.parent -proc backend*(db: CoreDbRef): CoreDbBackendRef = - ## Getter, retrieves the *raw* backend object for special support. - result = db.methods.backendFn() - result.parent = db +proc backend*(dsc: CoreDxKvtRef | CoreDxTrieRelated | CoreDbRef): auto = + ## Getter, retrieves the *raw* backend object for special/localised support. + dsc.methods.backendFn() + +proc finish*(db: CoreDbRef; flush = false) = + ## Database destructor. If the argument `flush` is set `false`, the database + ## is left as-is and only the in-memory handlers are cleaned up. + ## + ## Otherwise the destructor is allowed to remove the database. This feature + ## depends on the backend database. Currently, only the `AristoDbRocks` type + ## backend removes the database on `true`. + db.methods.destroyFn flush proc `$$`*(e: CoreDbErrorRef): string = ## Pretty print error symbol, note that this directive may have side effects ## as it calls a backend function. e.parent.methods.errorPrintFn(e) +proc hash*(vid: CoreDbVidRef): Result[Hash256,void] = + ## Getter (well, sort of), retrieves the hash for a `vid` argument. The + ## function might fail if there is currently no hash available (e.g. on + ## `Aristo`.) Note that this is different from succeeding with an + ## `EMPTY_ROOT_HASH` value. + ## + ## The value `EMPTY_ROOT_HASH` is also returned on an empty `vid` argument + ## `CoreDbVidRef(nil)`, say. + ## + if not vid.isNil and vid.ready: + return vid.parent.methods.vidHashFn vid + ok EMPTY_ROOT_HASH + +proc recast*(account: CoreDbAccount): Result[Account,void] = + ## Convert the argument `account` to the portable Ethereum representation + ## of an account. This conversion may fail if the storage root hash (see + ## `hash()` above) is currently unavailable. + ## + ## Note that for the legacy backend, this function always succeeds. + ## + ok Account( + nonce: account.nonce, + balance: account.balance, + codeHash: account.codeHash, + storageRoot: ? account.storageVid.hash) + +proc getRoot*( + db: CoreDbRef; + root: Hash256; + createOk = false; + ): CoreDbRc[CoreDbVidRef] = + ## Find root node with argument hash `root` in database and return the + ## corresponding `CoreDbVidRef` object. If the `root` arguent is set + ## `EMPTY_CODE_HASH`, this function always succeeds, otherwise it fails + ## unless a root node with the corresponding hash exists. + ## + ## This function is intended to open a virtual accounts trie database as in: + ## :: + ## proc openAccountLedger(db: CoreDbRef, rootHash: Hash256): CoreDxMptRef = + ## let root = db.getRoot(rootHash).isOkOr: + ## # some error handling + ## return + ## db.newAccMpt root + ## + db.methods.getRootFn(root, createOk) + # ------------------------------------------------------------------------------ # Public key-value table methods # ------------------------------------------------------------------------------ -func toKvt*(db: CoreDbRef): CoreDxKvtRef = +proc newKvt*(db: CoreDbRef): CoreDxKvtRef = ## Getter (pseudo constructor) - db.kvtRef + db.methods.newKvtFn() proc get*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] = kvt.methods.getFn key @@ -228,74 +292,67 @@ iterator pairs*(kvt: CoreDxKvtRef): (Blob, Blob) {.apiRaise.} = for k,v in kvt.methods.pairsIt(): yield (k,v) -proc backend*(kvt: CoreDxKvtRef): CoreDbKvtBackendRef = - ## Getter, retrieves the *raw* backend object for special support. - result = kvt.methods.backendFn() - result.parent = kvt.parent - # ------------------------------------------------------------------------------ # Public Merkle Patricia Tree, hexary trie constructors # ------------------------------------------------------------------------------ -proc newMpt*(db: CoreDbRef; root=EMPTY_ROOT_HASH): CoreDbRc[CoreDxMptRef] = - ## Constructor - db.new.mptFn root +proc newMpt*(db: CoreDbRef; root: CoreDbVidRef; prune = true): CoreDxMptRef = + ## Constructor, will defect on failure (note that the legacy backend + ## always succeeds) + db.methods.newMptFn(root, prune).valueOr: raiseAssert $$error + +proc newAccMpt*(db: CoreDbRef; root: CoreDbVidRef; prune = true): CoreDxAccRef = + ## Similar to `newMpt()` for handling accounts. Although this sub-trie can + ## be emulated by means of `newMpt(..).toPhk()`, it is recommended using + ## this constructor which implies its own subset of methods to handle that + ## trie. + db.methods.newAccFn(root, prune).valueOr: raiseAssert $$error proc toMpt*(phk: CoreDxPhkRef): CoreDxMptRef = ## Replaces the pre-hashed argument trie `phk` by the non pre-hashed *MPT*. + ## Note that this does not apply to an accounts trie that was created by + ## `newAccMpt()`. phk.fromMpt proc toPhk*(mpt: CoreDxMptRef): CoreDxPhkRef = ## Replaces argument `mpt` by a pre-hashed *MPT*. + ## Note that this does not apply to an accounts trie that was created by + ## `newAaccMpt()`. mpt.toCoreDxPhkRef # ------------------------------------------------------------------------------ -# Public hexary trie legacy constructors +# Public common methods for all hexary trie databases (`mpt`, `phk`, or `acc`) # ------------------------------------------------------------------------------ -proc newMptPrune*( - db: CoreDbRef; - root = EMPTY_ROOT_HASH; - prune = true; - ): CoreDbRc[CoreDxMptRef] = - ## Constructor, `HexaryTrie` compliant - db.new.legacyMptFn(root, prune) - -proc newPhkPrune*( - db: CoreDbRef; - root = EMPTY_ROOT_HASH; - prune = true; - ): CoreDbRc[CoreDxPhkRef] = - ## Constructor, `SecureHexaryTrie` compliant - ok (? db.new.legacyMptFn(root, prune)).toCoreDxPhkRef - -# ------------------------------------------------------------------------------ -# Public hexary trie database methods (`mpt` or `phk`) -# ------------------------------------------------------------------------------ - -proc isPruning*(trie: CoreDxTrieRef): bool = +proc isPruning*(dsc: CoreDxTrieRefs | CoreDxAccRef): bool = ## Getter - trie.methods.isPruningFn() + dsc.methods.isPruningFn() -proc get*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[Blob] = - trie.methods.getFn(key) +proc rootVid*(dsc: CoreDxTrieRefs | CoreDxAccRef): CoreDbVidRef = + ## Getter, result is not `nil` + dsc.methods.rootVidFn() -proc del*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[void] = - trie.methods.delFn key +# ------------------------------------------------------------------------------ +# Public generic hexary trie database methods (`mpt` or `phk`) +# ------------------------------------------------------------------------------ -proc put*( - trie: CoreDxTrieRef; +proc fetch*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[Blob] = + ## Fetch data from the argument `trie` + trie.methods.fetchFn(key) + +proc delete*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[void] = + trie.methods.deleteFn key + +proc merge*( + trie: CoreDxTrieRefs; key: openArray[byte]; value: openArray[byte]; ): CoreDbRc[void] = - trie.methods.putFn(key, value) + trie.methods.mergeFn(key, value) -proc contains*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[bool] = +proc contains*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[bool] = trie.methods.containsFn key -proc rootHash*(trie: CoreDxTrieRef): CoreDbRc[Hash256] = - trie.methods.rootHashFn() - iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = ## Trie traversal, only supported for `CoreDxMptRef` for k,v in mpt.methods.pairsIt(): @@ -306,10 +363,26 @@ iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = for k,v in mpt.methods.replicateIt(): yield (k,v) -proc backend*(trie: CoreDxTrieRef): CoreDbMptBackendRef = - ## Getter, retrieves the *raw* backend object for special support. - result = trie.methods.backendFn() - result.parent = trie.parent +# ------------------------------------------------------------------------------ +# Public trie database methods for accounts +# ------------------------------------------------------------------------------ + +proc fetch*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[CoreDbAccount] = + ## Fetch data from the argument `trie` + acc.methods.fetchFn address + +proc delete*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[void] = + acc.methods.deleteFn address + +proc merge*( + acc: CoreDxAccRef; + address: EthAddress; + account: CoreDbAccount; + ): CoreDbRc[void] = + acc.methods.mergeFn(address, account) + +proc contains*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[bool] = + acc.methods.containsFn address # ------------------------------------------------------------------------------ # Public transaction related methods @@ -317,7 +390,7 @@ proc backend*(trie: CoreDxTrieRef): CoreDbMptBackendRef = proc toTransactionID*(db: CoreDbRef): CoreDbRc[CoreDxTxID] = ## Getter, current transaction state - db.new.getIdFn() + db.methods.getIdFn() proc shortTimeReadOnly*( id: CoreDxTxID; @@ -329,7 +402,7 @@ proc shortTimeReadOnly*( proc newTransaction*(db: CoreDbRef): CoreDbRc[CoreDxTxRef] = ## Constructor - db.new.beginFn() + db.methods.beginFn() proc commit*(tx: CoreDxTxRef, applyDeletes = true): CoreDbRc[void] = tx.methods.commitFn applyDeletes @@ -352,12 +425,15 @@ proc newCapture*( flags: set[CoreDbCaptFlags] = {}; ): CoreDbRc[CoreDxCaptRef] = ## Constructor - db.new.captureFn flags + db.methods.captureFn flags proc recorder*(db: CoreDxCaptRef): CoreDbRc[CoreDbRef] = ## Getter db.methods.recorderFn() +proc logDb*(db: CoreDxCaptRef): CoreDbRc[CoreDbRef] = + db.methods.logDbFn() + proc flags*(db: CoreDxCaptRef): set[CoreDbCaptFlags] = ## Getter db.methods.getFlagsFn() @@ -368,15 +444,18 @@ proc flags*(db: CoreDxCaptRef): set[CoreDbCaptFlags] = when ProvideCoreDbLegacyAPI: - func parent*(cld: CoreDbChldRef): CoreDbRef = + func parent*(cld: CoreDbChldRefs): CoreDbRef = ## Getter, common method for all sub-modules cld.distinctBase.parent() + proc backend*(dsc: CoreDbChldRefs): auto = + dsc.distinctBase.backend + # ---------------- - func kvt*(db: CoreDbRef): CoreDbKvtRef = + proc kvt*(db: CoreDbRef): CoreDbKvtRef = ## Legacy pseudo constructor, see `toKvt()` for production constructor - db.toKvt.CoreDbKvtRef + db.newKvt().CoreDbKvtRef proc get*(kvt: CoreDbKvtRef; key: openArray[byte]): Blob = kvt.distinctBase.get(key).expect "kvt/get()" @@ -394,22 +473,17 @@ when ProvideCoreDbLegacyAPI: for k,v in kvt.distinctBase.pairs(): yield (k,v) - proc backend*(kvt: CoreDbKvtRef): CoreDbKvtBackendRef = - kvt.distinctBase.backend - # ---------------- proc toMpt*(phk: CoreDbPhkRef): CoreDbMptRef = phk.distinctBase.toMpt.CoreDbMptRef - proc mpt*(db: CoreDbRef; root=EMPTY_ROOT_HASH): CoreDbMptRef = - db.newMpt(root).expect("db/mpt()").CoreDbMptRef - proc mptPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbMptRef = - db.newMptPrune(root, prune).expect("db/mptPrune()").CoreDbMptRef + let vid = db.getRoot(root, createOk=true).expect "mpt/getRoot()" + db.newMpt(vid, prune).CoreDbMptRef proc mptPrune*(db: CoreDbRef; prune = true): CoreDbMptRef = - db.newMptPrune(EMPTY_ROOT_HASH, prune).expect("db/mptPrune()").CoreDbMptRef + db.newMpt(CoreDbVidRef(nil), prune).CoreDbMptRef # ---------------- @@ -417,48 +491,42 @@ when ProvideCoreDbLegacyAPI: mpt.distinctBase.toPhk.CoreDbPhkRef proc phkPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbPhkRef = - db.newPhkPrune(root, prune).expect("db/phkPrune()").CoreDbPhkRef + let vid = db.getRoot(root, createOk=true).expect "phk/getRoot()" + db.newMpt(vid, prune).toCoreDxPhkRef.CoreDbPhkRef proc phkPrune*(db: CoreDbRef; prune = true): CoreDbPhkRef = - db.newPhkPrune(EMPTY_ROOT_HASH, prune).expect("db/phkPrune()").CoreDbPhkRef + db.newMpt(CoreDbVidRef(nil), prune).toCoreDxPhkRef.CoreDbPhkRef # ---------------- - proc isPruning*(trie: CoreDbTrieRef): bool = + proc isPruning*(trie: CoreDbTrieRefs): bool = trie.distinctBase.isPruning() - proc get*(trie: CoreDbTrieRef; key: openArray[byte]): Blob = - trie.distinctBase.get(key).expect "trie/get()" + proc get*(trie: CoreDbTrieRefs; key: openArray[byte]): Blob = + trie.distinctBase.fetch(key).expect "trie/get()" - proc del*(trie: CoreDbTrieRef; key: openArray[byte]) = - trie.distinctBase.del(key).expect "trie/del()" + proc del*(trie: CoreDbTrieRefs; key: openArray[byte]) = + trie.distinctBase.delete(key).expect "trie/del()" - proc put*( - trie: CoreDbTrieRef; - key: openArray[byte]; - value: openArray[byte]; - ) = - trie.distinctBase.put(key, value).expect "trie/put()" + proc put*(trie: CoreDbTrieRefs; key: openArray[byte]; val: openArray[byte]) = + trie.distinctBase.merge(key, val).expect "trie/put()" - proc contains*(trie: CoreDbTrieRef; key: openArray[byte]): bool = + proc contains*(trie: CoreDbTrieRefs; key: openArray[byte]): bool = trie.distinctBase.contains(key).expect "trie/contains()" - proc rootHash*(trie: CoreDbTrieRef): Hash256 = - trie.distinctBase.rootHash().expect "trie/rootHash()" + proc rootHash*(trie: CoreDbTrieRefs): Hash256 = + trie.distinctBase.rootVid().hash().expect "trie/rootHash()" iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} = - ## Trie traversal, only supported for `CoreDbMptRef` + ## Trie traversal, not supported for `CoreDbPhkRef` for k,v in mpt.distinctBase.pairs(): yield (k,v) iterator replicate*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} = - ## Low level trie dump, only supported for `CoreDbMptRef` + ## Low level trie dump, not supported for `CoreDbPhkRef` for k,v in mpt.distinctBase.replicate(): yield (k,v) - proc backend*(trie: CoreDbTrieRef): CoreDbMptBackendRef = - trie.distinctBase.backend - # ---------------- proc getTransactionID*(db: CoreDbRef): CoreDbTxID = @@ -512,6 +580,9 @@ when ProvideCoreDbLegacyAPI: proc recorder*(db: CoreDbCaptRef): CoreDbRef = db.distinctBase.recorder().expect("db/recorder()") + proc logDb*(db: CoreDbCaptRef): CoreDbRef = + db.distinctBase.logDb().expect("db/logDb()") + proc flags*(db: CoreDbCaptRef): set[CoreDbCaptFlags] = db.distinctBase.flags() diff --git a/nimbus/db/core_db/base/base_desc.nim b/nimbus/db/core_db/base/base_desc.nim index 6df126656..14b0d5b80 100644 --- a/nimbus/db/core_db/base/base_desc.nim +++ b/nimbus/db/core_db/base/base_desc.nim @@ -24,57 +24,76 @@ type Ooops LegacyDbMemory LegacyDbPersistent - # AristoDbMemory - # AristoDbPersistent + AristoDbMemory ## Memory backend emulator + AristoDbRocks ## RocksDB backend + AristoDbVoid ## No backend (to be prefered over `XxxDbMemory`) const - CoreDbPersistentTypes* = {LegacyDbPersistent} + CoreDbPersistentTypes* = {LegacyDbPersistent, AristoDbRocks} type CoreDbRc*[T] = Result[T,CoreDbErrorRef] + CoreDbAccount* = object + ## Generic account representation referencing an *MPT* sub-trie + nonce*: AccountNonce ## Some `uint64` type + balance*: UInt256 + storageVid*: CoreDbVidRef ## Implies storage root sub-MPT + codeHash*: Hash256 + + CoreDbErrorCode* = enum + Unspecified = 0 + RlpException + KvtNotFound + MptNotFound + RootNotFound + CoreDbCaptFlags* {.pure.} = enum PersistPut PersistDel - # -------------------------------------------------- - # Constructors - # -------------------------------------------------- - CoreDbNewMptFn* = - proc(root: Hash256): CoreDbRc[CoreDxMptRef] {.noRaise.} - CoreDbNewLegaMptFn* = - proc(root: Hash256; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.} - CoreDbNewTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.} - CoreDbNewTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.} - CoreDbNewCaptFn* = - proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.} - - CoreDbConstructorFns* = object - ## Constructors - - # Hexary trie - mptFn*: CoreDbNewMptFn - legacyMptFn*: CoreDbNewLegaMptFn # Legacy handler, should go away - - # Transactions - getIdFn*: CoreDbNewTxGetIdFn - beginFn*: CoreDbNewTxBeginFn - - # capture/tracer - captureFn*: CoreDbNewCaptFn - - # -------------------------------------------------- # Sub-descriptor: Misc methods for main descriptor # -------------------------------------------------- - CoreDbBackendFn* = proc(): CoreDbBackendRef {.noRaise.} - CoreDbErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.} - CoreDbInitLegaSetupFn* = proc() {.noRaise.} + CoreDbBaseBackendFn* = proc(): CoreDbBackendRef {.noRaise.} + CoreDbBaseDestroyFn* = proc(flush = true) {.noRaise.} + CoreDbBaseVidHashFn* = + proc(vid: CoreDbVidRef): Result[Hash256,void] {.noRaise.} + CoreDbBaseErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.} + CoreDbBaseInitLegaSetupFn* = proc() {.noRaise.} + CoreDbBaseRootFn* = + proc(root: Hash256; createOk: bool): CoreDbRc[CoreDbVidRef] {.noRaise.} + CoreDbBaseKvtFn* = proc(): CoreDxKvtRef {.noRaise.} + CoreDbBaseMptFn* = + proc(root: CoreDbVidRef; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.} + CoreDbBaseAccFn* = + proc(root: CoreDbVidRef; prune: bool): CoreDbRc[CoreDxAccRef] {.noRaise.} + CoreDbBaseTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.} + CoreDbBaseTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.} + CoreDbBaseCaptFn* = + proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.} - CoreDbMiscFns* = object - backendFn*: CoreDbBackendFn - errorPrintFn*: CoreDbErrorPrintFn - legacySetupFn*: CoreDbInitLegaSetupFn + CoreDbBaseFns* = object + backendFn*: CoreDbBaseBackendFn + destroyFn*: CoreDbBaseDestroyFn + vidHashFn*: CoreDbBaseVidHashFn + errorPrintFn*: CoreDbBaseErrorPrintFn + legacySetupFn*: CoreDbBaseInitLegaSetupFn + getRootFn*: CoreDbBaseRootFn + + # Kvt constructor + newKvtFn*: CoreDbBaseKvtFn + + # Hexary trie constructors + newMptFn*: CoreDbBaseMptFn + newAccFn*: CoreDbBaseAccFn + + # Transactions constructors + getIdFn*: CoreDbBaseTxGetIdFn + beginFn*: CoreDbBaseTxBeginFn + + # capture/tracer constructors + captureFn*: CoreDbBaseCaptFn # -------------------------------------------------- @@ -99,32 +118,59 @@ type # -------------------------------------------------- - # Sub-descriptor: Mpt/hexary trie methods + # Sub-descriptor: generic Mpt/hexary trie methods # -------------------------------------------------- CoreDbMptBackendFn* = proc(): CoreDbMptBackendRef {.noRaise.} - CoreDbMptGetFn* = + CoreDbMptFetchFn* = proc(k: openArray[byte]): CoreDbRc[Blob] {.noRaise.} - CoreDbMptDelFn* = + CoreDbMptFetchAccountFn* = + proc(k: openArray[byte]): CoreDbRc[CoreDbAccount] {.noRaise.} + CoreDbMptDeleteFn* = proc(k: openArray[byte]): CoreDbRc[void] {.noRaise.} - CoreDbMptPutFn* = - proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void ] {.noRaise.} + CoreDbMptMergeFn* = + proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] {.noRaise.} + CoreDbMptMergeAccountFn* = + proc(k: openArray[byte]; v: CoreDbAccount): CoreDbRc[void] {.noRaise.} CoreDbMptContainsFn* = proc(k: openArray[byte]): CoreDbRc[bool] {.noRaise.} - CoreDbMptRootHashFn* = proc(): CoreDbRc[Hash256] {.noRaise.} + CoreDbMptRootVidFn* = proc(): CoreDbVidRef {.noRaise.} CoreDbMptIsPruningFn* = proc(): bool {.noRaise.} CoreDbMptPairsIt* = iterator(): (Blob,Blob) {.apiRaise.} CoreDbMptReplicateIt* = iterator(): (Blob,Blob) {.apiRaise.} CoreDbMptFns* = object ## Methods for trie objects - backendFn*: CoreDbMptBackendFn - getFn*: CoreDbMptGetFn - delFn*: CoreDbMptDelFn - putFn*: CoreDbMptPutFn - containsFn*: CoreDbMptContainsFn - rootHashFn*: CoreDbMptRootHashFn - pairsIt*: CoreDbMptPairsIt - replicateIt*: CoreDbMptReplicateIt - isPruningFn*: CoreDbMptIsPruningFn # Legacy handler, should go away + backendFn*: CoreDbMptBackendFn + fetchFn*: CoreDbMptFetchFn + deleteFn*: CoreDbMptDeleteFn + mergeFn*: CoreDbMptMergeFn + containsFn*: CoreDbMptContainsFn + rootVidFn*: CoreDbMptRootVidFn + pairsIt*: CoreDbMptPairsIt + replicateIt*: CoreDbMptReplicateIt + isPruningFn*: CoreDbMptIsPruningFn + + + # ---------------------------------------------------- + # Sub-descriptor: Mpt/hexary trie methods for accounts + # ------------------------------------------------------ + CoreDbAccBackendFn* = proc(): CoreDbAccBackendRef {.noRaise.} + CoreDbAccFetchFn* = proc(k: EthAddress): CoreDbRc[CoreDbAccount] {.noRaise.} + CoreDbAccDeleteFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.} + CoreDbAccMergeFn* = + proc(k: EthAddress; v: CoreDbAccount): CoreDbRc[void] {.noRaise.} + CoreDbAccContainsFn* = proc(k: EthAddress): CoreDbRc[bool] {.noRaise.} + CoreDbAccRootVidFn* = proc(): CoreDbVidRef {.noRaise.} + CoreDbAccIsPruningFn* = proc(): bool {.noRaise.} + + CoreDbAccFns* = object + ## Methods for trie objects + backendFn*: CoreDbAccBackendFn + fetchFn*: CoreDbAccFetchFn + deleteFn*: CoreDbAccDeleteFn + mergeFn*: CoreDbAccMergeFn + containsFn*: CoreDbAccContainsFn + rootVidFn*: CoreDbAccRootVidFn + isPruningFn*: CoreDbAccIsPruningFn # -------------------------------------------------- @@ -156,10 +202,12 @@ type # Sub-descriptor: capture recorder methods # -------------------------------------------------- CoreDbCaptRecorderFn* = proc(): CoreDbRc[CoreDbRef] {.noRaise.} + CoreDbCaptLogDbFn* = proc(): CoreDbRc[CoreDbRef] {.noRaise.} CoreDbCaptFlagsFn* = proc(): set[CoreDbCaptFlags] {.noRaise.} CoreDbCaptFns* = object recorderFn*: CoreDbCaptRecorderFn + logDbFn*: CoreDbCaptLogDbFn getFlagsFn*: CoreDbCaptFlagsFn # -------------------------------------------------- @@ -168,12 +216,11 @@ type CoreDbRef* = ref object of RootRef ## Database descriptor dbType*: CoreDbType - kvtRef*: CoreDxKvtRef - new*: CoreDbConstructorFns - methods*: CoreDbMiscFns + methods*: CoreDbBaseFns CoreDbErrorRef* = ref object of RootRef ## Generic error object + error*: CoreDbErrorCode parent*: CoreDbRef CoreDbBackendRef* = ref object of RootRef @@ -188,6 +235,10 @@ type ## Backend wrapper for direct backend access parent*: CoreDbRef + CoreDbAccBackendRef* = ref object of RootRef + ## Backend wrapper for direct backend access + parent*: CoreDbRef + CoreDxKvtRef* = ref object ## Statically initialised Key-Value pair table living in `CoreDbRef` parent*: CoreDbRef @@ -199,10 +250,22 @@ type parent*: CoreDbRef methods*: CoreDbMptFns + CoreDxAccRef* = ref object + ## Similar to `CoreDxKvtRef`, only dealing with `CoreDbAccount` data + ## rather than `Blob` values. + parent*: CoreDbRef + methods*: CoreDbAccFns + + CoreDbVidRef* = ref object of RootRef + ## Generic state root: `Hash256` for legacy, `VertexID` for Aristo. This + ## object makes only sense in the context od an *MPT*. + parent*: CoreDbRef + ready*: bool ## Must be set `true` to enable + CoreDxPhkRef* = ref object ## Similar to `CoreDbMptRef` but with pre-hashed keys. That is, any - ## argument key for `put()`, `get()` etc. will be hashed first before - ## being applied. + ## argument key for `merge()`, `fetch()` etc. will be hashed first + ## before being applied. fromMpt*: CoreDxMptRef methods*: CoreDbMptFns diff --git a/nimbus/db/core_db/base/validate.nim b/nimbus/db/core_db/base/validate.nim index 17c3f35d9..7e8d5f40a 100644 --- a/nimbus/db/core_db/base/validate.nim +++ b/nimbus/db/core_db/base/validate.nim @@ -14,22 +14,34 @@ import type EphemMethodsDesc = - CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef + CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef | + CoreDbAccBackendRef | CoreDbVidRef MethodsDesc = - CoreDxKvtRef | - CoreDxMptRef | CoreDxPhkRef | - CoreDxTxRef | CoreDxTxID | + CoreDxKvtRef | + CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef | + CoreDxTxRef | CoreDxTxID | CoreDxCaptRef + ValidateDesc* = MethodsDesc | EphemMethodsDesc | CoreDbErrorRef + # ------------------------------------------------------------------------------ # Private helpers # ------------------------------------------------------------------------------ -proc validateMethodsDesc(msc: CoreDbMiscFns) = - doAssert not msc.backendFn.isNil - doAssert not msc.errorPrintFn.isNil - doAssert not msc.legacySetupFn.isNil +proc validateMethodsDesc(base: CoreDbBaseFns) = + doAssert not base.backendFn.isNil + doAssert not base.destroyFn.isNil + doAssert not base.vidHashFn.isNil + doAssert not base.errorPrintFn.isNil + doAssert not base.legacySetupFn.isNil + doAssert not base.getRootFn.isNil + doAssert not base.newKvtFn.isNil + doAssert not base.newMptFn.isNil + doAssert not base.newAccFn.isNil + doAssert not base.getIdFn.isNil + doAssert not base.beginFn.isNil + doAssert not base.captureFn.isNil proc validateMethodsDesc(kvt: CoreDbKvtFns) = doAssert not kvt.backendFn.isNil @@ -41,24 +53,31 @@ proc validateMethodsDesc(kvt: CoreDbKvtFns) = proc validateMethodsDesc(fns: CoreDbMptFns) = doAssert not fns.backendFn.isNil - doAssert not fns.getFn.isNil - doAssert not fns.delFn.isNil - doAssert not fns.putFn.isNil + doAssert not fns.fetchFn.isNil + doAssert not fns.deleteFn.isNil + doAssert not fns.mergeFn.isNil doAssert not fns.containsFn.isNil - doAssert not fns.rootHashFn.isNil + doAssert not fns.rootVidFn.isNil doAssert not fns.isPruningFn.isNil doAssert not fns.pairsIt.isNil doAssert not fns.replicateIt.isNil -proc validateConstructors(new: CoreDbConstructorFns) = - doAssert not new.mptFn.isNil - doAssert not new.legacyMptFn.isNil - doAssert not new.getIdFn.isNil - doAssert not new.beginFn.isNil - doAssert not new.captureFn.isNil +proc validateMethodsDesc(fns: CoreDbAccFns) = + doAssert not fns.backendFn.isNil + doAssert not fns.fetchFn.isNil + doAssert not fns.deleteFn.isNil + doAssert not fns.mergeFn.isNil + doAssert not fns.containsFn.isNil + doAssert not fns.rootVidFn.isNil + doAssert not fns.isPruningFn.isNil # ------------ +proc validateMethodsDesc(vid: CoreDbVidRef) = + doAssert not vid.isNil + doAssert not vid.parent.isNil + doAssert vid.ready == true + proc validateMethodsDesc(e: CoreDbErrorRef) = doAssert not e.isNil doAssert not e.parent.isNil @@ -66,7 +85,7 @@ proc validateMethodsDesc(e: CoreDbErrorRef) = proc validateMethodsDesc(eph: EphemMethodsDesc) = doAssert not eph.isNil doAssert not eph.parent.isNil - + proc validateMethodsDesc(kvt: CoreDxKvtRef) = doAssert not kvt.isNil doAssert not kvt.parent.isNil @@ -77,6 +96,11 @@ proc validateMethodsDesc(mpt: CoreDxMptRef) = doAssert not mpt.parent.isNil mpt.methods.validateMethodsDesc +proc validateMethodsDesc(acc: CoreDxAccRef) = + doAssert not acc.isNil + doAssert not acc.parent.isNil + acc.methods.validateMethodsDesc + proc validateMethodsDesc(phk: CoreDxPhkRef) = doAssert not phk.isNil doAssert not phk.fromMpt.isNil @@ -104,16 +128,14 @@ proc validateMethodsDesc(id: CoreDxTxID) = proc validateMethodsDesc(db: CoreDbRef) = doAssert not db.isNil doAssert db.dbType != CoreDbType(0) - db.kvtRef.validateMethodsDesc - db.new.validateConstructors db.methods.validateMethodsDesc # ------------------------------------------------------------------------------ # Public debugging helpers # ------------------------------------------------------------------------------ -proc validate*(desc: MethodsDesc | EphemMethodsDesc | CoreDbErrorRef) = - desc.validateMethodsDesc +proc validate*(dsc: ValidateDesc) = + dsc.validateMethodsDesc proc validate*(db: CoreDbRef) = db.validateMethodsDesc diff --git a/nimbus/db/core_db/memory_only.nim b/nimbus/db/core_db/memory_only.nim index b5a567266..c5417580f 100644 --- a/nimbus/db/core_db/memory_only.nim +++ b/nimbus/db/core_db/memory_only.nim @@ -13,14 +13,18 @@ import std/options, eth/[common, trie/db], - "."/[base, core_apps, legacy_db] + ./backend/[legacy_db], + "."/[base, core_apps] export common, core_apps, # Not all symbols from the object sources will be exported by default + CoreDbAccount, + CoreDbApiError, CoreDbCaptFlags, + CoreDbErrorCode, CoreDbErrorRef, CoreDbCaptRef, CoreDbKvtRef, @@ -30,6 +34,8 @@ export CoreDbTxID, CoreDbTxRef, CoreDbType, + CoreDbVidRef, + CoreDxAccRef, CoreDxCaptRef, CoreDxKvtRef, CoreDxMptRef, @@ -44,26 +50,34 @@ export contains, dbType, del, + delete, dispose, + fetch, + finish, get, + getRoot, getTransactionID, + hash, isLegacy, isPruning, kvt, + logDb, + merge, mptPrune, + newAccMpt, newCapture, newMpt, - newMptPrune, - newPhkPrune, newTransaction, pairs, parent, phkPrune, put, + recast, recorder, replicate, rollback, rootHash, + rootVid, safeDispose, setTransactionID, toLegacy, @@ -86,7 +100,9 @@ proc newCoreDbRef*( ## db.newLegacyPersistentCoreDbRef() -proc newCoreDbRef*(dbType: static[CoreDbType]): CoreDbRef = +proc newCoreDbRef*( + dbType: static[CoreDbType]; # Database type symbol + ): CoreDbRef = ## Constructor for volatile/memory type DB ## ## Note: Using legacy notation `newCoreDbRef()` rather than @@ -96,7 +112,7 @@ proc newCoreDbRef*(dbType: static[CoreDbType]): CoreDbRef = newLegacyMemoryCoreDbRef() else: - {.error: "Unsupported dbType for memory newCoreDbRef()".} + {.error: "Unsupported dbType for memory-only newCoreDbRef()".} # ------------------------------------------------------------------------------ # Public template wrappers diff --git a/nimbus/db/core_db/persistent.nim b/nimbus/db/core_db/persistent.nim index 562ab7b2e..e3333893d 100644 --- a/nimbus/db/core_db/persistent.nim +++ b/nimbus/db/core_db/persistent.nim @@ -5,7 +5,7 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. -## This module automatically pulls in the persistent backend library at the +## This module automatically pulls in the persistent backend libraries at the ## linking stage (e.g. `rocksdb`) which can be avoided for pure memory DB ## applications by importing `db/code_db/memory_only` (rather than ## `db/core_db/persistent`.) @@ -13,12 +13,18 @@ {.push raises: [].} import - "."/[memory_only, legacy_rocksdb] + ../aristo, + ./backend/[legacy_rocksdb], + ./memory_only export - memory_only + memory_only, + toRocksStoreRef -proc newCoreDbRef*(dbType: static[CoreDbType]; path: string): CoreDbRef = +proc newCoreDbRef*( + dbType: static[CoreDbType]; # Database type symbol + path: string; # Storage path for database + ): CoreDbRef = ## Constructor for persistent type DB ## ## Note: Using legacy notation `newCoreDbRef()` rather than @@ -26,6 +32,9 @@ proc newCoreDbRef*(dbType: static[CoreDbType]; path: string): CoreDbRef = when dbType == LegacyDbPersistent: newLegacyPersistentCoreDbRef path + elif dbType == AristoDbRocks: + newAristoRocksDbCoreDbRef path + else: {.error: "Unsupported dbType for persistent newCoreDbRef()".} diff --git a/nimbus/db/state_db.nim b/nimbus/db/state_db.nim index 835a153db..c2daca0f0 100644 --- a/nimbus/db/state_db.nim +++ b/nimbus/db/state_db.nim @@ -63,7 +63,7 @@ proc pruneTrie*(db: AccountStateDB): bool = func db*(db: AccountStateDB): CoreDbRef = db.trie.db -func kvt*(db: AccountStateDB): CoreDbKvtRef = +proc kvt*(db: AccountStateDB): CoreDbKvtRef = db.trie.db.kvt proc rootHash*(db: AccountStateDB): KeccakHash = diff --git a/nimbus/evm/interpreter_dispatch.nim b/nimbus/evm/interpreter_dispatch.nim index f0edc1c2d..d2f78ef90 100644 --- a/nimbus/evm/interpreter_dispatch.nim +++ b/nimbus/evm/interpreter_dispatch.nim @@ -121,7 +121,7 @@ proc afterExecCall(c: Computation) = ## also see: https://github.com/ethereum/EIPs/issues/716 if c.isError or c.fork >= FkByzantium: - if c.msg.contractAddress == ripemdAddr: + if c.msg.contractAddress == RIPEMD_ADDR: # Special case to account for geth+parity bug c.vmState.stateDB.ripemdSpecial() diff --git a/nimbus/sync/handlers/snap.nim b/nimbus/sync/handlers/snap.nim index 7d6e4415a..e306cd3a9 100644 --- a/nimbus/sync/handlers/snap.nim +++ b/nimbus/sync/handlers/snap.nim @@ -17,7 +17,7 @@ import eth/[common, p2p, trie/db, trie/nibbles], stew/[byteutils, interval_set], ../../core/chain, - ../../db/core_db/legacy_db, + ../../db/core_db, ../snap/[constants, range_desc], ../snap/worker/db/[hexary_desc, hexary_error, hexary_paths, snapdb_persistent, hexary_range], diff --git a/nimbus/sync/snap/worker/db/snapdb_desc.nim b/nimbus/sync/snap/worker/db/snapdb_desc.nim index 5b776aa2f..66815d29d 100644 --- a/nimbus/sync/snap/worker/db/snapdb_desc.nim +++ b/nimbus/sync/snap/worker/db/snapdb_desc.nim @@ -14,7 +14,7 @@ import std/tables, chronicles, eth/[common, p2p, trie/nibbles], - ../../../../db/core_db/legacy_rocksdb, + ../../../../db/core_db/persistent, ../../../../db/[core_db, select_backend, storage_types], ../../../protocol, ../../range_desc, diff --git a/nimbus/sync/snap/worker/db/snapdb_persistent.nim b/nimbus/sync/snap/worker/db/snapdb_persistent.nim index 399a24402..50e4a7565 100644 --- a/nimbus/sync/snap/worker/db/snapdb_persistent.nim +++ b/nimbus/sync/snap/worker/db/snapdb_persistent.nim @@ -14,7 +14,8 @@ import std/[algorithm, tables], chronicles, eth/[common, trie/db], - ../../../../db/[core_db, core_db/legacy_db, kvstore_rocksdb], + results, + ../../../../db/[core_db, kvstore_rocksdb], ../../range_desc, "."/[hexary_desc, hexary_error, rocky_bulk_load, snapdb_desc] diff --git a/nimbus/tracer.nim b/nimbus/tracer.nim index 3f7533da9..c8733a0b5 100644 --- a/nimbus/tracer.nim +++ b/nimbus/tracer.nim @@ -76,7 +76,7 @@ proc dumpMemoryDB*(node: JsonNode, db: CoreDbRef) = node["state"] = n proc dumpMemoryDB*(node: JsonNode, capture: CoreDbCaptRef) = - node.dumpMemoryDB capture.recorder + node.dumpMemoryDB capture.logDb const senderName = "sender" diff --git a/tests/replay/xcheck.nim b/tests/replay/xcheck.nim new file mode 100644 index 000000000..899b44dcb --- /dev/null +++ b/tests/replay/xcheck.nim @@ -0,0 +1,50 @@ +# Nimbus - Types, data structures and shared utilities used in network sync +# +# Copyright (c) 2018-2021 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or +# http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or +# http://opensource.org/licenses/MIT) +# at your option. This file may not be copied, modified, or +# distributed except according to those terms. + +import + unittest2 + +# ------------------------------------------------------------------------------ +# Public workflow helpers +# ------------------------------------------------------------------------------ + +template xCheck*(expr: untyped): untyped = + ## Note: this check will invoke `expr` twice + if not (expr): + check expr + return + +template xCheck*(expr: untyped; ifFalse: untyped): untyped = + ## Note: this check will invoke `expr` twice + if not (expr): + ifFalse + check expr + return + +template xCheckRc*(expr: untyped): untyped = + if rc.isErr: + xCheck(expr) + +template xCheckRc*(expr: untyped; ifFalse: untyped): untyped = + if rc.isErr: + xCheck(expr, ifFalse) + +template xCheckErr*(expr: untyped): untyped = + if rc.isOk: + xCheck(expr) + +template xCheckErr*(expr: untyped; ifFalse: untyped): untyped = + if rc.isOk: + xCheck(expr, ifFalse) + +# ------------------------------------------------------------------------------ +# End +# ------------------------------------------------------------------------------ diff --git a/tests/test_aristo/test_backend.nim b/tests/test_aristo/test_backend.nim index 90283007e..2a72185e9 100644 --- a/tests/test_aristo/test_backend.nim +++ b/tests/test_aristo/test_backend.nim @@ -28,6 +28,7 @@ import aristo_persistent, aristo_transcode, aristo_vid], + ../replay/xcheck, ./test_helpers const diff --git a/tests/test_aristo/test_filter.nim b/tests/test_aristo/test_filter.nim index adcb61197..400025a2f 100644 --- a/tests/test_aristo/test_filter.nim +++ b/tests/test_aristo/test_filter.nim @@ -23,6 +23,7 @@ import ../../nimbus/db/aristo, ../../nimbus/db/aristo/aristo_desc/desc_backend, ../../nimbus/db/aristo/aristo_filter/[filter_fifos, filter_scheduler], + ../replay/xcheck, ./test_helpers type diff --git a/tests/test_aristo/test_helpers.nim b/tests/test_aristo/test_helpers.nim index 32a45eb39..b86dee9be 100644 --- a/tests/test_aristo/test_helpers.nim +++ b/tests/test_aristo/test_helpers.nim @@ -192,39 +192,6 @@ proc mapRootVid*( leafTie: LeafTie(root: toVid, path: it.leafTie.path), payload: it.payload)) -# ------------------------------------------------------------------------------ -# Public workflow helpers -# ------------------------------------------------------------------------------ - -template xCheck*(expr: untyped): untyped = - ## Note: this check will invoke `expr` twice - if not (expr): - check expr - return - -template xCheck*(expr: untyped; ifFalse: untyped): untyped = - ## Note: this check will invoke `expr` twice - if not (expr): - ifFalse - check expr - return - -template xCheckRc*(expr: untyped): untyped = - if rc.isErr: - xCheck(expr) - -template xCheckRc*(expr: untyped; ifFalse: untyped): untyped = - if rc.isErr: - xCheck(expr, ifFalse) - -template xCheckErr*(expr: untyped): untyped = - if rc.isOk: - xCheck(expr) - -template xCheckErr*(expr: untyped; ifFalse: untyped): untyped = - if rc.isOk: - xCheck(expr, ifFalse) - # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/tests/test_aristo/test_misc.nim b/tests/test_aristo/test_misc.nim index 3c31c9c55..42abb9745 100644 --- a/tests/test_aristo/test_misc.nim +++ b/tests/test_aristo/test_misc.nim @@ -22,6 +22,7 @@ import ../../nimbus/db/aristo/[ aristo_debug, aristo_desc, aristo_transcode, aristo_vid], ../../nimbus/db/aristo/aristo_filter/filter_scheduler, + ../replay/xcheck, ./test_helpers type diff --git a/tests/test_aristo/test_tx.nim b/tests/test_aristo/test_tx.nim index f7053d598..840ca0f16 100644 --- a/tests/test_aristo/test_tx.nim +++ b/tests/test_aristo/test_tx.nim @@ -21,6 +21,7 @@ import aristo_check, aristo_debug, aristo_delete, aristo_desc, aristo_get, aristo_merge], ../../nimbus/db/[aristo, aristo/aristo_init/persistent], + ../replay/xcheck, ./test_helpers type diff --git a/tests/test_coredb/test_helpers.nim b/tests/test_coredb/test_helpers.nim index 1ffba4112..04d0c02f5 100644 --- a/tests/test_coredb/test_helpers.nim +++ b/tests/test_coredb/test_helpers.nim @@ -39,39 +39,6 @@ proc say*(noisy = false; pfx = "***"; args: varargs[string, `$`]) = # Public helpers # ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ -# Public workflow helpers -# ------------------------------------------------------------------------------ - -template xCheck*(expr: untyped): untyped = - ## Note: this check will invoke `expr` twice - if not (expr): - check expr - return - -template xCheck*(expr: untyped; ifFalse: untyped): untyped = - ## Note: this check will invoke `expr` twice - if not (expr): - ifFalse - check expr - return - -template xCheckRc*(expr: untyped): untyped = - if rc.isErr: - xCheck(expr) - -template xCheckRc*(expr: untyped; ifFalse: untyped): untyped = - if rc.isErr: - xCheck(expr, ifFalse) - -template xCheckErr*(expr: untyped): untyped = - if rc.isOk: - xCheck(expr) - -template xCheckErr*(expr: untyped; ifFalse: untyped): untyped = - if rc.isOk: - xCheck(expr, ifFalse) - # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/tests/test_coredb/test_legacy.nim b/tests/test_coredb/test_legacy.nim index 926e162c4..75e7db5c0 100644 --- a/tests/test_coredb/test_legacy.nim +++ b/tests/test_coredb/test_legacy.nim @@ -15,7 +15,7 @@ import results, unittest2, ../../nimbus/[core/chain], - ../replay/undump_blocks, + ../replay/[undump_blocks, xcheck], ./test_helpers # ------------------------------------------------------------------------------ diff --git a/tests/test_rocksdb_timing.nim b/tests/test_rocksdb_timing.nim index 04e4f5e13..a51be57a9 100644 --- a/tests/test_rocksdb_timing.nim +++ b/tests/test_rocksdb_timing.nim @@ -17,7 +17,7 @@ import eth/[common, p2p], rocksdb, unittest2, - ../nimbus/db/core_db/[legacy_rocksdb, persistent], + ../nimbus/db/core_db/persistent, ../nimbus/core/chain, ../nimbus/sync/snap/range_desc, ../nimbus/sync/snap/worker/db/hexary_desc, diff --git a/tests/test_rocksdb_timing/test_db_timing.nim b/tests/test_rocksdb_timing/test_db_timing.nim index 3066f726a..1d94a4b33 100644 --- a/tests/test_rocksdb_timing/test_db_timing.nim +++ b/tests/test_rocksdb_timing/test_db_timing.nim @@ -18,7 +18,7 @@ import unittest2, ../../nimbus/core/chain, ../../nimbus/db/core_db, - ../../nimbus/db/core_db/legacy_rocksdb, + ../../nimbus/db/core_db/persistent, ../../nimbus/sync/snap/range_desc, ../../nimbus/sync/snap/worker/db/[hexary_desc, rocky_bulk_load], ../../nimbus/utils/prettify, diff --git a/tests/test_sync_snap.nim b/tests/test_sync_snap.nim index f339c04d8..264d6543f 100644 --- a/tests/test_sync_snap.nim +++ b/tests/test_sync_snap.nim @@ -18,7 +18,7 @@ import rocksdb, unittest2, ../nimbus/db/[core_db, kvstore_rocksdb], - ../nimbus/db/core_db/[legacy_rocksdb, persistent], + ../nimbus/db/core_db/persistent, ../nimbus/core/chain, ../nimbus/sync/types, ../nimbus/sync/snap/range_desc, diff --git a/tests/test_sync_snap/test_syncdb.nim b/tests/test_sync_snap/test_syncdb.nim index 4a47fe828..78413cff7 100644 --- a/tests/test_sync_snap/test_syncdb.nim +++ b/tests/test_sync_snap/test_syncdb.nim @@ -18,7 +18,7 @@ import unittest2, ../../nimbus/common as nimbus_common, ../../nimbus/core/chain, - ../../nimbus/db/[core_db/legacy_db, storage_types], + ../../nimbus/db/storage_types, ../../nimbus/sync/snap/worker/db/snapdb_desc, ../replay/[pp, undump_blocks, undump_kvp], ./test_helpers