From 14a5f46d13c4219313bae1c56c9b4a7b4fef6b94 Mon Sep 17 00:00:00 2001 From: Jordan Hrycaj Date: Mon, 18 Mar 2024 19:40:23 +0000 Subject: [PATCH] Core db implement ctx layer for mpt state admin (#2082) * CoreDb+Ledger: Update logging why: Use symbol `api` rather than `ctx` because the latter will be used as name for particular objects * CoreDb: Remove cruft * CoreDb: Remove `TxID` support why: It is nowhere used and ugly implemented. The upcoming context layer will be a cleaner alternative to use, instead should this particular functionality be needed. * CoreDb: Rearrange base methods in source code for better reading * CoreDb+Aristo: Update API closures for better reading & maintenance * CoreDb: Implement context layer for MPT why: On `Aristo` the context layer allows to manage different views on the same backend database. This is an abstraction of the legacy hexary trie which can be localised on a particular root nose. details: The `ctx` context provides the state (equiv. to state root) of the database for MPT and account descriptors. * Fix Copyright headers --- nimbus/db/core_db/backend/aristo_db.nim | 60 +- .../backend/aristo_db/handlers_aristo.nim | 587 +++++++-------- nimbus/db/core_db/backend/legacy_db.nim | 137 ++-- nimbus/db/core_db/base.nim | 678 +++++++++--------- nimbus/db/core_db/base/api_legacy_desc.nim | 6 +- nimbus/db/core_db/base/api_new_desc.nim | 4 +- nimbus/db/core_db/base/api_tracking.nim | 18 +- nimbus/db/core_db/base/base_desc.nim | 103 +-- nimbus/db/core_db/base/validate.nim | 33 +- nimbus/db/core_db/base_iterators.nim | 12 +- .../db/core_db/base_iterators_persistent.nim | 4 +- nimbus/db/core_db/core_apps_newapi.nim | 33 +- nimbus/db/core_db/memory_only.nim | 9 - nimbus/db/ledger/backend/accounts_ledger.nim | 2 +- nimbus/db/ledger/base.nim | 98 +-- nimbus/db/ledger/base/api_tracking.nim | 4 +- nimbus/db/ledger/base_iterators.nim | 10 +- nimbus/db/ledger/distinct_ledgers.nim | 9 +- 18 files changed, 866 insertions(+), 941 deletions(-) diff --git a/nimbus/db/core_db/backend/aristo_db.nim b/nimbus/db/core_db/backend/aristo_db.nim index db67c0453..aaa5ab0e2 100644 --- a/nimbus/db/core_db/backend/aristo_db.nim +++ b/nimbus/db/core_db/backend/aristo_db.nim @@ -65,36 +65,39 @@ proc txMethods( kTx: KvtTxRef; ): CoreDbTxFns = ## To be constructed by some `CoreDbBaseFns` function + let + adbBase = db.adbBase + kdbBase = db.kdbBase + + adbApi = adbBase.api + kdbApi = kdbBase.api + CoreDbTxFns( levelFn: proc(): int = aTx.level, commitFn: proc(ignore: bool): CoreDbRc[void] = const info = "commitFn()" - ? db.adbBase.api.commit(aTx).toVoidRc(db.adbBase, info) - ? db.kdbBase.api.commit(kTx).toVoidRc(db.kdbBase, info) + ? adbApi.commit(aTx).toVoidRc(adbBase, info) + ? kdbApi.commit(kTx).toVoidRc(kdbBase, info) ok(), rollbackFn: proc(): CoreDbRc[void] = const info = "rollbackFn()" - ? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) - ? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info) + ? adbApi.rollback(aTx).toVoidRc(adbBase, info) + ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info) ok(), disposeFn: proc(): CoreDbRc[void] = const info = "disposeFn()" - if db.adbBase.api.isTop(aTx): - ? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) - if db.kdbBase.api.isTop(kTx): - ? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info) + if adbApi.isTop(aTx): ? adbApi.rollback(aTx).toVoidRc(adbBase, info) + if kdbApi.isTop(kTx): ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info) ok(), safeDisposeFn: proc(): CoreDbRc[void] = const info = "safeDisposeFn()" - if db.adbBase.api.isTop(aTx): - ? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) - if db.kdbBase.api.isTop(kTx): - ? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info) + if adbApi.isTop(aTx): ? adbApi.rollback(aTx).toVoidRc(adbBase, info) + if kdbApi.isTop(kTx): ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info) ok()) @@ -104,9 +107,6 @@ proc baseMethods( K: typedesc; ): CoreDbBaseFns = CoreDbBaseFns( - verifyFn: proc(trie: CoreDbTrieRef): bool = - db.adbBase.verify(trie), - backendFn: proc(): CoreDbBackendRef = db.bless(AristoCoreDbBE()), @@ -117,9 +117,6 @@ proc baseMethods( levelFn: proc(): int = db.adbBase.getLevel, - tryHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = - db.adbBase.tryHash(trie, "tryHashFn()"), - rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = db.adbBase.rootHash(trie, "rootHashFn()"), @@ -132,27 +129,11 @@ proc baseMethods( legacySetupFn: proc() = discard, - getTrieFn: proc( - kind: CoreDbSubTrie; - root: Hash256; - address: Option[EthAddress]; - ): CoreDbRc[CoreDbTrieRef] = - db.adbBase.newTrie(kind, root, address, "getTrieFn()"), - newKvtFn: proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] = db.kdbBase.newKvtHandler(sharedTable, "newKvtFn()"), - newMptFn: proc( - trie: CoreDbTrieRef; - prune: bool; # ignored - ): CoreDbRc[CoreDxMptRef] = - db.adbBase.newMptHandler(trie, "newMptFn()"), - - newAccFn: proc( - trie: CoreDbTrieRef; - prune: bool; # ignored - ): CoreDbRc[CoreDxAccRef] = - ok(? db.adbBase.newAccHandler(trie, "newAccFn()")), + getCtxFn: proc(): CoreDbCtxRef = + db.adbBase.ctx, beginFn: proc(): CoreDbRc[CoreDxTxRef] = const info = "beginFn()" @@ -161,9 +142,6 @@ proc baseMethods( kTx = ? db.kdbBase.txBegin(info) ok(db.bless CoreDxTxRef(methods: db.txMethods(aTx, kTx))), - getIdFn: proc(): CoreDbRc[CoreDxTxID] = - CoreDxTxID.notImplemented(db, "getIdFn()"), - newCaptureFn: proc(flags: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] = CoreDxCaptRef.notImplemented(db, "capture()")) @@ -256,14 +234,10 @@ func toAristoProfData*( result.kvt = db.AristoCoreDbRef.kdbBase.api.KvtApiProfRef.data func toAristoApi*(dsc: CoreDxKvtRef): KvtApiRef = - doAssert not dsc.parent.isNil - doAssert dsc.parent.isAristo if dsc.parent.isAristo: return AristoCoreDbRef(dsc.parent).kdbBase.api func toAristoApi*(dsc: CoreDxMptRef): AristoApiRef = - doAssert not dsc.parent.isNil - doAssert dsc.parent.isAristo if dsc.parent.isAristo: return AristoCoreDbRef(dsc.parent).adbBase.api diff --git a/nimbus/db/core_db/backend/aristo_db/handlers_aristo.nim b/nimbus/db/core_db/backend/aristo_db/handlers_aristo.nim index eed520ee9..2e10edc26 100644 --- a/nimbus/db/core_db/backend/aristo_db/handlers_aristo.nim +++ b/nimbus/db/core_db/backend/aristo_db/handlers_aristo.nim @@ -24,8 +24,12 @@ import type AristoBaseRef* = ref object parent: CoreDbRef ## Opaque top level descriptor - adb: AristoDbRef ## Aristo MPT database api*: AristoApiRef ## Api functions can be re-directed + ctx*: AristoCoreDbCtxRef ## Currently active context + + AristoCoreDbCtxRef = ref object of CoreDbCtxRef + base: AristoBaseRef ## Local base descriptor + mpt: AristoDbRef ## Aristo MPT database AristoCoreDxAccRef = ref object of CoreDxAccRef base: AristoBaseRef ## Local base descriptor @@ -71,11 +75,6 @@ static: # Private helpers # ------------------------------------------------------------------------------ -template logTxt(info: static[string]): static[string] = - "CoreDb/adb " & info - -# ------------------------------- - func isValid(trie: CoreDbTrieRef): bool = not trie.isNil and trie.ready @@ -177,46 +176,63 @@ func toVoidRc[T]( return ok() err rc.error.toError(base, info, error) +# ------------------------------- + +proc tryHash( + base: AristoBaseRef; + trie: CoreDbTrieRef; + info: static[string]; + ): CoreDbRc[Hash256] = + let trie = trie.AristoCoreDbTrie + if not trie.isValid: + return err(TrieInvalid.toError(base, info, HashNotAvailable)) + + let root = trie.to(VertexID) + if not root.isValid: + return ok(EMPTY_ROOT_HASH) + + let rc = base.api.getKeyRc(trie.base.ctx.mpt, root) + if rc.isErr: + return err(rc.error.toError(base, info, HashNotAvailable)) + + ok rc.value.to(Hash256) + # ------------------------------------------------------------------------------ # Private `MPT` call back functions # ------------------------------------------------------------------------------ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = ## Hexary trie database handlers + let + cMpt = cMpt # So it can savely be captured + base = cMpt.base # Will not change and can be captured + db = base.parent # Ditto + api = base.api # Ditto + mpt = base.ctx.mpt # Ditto - proc mptBackend( - cMpt: AristoCoreDxMptRef; - ): CoreDbMptBackendRef = - let base = cMpt.base - base.parent.bless AristoCoreDbMptBE(adb: base.adb) + proc mptBackend(): CoreDbMptBackendRef = + db.bless AristoCoreDbMptBE(adb: mpt) - proc mptTrieFn( - cMpt: AristoCoreDxMptRef; - ): CoreDbTrieRef = + proc mptTrieFn(): CoreDbTrieRef = let trie = if LEAST_FREE_VID <= cMpt.root.distinctBase: assert cMpt.accPath.isValid # debug mode only AristoCoreDbTrie( - base: cMpt.base, + base: base, kind: StorageTrie, stoRoot: cMpt.root, stoAddr: cMpt.address) else: AristoCoreDbTrie( - base: cMpt.base, + base: base, kind: CoreDbSubTrie(cMpt.root)) - cMpt.base.parent.bless trie + db.bless trie - proc mptPersistent( - cMpt: AristoCoreDxMptRef; - info: static[string]; - ): CoreDbRc[void] = - let - base = cMpt.base - mpt = base.adb - api = base.api - rc = api.stow(mpt, persistent = true) + proc mptPersistent(): CoreDbRc[void] = + const info = "persistentFn()" + + let rc = api.stow(mpt, persistent = true) if rc.isOk: ok() elif api.level(mpt) == 0: @@ -224,25 +240,17 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = else: err(rc.error.toError(base, info, MptTxPending)) - proc mptFetch( - cMpt: AristoCoreDxMptRef; - k: openArray[byte]; - info: static[string]; - ): CoreDbRc[Blob] = - let - base = cMpt.base - root = cMpt.root + proc mptFetch(key: openArray[byte]): CoreDbRc[Blob] = + const info = "fetchFn()" # Some pathological behaviour observed with storage tries due to lazy # update. The `fetchPayload()` does not now about this and would complain # an error different from `FetchPathNotFound`. + let root = cMpt.root if not root.isValid: return err((VoidTrieID,MptRootMissing).toError(base, info, MptNotFound)) - let - mpt = base.adb - api = base.api - rc = api.fetchPayload(mpt, root, k) + let rc = api.fetchPayload(mpt, root, key) if rc.isOk: api.serialise(mpt, rc.value).toRc(base, info) elif rc.error[1] != FetchPathNotFound: @@ -250,19 +258,11 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = else: err rc.error.toError(base, info, MptNotFound) - proc mptMerge( - cMpt: AristoCoreDxMptRef; - k: openArray[byte]; - v: openArray[byte]; - info: static[string]; - ): CoreDbRc[void] = - let - base = cMpt.base - api = base.api - mpt = base.adb - rootOk = cMpt.root.isValid + proc mptMerge(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = + const info = "mergeFn()" # Provide root ID on-the-fly + let rootOk = cMpt.root.isValid if not rootOk: cMpt.root = api.vidFetch(mpt, pristine=true) @@ -275,22 +275,15 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = return err(rc.error.toError(base, info)) ok() - proc mptDelete( - cMpt: AristoCoreDxMptRef; - k: openArray[byte]; - info: static[string]; - ): CoreDbRc[void] = - let - base = cMpt.base - api = base.api - mpt = base.adb + proc mptDelete(key: openArray[byte]): CoreDbRc[void] = + const info = "deleteFn()" if not cMpt.root.isValid and cMpt.accPath.isValid: # This is insane but legit. A storage trie was announced for an account # but no data have been added, yet. return ok() - let rc = api.delete(mpt, cMpt.root, k, cMpt.accPath) + let rc = api.delete(mpt, cMpt.root, key, cMpt.accPath) if rc.isErr: if rc.error[1] == DelPathNotFound: return err(rc.error.toError(base, info, MptNotFound)) @@ -301,47 +294,39 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = cMpt.root = VoidTrieID ok() - proc mptHasPath( - cMpt: AristoCoreDxMptRef; - key: openArray[byte]; - info: static[string]; - ): CoreDbRc[bool] = - let - base = cMpt.base - mpt = base.adb - api = base.api - rc = api.hasPath(mpt, cMpt.root, key) + proc mptHasPath(key: openArray[byte]): CoreDbRc[bool] = + const info = "hasPathFn()" + + let rc = api.hasPath(mpt, cMpt.root, key) if rc.isErr: return err(rc.error.toError(base, info)) ok(rc.value) + CoreDbMptFns( backendFn: proc(): CoreDbMptBackendRef = - cMpt.mptBackend(), + mptBackend(), fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] = - cMpt.mptFetch(k, "fetchFn()"), + mptFetch(k), deleteFn: proc(k: openArray[byte]): CoreDbRc[void] = - cMpt.mptDelete(k, "deleteFn()"), + mptDelete(k), mergeFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = - cMpt.mptMerge(k, v, "mergeFn()"), + mptMerge(k, v), hasPathFn: proc(k: openArray[byte]): CoreDbRc[bool] = - cMpt.mptHasPath(k, "hasPathFn()"), + mptHasPath(k), getTrieFn: proc(): CoreDbTrieRef = - cMpt.mptTrieFn(), + mptTrieFn(), isPruningFn: proc(): bool = true, persistentFn: proc(): CoreDbRc[void] = - cMpt.mptPersistent("persistentFn()"), - - forgetFn: proc(): CoreDbRc[void] = - discard) + mptPersistent()) # ------------------------------------------------------------------------------ # Private account call back functions @@ -349,30 +334,25 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns = ## Hexary trie database handlers + let + cAcc = cAcc # So it can savely be captured + base = cAcc.base # Will not change and can be captured + db = base.parent # Ditto + api = base.api # Ditto + mpt = base.ctx.mpt # Ditto - proc accBackend( - cAcc: AristoCoreDxAccRef; - ): CoreDbAccBackendRef = - let base = cAcc.base - base.parent.bless AristoCoreDbAccBE(adb: base.adb) + proc accBackend(): CoreDbAccBackendRef = + db.bless AristoCoreDbAccBE(adb: mpt) - proc getTrieFn( - cMpt: AristoCoreDxAccRef; - ): CoreDbTrieRef = - let base = cAcc.base - base.parent.bless AristoCoreDbTrie( + proc getTrieFn(): CoreDbTrieRef = + db.bless AristoCoreDbTrie( base: base, kind: AccountsTrie) - proc accPersistent( - cAcc: AristoCoreDxAccRef; - info: static[string]; - ): CoreDbRc[void] = - let - base = cAcc.base - mpt = base.adb - api = base.api - rc = api.stow(mpt, persistent = true) + proc accPersistent(): CoreDbRc[void] = + const info = "persistentFn()" + + let rc = api.stow(mpt, persistent = true) if rc.isOk: ok() elif api.level(mpt) == 0: @@ -380,64 +360,45 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns = else: err(rc.error.toError(base, info, AccTxPending)) - proc accCloneMpt( - cAcc: AristoCoreDxAccRef; - info: static[string]; - ): CoreDbRc[CoreDxMptRef] = + proc accCloneMpt(): CoreDbRc[CoreDxMptRef] = ok(AristoCoreDxMptRef( - base: cAcc.base, + base: base, root: AccountsTrieID)) - proc accFetch( - cAcc: AristoCoreDxAccRef; - address: EthAddress; - info: static[string]; - ): CoreDbRc[CoreDbAccount] = - let - base = cAcc.base - api = base.api - mpt = base.adb - pyl = block: - let - key = address.keccakHash.data - rc = api.fetchPayload(mpt, AccountsTrieID, key) - if rc.isOk: - rc.value - elif rc.error[1] != FetchPathNotFound: - return err(rc.error.toError(base, info)) - else: - return err(rc.error.toError(base, info, AccNotFound)) + proc accFetch(address: EthAddress): CoreDbRc[CoreDbAccount] = + const info = "fetchFn()" + + let pyl = block: + let + key = address.keccakHash.data + rc = api.fetchPayload(mpt, AccountsTrieID, key) + if rc.isOk: + rc.value + elif rc.error[1] != FetchPathNotFound: + return err(rc.error.toError(base, info)) + else: + return err(rc.error.toError(base, info, AccNotFound)) if pyl.pType != AccountData: - let vePair = (pyl.account.storageID, PayloadTypeUnsupported) - return err(vePair.toError(base, info & "/" & $pyl.pType)) + let vidErrPair = (pyl.account.storageID, PayloadTypeUnsupported) + return err(vidErrPair.toError(base, info & "/" & $pyl.pType)) ok cAcc.toCoreDbAccount(pyl.account, address) - proc accMerge( - cAcc: AristoCoreDxAccRef; - acc: CoreDbAccount; - info: static[string]; - ): CoreDbRc[void] = + proc accMerge(account: CoreDbAccount): CoreDbRc[void] = + const info = "mergeFn()" + let - base = cAcc.base - api = base.api - mpt = base.adb - key = acc.address.keccakHash.data - val = acc.toPayloadRef() + key = account.address.keccakHash.data + val = account.toPayloadRef() rc = api.mergePayload(mpt, AccountsTrieID, key, val) if rc.isErr: return err(rc.error.toError(base, info)) ok() - proc accDelete( - cAcc: AristoCoreDxAccRef; - address: EthAddress; - info: static[string]; - ): CoreDbRc[void] = + proc accDelete(address: EthAddress): CoreDbRc[void] = + const info = "deleteFn()" + let - base = cAcc.base - api = base.api - mpt = base.adb key = address.keccakHash.data rc = api.delete(mpt, AccountsTrieID, key, VOID_PATH_ID) if rc.isErr: @@ -446,15 +407,10 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns = return err(rc.error.toError(base, info)) ok() - proc accStoFlush( - cAcc: AristoCoreDxAccRef; - address: EthAddress; - info: static[string]; - ): CoreDbRc[void] = + proc accStoFlush(address: EthAddress): CoreDbRc[void] = + const info = "stoFlushFn()" + let - base = cAcc.base - api = base.api - mpt = base.adb key = address.keccakHash.data pyl = api.fetchPayload(mpt, AccountsTrieID, key).valueOr: return ok() @@ -468,53 +424,185 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns = return err(rc.error.toError(base, info)) ok() - proc accHasPath( - cAcc: AristoCoreDxAccRef; - address: EthAddress; - info: static[string]; - ): CoreDbRc[bool] = + proc accHasPath(address: EthAddress): CoreDbRc[bool] = + const info = "hasPathFn()" + let - base = cAcc.base - api = cAcc.base.api - mpt = cAcc.base.adb key = address.keccakHash.data rc = api.hasPath(mpt, AccountsTrieID, key) if rc.isErr: return err(rc.error.toError(base, info)) ok(rc.value) + CoreDbAccFns( backendFn: proc(): CoreDbAccBackendRef = - cAcc.accBackend(), + accBackend(), - newMptFn: proc(): CoreDbRc[CoreDxMptRef] = - cAcc.accCloneMpt("newMptFn()"), + getMptFn: proc(): CoreDbRc[CoreDxMptRef] = + accCloneMpt(), fetchFn: proc(address: EthAddress): CoreDbRc[CoreDbAccount] = - cAcc.accFetch(address, "fetchFn()"), + accFetch(address), deleteFn: proc(address: EthAddress): CoreDbRc[void] = - cAcc.accDelete(address, "deleteFn()"), + accDelete(address), stoFlushFn: proc(address: EthAddress): CoreDbRc[void] = - cAcc.accStoFlush(address, "stoFlushFn()"), + accStoFlush(address), mergeFn: proc(acc: CoreDbAccount): CoreDbRc[void] = - cAcc.accMerge(acc, "mergeFn()"), + accMerge(acc), hasPathFn: proc(address: EthAddress): CoreDbRc[bool] = - cAcc.accHasPath(address, "hasPathFn()"), + accHasPath(address), getTrieFn: proc(): CoreDbTrieRef = - cAcc.getTrieFn(), + getTrieFn(), isPruningFn: proc(): bool = true, persistentFn: proc(): CoreDbRc[void] = - cAcc.accPersistent("persistentFn()"), + accPersistent()) - forgetFn: proc(): CoreDbRc[void] = +# ------------------------------------------------------------------------------ +# Private context call back functions +# ------------------------------------------------------------------------------ + +proc ctxMethods(cCtx: AristoCoreDbCtxRef): CoreDbCtxFns = + let + cCtx = cCtx # So it can savely be captured + base = cCtx.base # Will not change and can be captured + db = base.parent # Ditto + api = base.api # Ditto + mpt = base.ctx.mpt # Ditto + + proc ctxNewTrie( + kind: CoreDbSubTrie; + root: Hash256; + address: Option[EthAddress]; + info: static[string]; + ): CoreDbRc[CoreDbTrieRef] = + let trie = AristoCoreDbTrie( + base: base, + kind: kind) + + if kind == StorageTrie: + if address.isNone: + let error = aristo.UtilsAccPathMissing + return err(error.toError(base, info, AccAddrMissing)) + trie.stoAddr = address.unsafeGet + + if not root.isValid: + return ok(db.bless trie) + + # Reset non-dynamic trie when instantiating. This applies to root IDs beween + # `VertexID(2) .. LEAST_FREE_VID`. It emulates the behaviour of a new empty + # MPT on the legacy database. + if AccountsTrie < kind and kind.ord < LEAST_FREE_VID: + trie.reset = true + + # Update hashes in order to verify the trie state root. + ? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable) + + # Make sure that the hash is available as state root on the main trie + let rc = api.getKeyRc(mpt, VertexID kind) + if rc.isErr: + doAssert rc.error == GetKeyNotFound + elif rc.value == root.to(HashKey): + return ok(db.bless trie) + + err(aristo.GenericError.toError(base, info, RootNotFound)) + + + proc ctxGetMpt( + trie: CoreDbTrieRef; + info: static[string]; + ): CoreDbRc[CoreDxMptRef] = + let + trie = AristoCoreDbTrie(trie) + var + reset = false + newMpt: AristoCoreDxMptRef + if not trie.isValid: + reset = true + newMpt = AristoCoreDxMptRef( + root: GenericTrieID, + accPath: VOID_PATH_ID) + + elif trie.kind == StorageTrie: + newMpt = AristoCoreDxMptRef( + root: trie.stoRoot, + accPath: trie.stoAddr.to(PathID), + address: trie.stoAddr) + if trie.stoRoot.isValid: + if trie.stoRoot.distinctBase < LEAST_FREE_VID: + let error = (trie.stoRoot,MptRootUnacceptable) + return err(error.toError(base, info, RootUnacceptable)) + # Verify path if there is a particular storge root VID + let rc = api.hikeUp(newMpt.accPath.to(NibblesSeq), AccountsTrieID, mpt) + if rc.isErr: + return err(rc.error[1].toError(base, info, AccNotFound)) + else: + reset = AccountsTrie < trie.kind + newMpt = AristoCoreDxMptRef( + root: VertexID(trie.kind), + accPath: VOID_PATH_ID) + + # Reset trie. This a emulates the behaviour of a new empty MPT on the + # legacy database. + if reset: + let rc = api.delTree(mpt, newMpt.root, VOID_PATH_ID) + if rc.isErr: + return err(rc.error.toError(base, info, AutoFlushFailed)) + trie.reset = false + + newMpt.base = base + newMpt.methods = newMpt.mptMethods() + + ok(db.bless newMpt) + + + proc ctxGetAcc( + trie: CoreDbTrieRef; + info: static[string]; + ): CoreDbRc[CoreDxAccRef] = + let trie = AristoCoreDbTrie(trie) + if trie.kind != AccountsTrie: + let error = (AccountsTrieID, AccRootUnacceptable) + return err(error.toError(base, info, RootUnacceptable)) + + let acc = AristoCoreDxAccRef(base: base) + acc.methods = acc.accMethods() + + ok(db.bless acc) + + CoreDbCtxFns( + fromTxFn: proc(root: Hash256; kind: CoreDbSubTrie): CoreDbRc[CoreDbCtxRef] = + const info = "fromTxFn()" + err(aristo.NotImplemented.toError(base, info, base_desc.NotImplemented)), + + swapFn: proc(cty: CoreDbCtxRef): CoreDbCtxRef = + doAssert not cty.isNil + base.ctx.swap(AristoCoreDbCtxRef(cty)), + + newTrieFn: proc( + trie: CoreDbSubTrie; + root: Hash256; + address: Option[EthAddress]; + ): CoreDbRc[CoreDbTrieRef] = + ctxNewTrie(trie, root, address, "newTrieFn()"), + + getMptFn: proc(trie: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxMptRef] = + ctxGetMpt(trie, "newMptFn()"), + + getAccFn: proc(trie: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxAccRef] = + ctxGetAcc(trie, "newAccFn()"), + + forgetFn: proc() = + api.forget(mpt).isOkOr: + raiseAssert "forgetFn(): " & $error discard) # ------------------------------------------------------------------------------ @@ -546,7 +634,7 @@ func toVoidRc*[T]( # --------------------- func to*(dsc: CoreDxMptRef, T: type AristoDbRef): T = - AristoCoreDxMptRef(dsc).base.adb + AristoCoreDxMptRef(dsc).base.ctx.mpt func rootID*(dsc: CoreDxMptRef): VertexID = dsc.AristoCoreDxMptRef.root @@ -561,31 +649,12 @@ proc txBegin*( base: AristoBaseRef; info: static[string]; ): CoreDbRc[AristoTxRef] = - base.api.txBegin(base.adb).toRc(base, info) + base.api.txBegin(base.ctx.mpt).toRc(base, info) # --------------------- proc getLevel*(base: AristoBaseRef): int = - base.api.level(base.adb) - -proc tryHash*( - base: AristoBaseRef; - trie: CoreDbTrieRef; - info: static[string]; - ): CoreDbRc[Hash256] = - let trie = trie.AristoCoreDbTrie - if not trie.isValid: - return err(TrieInvalid.toError(base, info, HashNotAvailable)) - - let root = trie.to(VertexID) - if not root.isValid: - return ok(EMPTY_ROOT_HASH) - - let rc = base.api.getKeyRc(trie.base.adb, root) - if rc.isErr: - return err(rc.error.toError(base, info, HashNotAvailable)) - - ok rc.value.to(Hash256) + base.api.level(base.ctx.mpt) proc triePrint*( base: AristoBaseRef; @@ -626,7 +695,7 @@ proc rootHash*( let api = base.api - mpt = base.adb + mpt = base.ctx.mpt ? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable) let key = block: @@ -638,145 +707,29 @@ proc rootHash*( ok key.to(Hash256) - -proc newTrie*( - base: AristoBaseRef; - kind: CoreDbSubTrie; - root: Hash256; - address: Option[EthAddress]; - info: static[string]; - ): CoreDbRc[CoreDbTrieRef] = - let - adb = base.adb - api = base.api - trie = AristoCoreDbTrie( - base: base, - kind: kind) - - if kind == StorageTrie: - if address.isNone: - let error = aristo.UtilsAccPathMissing - return err(error.toError(base, info, AccAddrMissing)) - trie.stoAddr = address.unsafeGet - - if not root.isValid: - return ok(base.parent.bless trie) - - # Reset non-dynamic trie when instantiating. This applies to root IDs beween - # `VertexID(2) .. LEAST_FREE_VID`. It emulates the behaviour of a new empty - # MPT on the legacy database. - if AccountsTrie < kind and kind.ord < LEAST_FREE_VID: - trie.reset = true - - # Update hashes in order to verify the trie state root. - ? api.hashify(adb).toVoidRc(base, info, HashNotAvailable) - - # Make sure that the hash is available as state root on the main trie - let rc = api.getKeyRc(adb, VertexID kind) - if rc.isErr: - doAssert rc.error == GetKeyNotFound - elif rc.value == root.to(HashKey): - return ok(base.parent.bless trie) - - err(aristo.GenericError.toError(base, info, RootNotFound)) - # ------------------------------------------------------------------------------ # Public constructors and related # ------------------------------------------------------------------------------ -proc verify*(base: AristoBaseRef; trie: CoreDbTrieRef): bool = - let trie = trie.AristoCoreDbTrie - if not trie.base.isNil: - if trie.kind != StorageTrie: - return true - if LEAST_FREE_VID < trie.stoRoot.distinctBase: - let path = trie.stoAddr.to(PathID).to(NibblesSeq) - if base.api.hikeUp(path, AccountsTrieID, base.adb).isOk: - return true - false - -proc newMptHandler*( - base: AristoBaseRef; - trie: CoreDbTrieRef; - info: static[string]; - ): CoreDbRc[CoreDxMptRef] = - let - trie = AristoCoreDbTrie(trie) - api = base.api - - var - reset = false - mpt: AristoCoreDxMptRef - if not trie.isValid: - reset = true - mpt = AristoCoreDxMptRef( - root: GenericTrieID, - accPath: VOID_PATH_ID) - - elif trie.kind == StorageTrie: - mpt = AristoCoreDxMptRef( - root: trie.stoRoot, - accPath: trie.stoAddr.to(PathID), - address: trie.stoAddr) - - if trie.stoRoot.isValid: - if trie.stoRoot.distinctBase < LEAST_FREE_VID: - let error = (trie.stoRoot,MptRootUnacceptable) - return err(error.toError(base, info, RootUnacceptable)) - # Verify path if there is a particular storge root VID - let rc = api.hikeUp(mpt.accPath.to(NibblesSeq), AccountsTrieID, base.adb) - if rc.isErr: - return err(rc.error[1].toError(base, info, AccNotFound)) - else: - reset = AccountsTrie < trie.kind - mpt = AristoCoreDxMptRef( - root: VertexID(trie.kind), - accPath: VOID_PATH_ID) - - # Reset trie. This a emulates the behaviour of a new empty MPT on the - # legacy database. - if reset: - let rc = base.api.delTree(base.adb, mpt.root, VOID_PATH_ID) - if rc.isErr: - return err(rc.error.toError(base, info, AutoFlushFailed)) - trie.reset = false - - mpt.base = base - mpt.methods = mpt.mptMethods() - - ok(base.parent.bless mpt) - - -proc newAccHandler*( - base: AristoBaseRef; - trie: CoreDbTrieRef; - info: static[string]; - ): CoreDbRc[CoreDxAccRef] = - let trie = AristoCoreDbTrie(trie) - if trie.kind != AccountsTrie: - let error = (AccountsTrieID, AccRootUnacceptable) - return err(error.toError(base, info, RootUnacceptable)) - - let acc = AristoCoreDxAccRef(base: base) - acc.methods = acc.accMethods() - - ok(base.parent.bless acc) - - proc destroy*(base: AristoBaseRef; flush: bool) = - base.api.finish(base.adb, flush) + base.api.finish(base.ctx.mpt, flush) func init*(T: type AristoBaseRef; db: CoreDbRef; adb: AristoDbRef): T = result = T( parent: db, - api: AristoApiRef.init(), - adb: adb) + api: AristoApiRef.init()) + + # Create initial context + result.ctx = db.bless AristoCoreDbCtxRef( + base: result, + mpt: adb) + result.ctx.methods = result.ctx.ctxMethods when CoreDbEnableApiProfiling: let profApi = AristoApiProfRef.init(result.api, adb.backend) result.api = profApi - result.adb.backend = profApi.be + result.ctx.mpt.backend = profApi.be # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/core_db/backend/legacy_db.nim b/nimbus/db/core_db/backend/legacy_db.nim index 95e870e7f..7be626eb4 100644 --- a/nimbus/db/core_db/backend/legacy_db.nim +++ b/nimbus/db/core_db/backend/legacy_db.nim @@ -28,6 +28,7 @@ type kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor tdb: TrieDatabaseRef ## Descriptor reference copy captured with closures top: LegacyCoreDxTxRef ## Top transaction (if any) + ctx: LegacyCoreDbCtxRef ## Cache, there is only one context here level: int ## Debugging LegacyDbClose* = proc() {.gcsafe, raises: [].} @@ -40,6 +41,10 @@ type address: Option[EthAddress] ## For storage tree debugging accPath: Blob ## For storage tree debugging + LegacyCoreDbCtxRef = ref object of CoreDbCtxRef + ## Context (there is only one context here) + base: LegacyDbRef + LegacyCoreDxTxRef = ref object of CoreDxTxRef ltx: DbTransaction ## Legacy transaction descriptor back: LegacyCoreDxTxRef ## Previous transaction @@ -312,9 +317,6 @@ proc mptMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbMptFns = if 0 < db.txLevel(): const info = "persistentFn()" return err(db.bless(MptTxPending, LegacyCoreDbError(ctx: info))) - ok(), - - forgetFn: proc(): CoreDbRc[void] = ok()) proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns = @@ -323,7 +325,7 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns = backendFn: proc(): CoreDbAccBackendRef = db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)), - newMptFn: proc(): CoreDbRc[CoreDxMptRef] = + getMptFn: proc(): CoreDbRc[CoreDxMptRef] = let xMpt = HexaryChildDbRef(trie: mpt.trie) ok(db.bless CoreDxMptRef(methods: xMpt.mptMethods db)), @@ -367,11 +369,68 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns = if 0 < db.txLevel(): const info = "persistentFn()" return err(db.bless(AccTxPending, LegacyCoreDbError(ctx: info))) - ok(), - - forgetFn: proc(): CoreDbRc[void] = ok()) + +proc ctxMethods(ctx: LegacyCoreDbCtxRef): CoreDbCtxFns = + let + db = ctx.base + tdb = db.tdb + + CoreDbCtxFns( + fromTxFn: proc( + root: Hash256; + kind: CoreDbSubTrie; + ): CoreDbRc[CoreDbCtxRef] = + # This is not 100% on the tx layer but should work anyway with + # the application as it emulates sort of `Aristo` behaviour. + if db.tdb.contains root.data: + return ok(ctx) + err(db.bless(CtxNotFound, LegacyCoreDbError(ctx: "fromTxFn()"))), + + swapFn: proc(cty: CoreDbCtxRef): CoreDbCtxRef = + doAssert cty == ctx + ctx, + + newTrieFn: proc( + kind: CoreDbSubTrie; + root: Hash256; + address: Option[EthAddress]; + ): CoreDbRc[CoreDbTrieRef] = + var trie = LegacyCoreDbTrie(root: root) + when CoreDbEnableApiTracking: + trie.kind = kind + trie.address = address + if address.isSome: + trie.accPath = @(address.unsafeGet.keccakHash.data) + ok(db.bless trie), + + getMptFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxMptRef] = + var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune)) + when CoreDbEnableApiTracking: + if not trie.isNil and trie.ready: + let trie = trie.LegacyCoreDbTrie + mpt.kind = trie.kind + mpt.address = trie.address + mpt.accPath = trie.accPath + ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)), + + getAccFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxAccRef] = + var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune)) + when CoreDbEnableApiTracking: + if not trie.isNil and trie.ready: + if trie.LegacyCoreDbTrie.kind != AccountsTrie: + let ctx = LegacyCoreDbError( + ctx: "newAccFn()", + msg: "got " & $trie.LegacyCoreDbTrie.kind) + return err(db.bless(RootUnacceptable, ctx)) + mpt.kind = AccountsTrie + ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)), + + forgetFn: proc() = + discard) + + proc txMethods(tx: CoreDxTxRef): CoreDbTxFns = let tx = tx.LegacyCoreDxTxRef @@ -405,12 +464,6 @@ proc txMethods(tx: CoreDxTxRef): CoreDbTxFns = tx.pop() ok()) -proc tidMethods(tid: TransactionID; tdb: TrieDatabaseRef): CoreDbTxIdFns = - CoreDbTxIdFns( - roWrapperFn: proc(action: CoreDbTxIdActionFn): CoreDbRc[void] = - tdb.shortTimeReadOnly(tid, action()) - ok()) - proc cptMethods(cpt: RecorderRef; db: LegacyDbRef): CoreDbCaptFns = CoreDbCaptFns( recorderFn: proc(): CoreDbRef = @@ -436,16 +489,6 @@ proc baseMethods( ): CoreDbBaseFns = let tdb = db.tdb CoreDbBaseFns( - verifyFn: proc(trie: CoreDbTrieRef): bool = - when CoreDbEnableApiTracking: - let trie = trie.LegacyCoreDbTrie - if trie.kind == StorageTrie: - if trie.root != EMPTY_ROOT_HASH and trie.address.isNone: - return false - else: - discard # at the moment - true, - backendFn: proc(): CoreDbBackendRef = db.bless(LegacyCoreDbBE(base: db)), @@ -456,9 +499,6 @@ proc baseMethods( if not closeDb.isNil: closeDb(), - tryHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = - ok(trie.lroot), - rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = ok(trie.lroot), @@ -471,46 +511,11 @@ proc baseMethods( legacySetupFn: proc() = db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]), - getTrieFn: proc( - kind: CoreDbSubTrie; - root: Hash256; - address: Option[EthAddress]; - ): CoreDbRc[CoreDbTrieRef] = - var trie = LegacyCoreDbTrie(root: root) - when CoreDbEnableApiTracking: - trie.kind = kind - trie.address = address - if address.isSome: - trie.accPath = @(address.unsafeGet.keccakHash.data) - ok(db.bless trie), - newKvtFn: proc(sharedTable = true): CoreDbRc[CoreDxKvtRef] = ok(db.kvt), - newMptFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxMptRef] = - var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune)) - when CoreDbEnableApiTracking: - if not trie.isNil and trie.ready: - let trie = trie.LegacyCoreDbTrie - mpt.kind = trie.kind - mpt.address = trie.address - mpt.accPath = trie.accPath - ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)), - - newAccFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxAccRef] = - var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune)) - when CoreDbEnableApiTracking: - if not trie.isNil and trie.ready: - if trie.LegacyCoreDbTrie.kind != AccountsTrie: - let ctx = LegacyCoreDbError( - ctx: "newAccFn()", - msg: "got " & $trie.LegacyCoreDbTrie.kind) - return err(db.bless(RootUnacceptable, ctx)) - mpt.kind = AccountsTrie - ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)), - - getIdFn: proc(): CoreDbRc[CoreDxTxID] = - ok(db.bless CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb))), + getCtxFn: proc(): CoreDbCtxRef = + db.ctx, beginFn: proc(): CoreDbRc[CoreDxTxRef] = db.top = LegacyCoreDxTxRef( @@ -543,6 +548,12 @@ proc init*( # Base descriptor db.dbType = dbType db.methods = db.baseMethods(dbType, closeDb) + + # Blind context layer + let ctx = LegacyCoreDbCtxRef(base: db) + ctx.methods = ctx.ctxMethods + db.ctx = db.bless ctx + db.bless # ------------------------------------------------------------------------------ diff --git a/nimbus/db/core_db/base.nim b/nimbus/db/core_db/base.nim index 527148d4a..840d0bce8 100644 --- a/nimbus/db/core_db/base.nim +++ b/nimbus/db/core_db/base.nim @@ -43,6 +43,7 @@ export CoreDbApiError, CoreDbBackendRef, CoreDbCaptFlags, + CoreDbCtxRef, CoreDbErrorCode, CoreDbErrorRef, CoreDbFnInx, @@ -120,7 +121,7 @@ when ProvideLegacyAPI: when EnableApiTracking: w.beginLegaApi(s) code - const ctx {.inject,used.} = s + const api {.inject,used.} = s template setTrackLegaApi*( w: CoreDbApiTrackRef; @@ -145,7 +146,7 @@ template setTrackNewApi( when EnableApiTracking: w.beginNewApi(s) code - const ctx {.inject,used.} = s + const api {.inject,used.} = s template setTrackNewApi*( w: CoreDxApiTrackRef; @@ -247,11 +248,6 @@ proc prettyText*(trie: CoreDbTrieRef): string = ## Pretty print argument object (for tracking use `$$()`) if trie.isNil or not trie.ready: "$ΓΈ" else: trie.toStr() -proc verify*(trie: CoreDbTrieRef): bool = - ## Verify that the `trie` argument is `nil` or properly initialised. This - ## function is for debugging and subject to change. - trie.isNil or (trie.ready and trie.parent.methods.verifyFn trie) - # ------------------------------------------------------------------------------ # Public main descriptor methods # ------------------------------------------------------------------------------ @@ -268,7 +264,7 @@ proc dbType*(db: CoreDbRef): CoreDbType = ## db.setTrackNewApi BaseDbTypeFn result = db.dbType - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + db.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc compensateLegacySetup*(db: CoreDbRef) = ## On the persistent legacy hexary trie, this function is needed for @@ -277,7 +273,7 @@ proc compensateLegacySetup*(db: CoreDbRef) = ## db.setTrackNewApi BaseLegacySetupFn db.methods.legacySetupFn() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed + db.ifTrackNewApi: debug newApiTxt, api, elapsed proc level*(db: CoreDbRef): int = ## Getter, retrieve transaction level (zero if there is no pending @@ -285,7 +281,7 @@ proc level*(db: CoreDbRef): int = ## db.setTrackNewApi BaseLevelFn result = db.methods.levelFn() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + db.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc parent*(cld: CoreDxChldRefs): CoreDbRef = ## Getter, common method for all sub-modules @@ -297,7 +293,7 @@ proc backend*(dsc: CoreDxKvtRef | CoreDxTrieRelated | CoreDbRef): auto = ## dsc.setTrackNewApi AnyBackendFn result = dsc.methods.backendFn() - dsc.ifTrackNewApi: debug newApiTxt, ctx, elapsed + dsc.ifTrackNewApi: debug newApiTxt, api, elapsed proc finish*(db: CoreDbRef; flush = false) = ## Database destructor. If the argument `flush` is set `false`, the database @@ -309,7 +305,7 @@ proc finish*(db: CoreDbRef; flush = false) = ## db.setTrackNewApi BaseFinishFn db.methods.destroyFn flush - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed + db.ifTrackNewApi: debug newApiTxt, api, elapsed proc `$$`*(e: CoreDbErrorRef): string = ## Pretty print error symbol, note that this directive may have side effects @@ -317,120 +313,7 @@ proc `$$`*(e: CoreDbErrorRef): string = ## e.setTrackNewApi ErrorPrintFn result = e.prettyText() - e.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result - -proc `$$`*(trie: CoreDbTrieRef): string = - ## Pretty print vertex ID symbol, note that this directive may have side - ## effects as it calls a backend function. - ## - #trie.setTrackNewApi TriePrintFn - result = trie.prettyText() - #trie.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result - -proc rootHash*(trie: CoreDbTrieRef): CoreDbRc[Hash256] = - ## Getter (well, sort of), retrieves the root hash for the argument `trie` - ## descriptor. The function might fail if there is currently no hash - ## available (e.g. on `Aristo`.) Note that a failure to retrieve the hash - ## (which returns an error) is different from succeeding with an - ## `EMPTY_ROOT_HASH` value for an empty trie. - ## - ## The value `EMPTY_ROOT_HASH` is also returned on a void `trie` descriptor - ## argument `CoreDbTrieRef(nil)`. - ## - trie.setTrackNewApi RootHashFn - result = block: - if not trie.isNil and trie.ready: - trie.parent.methods.rootHashFn trie - else: - ok EMPTY_ROOT_HASH - # Note: tracker will be silent if `vid` is NIL - trie.ifTrackNewApi: debug newApiTxt, ctx, elapsed, trie, result - -proc rootHashOrEmpty*(trie: CoreDbTrieRef): Hash256 = - ## Convenience wrapper, returns `EMPTY_ROOT_HASH` where `hash()` would fail. - trie.rootHash.valueOr: EMPTY_ROOT_HASH - -proc recast*(account: CoreDbAccount): CoreDbRc[Account] = - ## 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. - ## - let stoTrie = account.stoTrie - stoTrie.setTrackNewApi EthAccRecastFn - let rc = - if stoTrie.isNil or not stoTrie.ready: CoreDbRc[Hash256].ok(EMPTY_ROOT_HASH) - else: stoTrie.parent.methods.rootHashFn stoTrie - result = - if rc.isOk: - ok Account( - nonce: account.nonce, - balance: account.balance, - codeHash: account.codeHash, - storageRoot: rc.value) - else: - err(rc.error) - stoTrie.ifTrackNewApi: debug newApiTxt, ctx, elapsed, stoTrie, result - - -proc getTrie*( - db: CoreDbRef; - kind: CoreDbSubTrie; - root: Hash256; - address = none(EthAddress); - ): CoreDbRc[CoreDbTrieRef] = - ## Retrieve virtual sub-trie descriptor. - ## - ## For a sub-trie of type `kind` find the root node with Merkle hash `root`. - ## If the `root` argument is set `EMPTY_ROOT_HASH`, this function always - ## succeeds. Otherwise, the function will fail unless a root node with the - ## corresponding argument Merkle hash `root` exists. - ## - ## For an `EMPTY_ROOT_HASH` root hash argument and a sub-trie of type `kind` - ## different form `StorageTrie` and `AccuntsTrie`, the returned sub-trie - ## descriptor will be flagged to flush the sub-trie when this descriptor is - ## incarnated as MPT (see `newMpt()`.). - ## - ## If the argument `kind` is `StorageTrie`, then the `address` argument is - ## needed which links an account to the result descriptor. - ## - ## This function is intended to open a virtual trie database as in: - ## :: - ## proc openAccountLedger(db: CoreDbRef, root: Hash256): CoreDxMptRef = - ## let trie = db.getTrie(AccountsTrie, root).valueOr: - ## # some error handling - ## return - ## db.newAccMpt trie - ## - db.setTrackNewApi BaseGetTrieFn - result = db.methods.getTrieFn(kind, root, address) - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, kind, root, address, result - -proc getTrie*( - db: CoreDbRef; - root: Hash256; - address: EthAddress; - ): CoreDbRc[CoreDbTrieRef] = - ## Shortcut for `db.getTrie(StorageTrie,root,some(address))`. - ## - db.setTrackNewApi BaseGetTrieFn - result = db.methods.getTrieFn(StorageTrie, root, some(address)) - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, root, address, result - -proc getTrie*( - db: CoreDbRef; - address: EthAddress; - ): CoreDbTrieRef = - ## Shortcut for `db.getTrie(StorageTrie,EMPTY_ROOT_HASH,address).value`. The - ## function will throw an exception on error. So the result will always be a - ## valid descriptor. - ## - db.setTrackNewApi BaseGetTrieFn - result = db.methods.getTrieFn( - StorageTrie, EMPTY_ROOT_HASH, some(address)).valueOr: - raiseAssert error.prettyText() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, address, result + e.ifTrackNewApi: debug newApiTxt, api, elapsed, result # ------------------------------------------------------------------------------ # Public key-value table methods @@ -457,13 +340,13 @@ proc newKvt*(db: CoreDbRef; sharedTable = true): CoreDxKvtRef = db.setTrackNewApi BaseNewKvtFn result = db.methods.newKvtFn(sharedTable).valueOr: raiseAssert error.prettyText() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, sharedTable + db.ifTrackNewApi: debug newApiTxt, api, elapsed, sharedTable proc get*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] = ## This function always returns a non-empty `Blob` or an error code. kvt.setTrackNewApi KvtGetFn result = kvt.methods.getFn key - kvt.ifTrackNewApi: debug newApiTxt, ctx, elapsed, key=key.toStr, result + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, key=key.toStr, result proc getOrEmpty*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] = ## This function sort of mimics the behaviour of the legacy database @@ -474,12 +357,12 @@ proc getOrEmpty*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] = result = kvt.methods.getFn key if result.isErr and result.error.error == KvtNotFound: result = CoreDbRc[Blob].ok(EmptyBlob) - kvt.ifTrackNewApi: debug newApiTxt, ctx, elapsed, key=key.toStr, result + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, key=key.toStr, result proc del*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[void] = kvt.setTrackNewApi KvtDelFn result = kvt.methods.delFn key - kvt.ifTrackNewApi: debug newApiTxt, ctx, elapsed, key=key.toStr, result + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, key=key.toStr, result proc put*( kvt: CoreDxKvtRef; @@ -489,16 +372,16 @@ proc put*( kvt.setTrackNewApi KvtPutFn result = kvt.methods.putFn(key, val) kvt.ifTrackNewApi: - debug newApiTxt, ctx, elapsed, key=key.toStr, val=val.toLenStr, result + debug newApiTxt, api, elapsed, key=key.toStr, val=val.toLenStr, result proc hasKey*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[bool] = ## Would be named `contains` if it returned `bool` rather than `Result[]`. ## kvt.setTrackNewApi KvtHasKeyFn result = kvt.methods.hasKeyFn key - kvt.ifTrackNewApi: debug newApiTxt, ctx, elapsed, key=key.toStr, result + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, key=key.toStr, result -proc persistent*(dsc: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = +proc persistent*(kvt: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = ## For the legacy database, this function has no effect and succeeds always. ## It will nevertheless return a discardable error if there is a pending ## transaction. @@ -506,17 +389,11 @@ proc persistent*(dsc: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = ## This function saves the current cache to the database if possible, ## regardless of the save/share mode assigned to the constructor. ## - ## Caveat: - ## If `dsc` is a detached descriptor of `Companion` or `TopShot` mode which - ## could be persistently saved, the changes are immediately visible on all - ## other descriptors unless they are hidden by newer versions of key-value - ## items in the cache. - ## - dsc.setTrackNewApi KvtPersistentFn - result = dsc.methods.persistentFn() - dsc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + kvt.setTrackNewApi KvtPersistentFn + result = kvt.methods.persistentFn() + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, result -proc forget*(dsc: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = +proc forget*(kvt: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = ## For the legacy database, this function has no effect and succeeds always. ## ## This function destroys the current non-shared descriptor (see argument @@ -528,65 +405,196 @@ proc forget*(dsc: CoreDxKvtRef): CoreDbRc[void] {.discardable.} = ## Auto destruction seems to be unreliable (causing spurious crashes.) ## So manual destruction using this function is advised. ## - dsc.setTrackNewApi KvtForgetFn - result = dsc.methods.forgetFn() - dsc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + kvt.setTrackNewApi KvtForgetFn + result = kvt.methods.forgetFn() + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed, result + +# ------------------------------------------------------------------------------ +# Public Merkle Patricia Tree context administration +# ------------------------------------------------------------------------------ + +proc ctx*(db: CoreDbRef): CoreDbCtxRef = + ## Get currently active context. + ## + db.setTrackNewApi BaseGetCtxFn + result = db.methods.getCtxFn() + db.ifTrackNewApi: debug newApiTxt, api, elapsed + +proc fromTx*( + ctx: CoreDbCtxRef; + root: Hash256; + kind = AccountsTrie; + ): CoreDbRc[CoreDbCtxRef] = + ## Create new context derived from matching transaction of the currently + ## active context. + ## + ctx.setTrackNewApi CtxFromTxFn + result = ctx.methods.fromTxFn(root, kind) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, result + +proc swap*(ctx: CoreDbCtxRef; other: CoreDbCtxRef): CoreDbCtxRef = + ## Activate argument context `other` and return the previously active + ## context. + ## + ctx.setTrackNewApi CtxSwapFn + result = ctx.methods.swapFn(other) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed + +proc forget*(ctx: CoreDbCtxRef) = + ## Dispose contextand all MPT views related. + ## + ctx.setTrackNewApi CtxForgetFn + ctx.methods.forgetFn() + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed + +# ------------------------------------------------------------------------------ +# Public Merkle Patricia Tree sub-trie abstaction management +# ------------------------------------------------------------------------------ + +proc newTrie*( + ctx: CoreDbCtxRef; + kind: CoreDbSubTrie; + root: Hash256; + address = none(EthAddress); + ): CoreDbRc[CoreDbTrieRef] = + ## Retrieve a new virtual sub-trie descriptor. + ## + ## For a sub-trie of type `kind` find the root node with Merkle hash `root`. + ## If the `root` argument is set `EMPTY_ROOT_HASH`, this function always + ## succeeds. Otherwise, the function will fail unless a root node with the + ## corresponding argument Merkle hash `root` exists. + ## + ## For an `EMPTY_ROOT_HASH` root hash argument and a sub-trie of type `kind` + ## different form `StorageTrie` and `AccuntsTrie`, the returned sub-trie + ## descriptor will be flagged to flush the sub-trie when this descriptor is + ## incarnated as MPT (see `newMpt()`.). + ## + ## If the argument `kind` is `StorageTrie`, then the `address` argument is + ## needed which links an account to the result descriptor. + ## + ## This function is intended to open a virtual trie database as in: + ## :: + ## proc openAccountLedger(db: CoreDbRef, root: Hash256): CoreDxMptRef = + ## let trie = db.ctx.newTrie(AccountsTrie, root).valueOr: + ## # some error handling + ## return + ## db.getAccMpt trie + ## + ctx.setTrackNewApi CtxNewTrieFn + result = ctx.methods.newTrieFn(kind, root, address) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, kind, root, address, result + +proc newTrie*( + ctx: CoreDbCtxRef; + root: Hash256; + address: EthAddress; + ): CoreDbRc[CoreDbTrieRef] = + ## Shortcut for `ctx.newTrie(StorageTrie,root,some(address))`. + ## + ctx.setTrackNewApi CtxNewTrieFn + result = ctx.methods.newTrieFn(StorageTrie, root, some(address)) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, root, address, result + +proc newTrie*( + ctx: CoreDbCtxRef; + address: EthAddress; + ): CoreDbTrieRef = + ## Shortcut for `ctx.newTrie(EMPTY_ROOT_HASH,address).value`. The function + ## will throw an exception on error. So the result will always be a valid + ## descriptor. + ## + ctx.setTrackNewApi CtxNewTrieFn + result = ctx.methods.newTrieFn( + StorageTrie, EMPTY_ROOT_HASH, some(address)).valueOr: + raiseAssert error.prettyText() + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, address, result + + +proc `$$`*(trie: CoreDbTrieRef): string = + ## Pretty print vertex ID symbol, note that this directive may have side + ## effects as it calls a backend function. + ## + #trie.setTrackNewApi TriePrintFn + result = trie.prettyText() + #trie.ifTrackNewApi: debug newApiTxt, api, elapsed, result + +proc rootHash*(trie: CoreDbTrieRef): CoreDbRc[Hash256] = + ## Getter (well, sort of), retrieves the root hash for the argument `trie` + ## descriptor. The function might fail if there is currently no hash + ## available (e.g. on `Aristo`.) Note that a failure to retrieve the hash + ## (which returns an error) is different from succeeding with an + ## `EMPTY_ROOT_HASH` value for an empty trie. + ## + ## The value `EMPTY_ROOT_HASH` is also returned on a void `trie` descriptor + ## argument `CoreDbTrieRef(nil)`. + ## + trie.setTrackNewApi RootHashFn + result = block: + if not trie.isNil and trie.ready: + trie.parent.methods.rootHashFn trie + else: + ok EMPTY_ROOT_HASH + # Note: tracker will be silent if `vid` is NIL + trie.ifTrackNewApi: debug newApiTxt, api, elapsed, trie, result + +proc rootHashOrEmpty*(trie: CoreDbTrieRef): Hash256 = + ## Convenience wrapper, returns `EMPTY_ROOT_HASH` where `hash()` would fail. + trie.rootHash.valueOr: EMPTY_ROOT_HASH # ------------------------------------------------------------------------------ # Public Merkle Patricia Tree, hexary trie constructors # ------------------------------------------------------------------------------ -proc newMpt*( - db: CoreDbRef; +proc getMpt*( + ctx: CoreDbCtxRef; trie: CoreDbTrieRef; prune = true; ): CoreDbRc[CoreDxMptRef] = - ## MPT sub-trie object incarnation. The argument `prune` is currently - ## ignored on other than the legacy backend. The legacy backend always - ## assumes `AutoSave` mode regardless of the function argument. + ## Get an MPT sub-trie view. The argument `prune` is currently ignored on + ## other than the legacy backend. ## - ## If the `trie` argument was created for an `EMPTY_ROOT_HASH` sub-trie, the - ## sub-trie database will be flushed. There is no need to keep the `trie` - ## argument. It can always be rerieved for this particular incarnation unsing - ## the function `getTrie()` on this MPT. + ## If the `trie` argument was created for an `EMPTY_ROOT_HASH` sub-trie, + ## the sub-trie will be flushed. There is no need to hold the `trie` + ## argument for later use. It can always be rerieved for this particular + ## view using the function `getTrie()`. ## - db.setTrackNewApi BaseNewMptFn - result = db.methods.newMptFn(trie, prune) - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, trie, prune, result + ctx.setTrackNewApi CtxGetMptFn + result = ctx.methods.getMptFn(trie, prune) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, trie, prune, result -proc newMpt*( - db: CoreDbRef; +proc getMpt*( + ctx: CoreDbCtxRef; kind: CoreDbSubTrie; address = none(EthAddress); prune = true; ): CoreDxMptRef = - ## Shortcut for `newMpt(trie,prune)` where the `trie` argument is + ## Shortcut for `getMpt(trie,prune)` where the `trie` argument is ## `db.getTrie(kind,EMPTY_ROOT_HASH).value`. This function will always ## return a non-nil descriptor or throw an exception. ## - db.setTrackNewApi BaseNewMptFn - let trie = db.methods.getTrieFn(kind, EMPTY_ROOT_HASH, address).value - result = db.methods.newMptFn(trie, prune).valueOr: + ctx.setTrackNewApi CtxGetMptFn + let trie = ctx.methods.newTrieFn(kind, EMPTY_ROOT_HASH, address).value + result = ctx.methods.getMptFn(trie, prune).valueOr: raiseAssert error.prettyText() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prune + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, prune -proc newMpt*(acc: CoreDxAccRef): CoreDxMptRef = - ## Constructor, will defect on failure. +proc getMpt*(acc: CoreDxAccRef): CoreDxMptRef = + ## Variant of `getMpt()`, will defect on failure. ## - ## Variant of `newMpt()` where the input arguments are taken from the - ## current `acc` descriptor settings. + ## The needed sub-trie information is taken/implied from the current `acc` + ## argument. ## acc.setTrackNewApi AccToMptFn - result = acc.methods.newMptFn().valueOr: + result = acc.methods.getMptFn().valueOr: raiseAssert error.prettyText() acc.ifTrackNewApi: let root = result.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, root + debug newApiTxt, api, elapsed, root -proc newAccMpt*( - db: CoreDbRef; +proc getAccMpt*( + ctx: CoreDbCtxRef; trie: CoreDbTrieRef; prune = true; ): CoreDbRc[CoreDxAccRef] = @@ -599,52 +607,53 @@ proc newAccMpt*( ## ... # No node with ## return ## - ## let acc = db.newAccMpt(trie) + ## let acc = db.getAccMpt(trie) ## ... # Was not the state root for the accounts sub-trie ## return ## - ## This function works similar to `newMpt()` for handling accounts. Although - ## this sub-trie can be emulated by means of `newMpt(..).toPhk()`, it is + ## This function works similar to `getMpt()` for handling accounts. Although + ## this sub-trie can be emulated by means of `getMpt(..).toPhk()`, it is ## recommended using this particular constructor for accounts because it ## provides its own subset of methods to handle accounts. ## - db.setTrackNewApi BaseNewAccFn - result = db.methods.newAccFn(trie, prune) - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, trie, prune, result + ctx.setTrackNewApi CtxGetAccMptFn + result = ctx.methods.getAccFn(trie, prune) + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, trie, prune, result -proc newAccMpt*( - db: CoreDbRef; +proc getAccMpt*( + ctx: CoreDbCtxRef; root = EMPTY_ROOT_HASH; prune = true; ): CoreDxAccRef = - ## Simplified version of `newAccMpt()` where the `CoreDbTrieRef` argument is + ## Simplified version of `getAccMpt()` where the `CoreDbTrieRef` argument is ## replaced by a `root` hash argument. This function is sort of a shortcut ## for: ## :: ## let trie = db.getTrie(AccountsTrie, root).value - ## result = db.newAccMpt(trie, prune).value + ## result = db.getAccMpt(trie, prune).value ## ## and will throw an exception if something goes wrong. The result reference ## will alwye be non `nil`. ## - db.setTrackNewApi BaseNewAccFn - let trie = db.methods.getTrieFn(AccountsTrie, root, none(EthAddress)).valueOr: + ctx.setTrackNewApi CtxGetAccMptFn + let trie = ctx.methods.newTrieFn( + AccountsTrie, root, none(EthAddress)).valueOr: raiseAssert error.prettyText() - result = db.methods.newAccFn(trie, prune).valueOr: + result = ctx.methods.getAccFn(trie, prune).valueOr: raiseAssert error.prettyText() - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prune + ctx.ifTrackNewApi: debug newApiTxt, api, elapsed, prune 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()`. + ## `getAccMpt()`. ## phk.setTrackNewApi PhkToMptFn result = phk.fromMpt phk.ifTrackNewApi: let trie = result.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie + debug newApiTxt, api, elapsed, trie proc toPhk*(mpt: CoreDxMptRef): CoreDxPhkRef = ## Replaces argument `mpt` by a pre-hashed *MPT*. @@ -655,7 +664,7 @@ proc toPhk*(mpt: CoreDxMptRef): CoreDxPhkRef = result = mpt.toCoreDxPhkRef mpt.ifTrackNewApi: let trie = result.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie + debug newApiTxt, api, elapsed, trie # ------------------------------------------------------------------------------ # Public common methods for all hexary trie databases (`mpt`, `phk`, or `acc`) @@ -666,7 +675,7 @@ proc isPruning*(dsc: CoreDxTrieRefs): bool = ## dsc.setTrackNewApi AnyIsPruningFn result = dsc.methods.isPruningFn() - dsc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + dsc.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc getTrie*(acc: CoreDxAccRef): CoreDbTrieRef = @@ -674,19 +683,19 @@ proc getTrie*(acc: CoreDxAccRef): CoreDbTrieRef = ## acc.setTrackNewApi AccGetTrieFn result = acc.methods.getTrieFn() - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + acc.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc getTrie*(mpt: CoreDxMptRef): CoreDbTrieRef = ## Variant of `getTrie()` mpt.setTrackNewApi MptGetTrieFn result = mpt.methods.getTrieFn() - mpt.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + mpt.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc getTrie*(phk: CoreDxPhkRef): CoreDbTrieRef = ## Variant of `getTrie()` phk.setTrackNewApi PhkGetTrieFn result = phk.methods.getTrieFn() - phk.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + phk.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc persistent*(acc: CoreDxAccRef): CoreDbRc[void] = @@ -705,7 +714,7 @@ proc persistent*(acc: CoreDxAccRef): CoreDbRc[void] = ## acc.setTrackNewApi AccPersistentFn result = acc.methods.persistentFn() - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + acc.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc persistent*(mpt: CoreDxMptRef): CoreDbRc[void] {.discardable.} = ## Variant of `persistent()` @@ -713,7 +722,7 @@ proc persistent*(mpt: CoreDxMptRef): CoreDbRc[void] {.discardable.} = result = mpt.methods.persistentFn() mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, result + debug newApiTxt, api, elapsed, trie, result proc persistent*(phk: CoreDxPhkRef): CoreDbRc[void] {.discardable.} = ## Variant of `persistent()` @@ -721,37 +730,7 @@ proc persistent*(phk: CoreDxPhkRef): CoreDbRc[void] {.discardable.} = result = phk.methods.persistentFn() phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, result - - -proc forget*(acc: CoreDxAccRef): CoreDbRc[void] {.discardable.} = - ## For the legacy database, this function has no effect and succeeds always. - ## - ## This function destroys the current descriptor without any further action - ## regardless of the save/share mode assigned to the constructor. - ## - ## See the discussion at `forget()` for a `CoreDxKvtRef` type argument - ## descriptor an explanation of how this function works. - ## - acc.setTrackNewApi AccForgetFn - result = acc.methods.forgetFn() - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result - -proc forget*(mpt: CoreDxMptRef): CoreDbRc[void] {.discardable.} = - ## Variant of `forget()` - mpt.setTrackNewApi MptForgetFn - result = mpt.methods.forgetFn() - mpt.ifTrackNewApi: - let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, result - -proc forget*(phk: CoreDxPhkRef): CoreDbRc[void] {.discardable.} = - ## Variant of `forget()` - phk.setTrackNewApi PhkForgetFn - result = phk.methods.forgetFn() - phk.ifTrackNewApi: - let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, result + debug newApiTxt, api, elapsed, trie, result # ------------------------------------------------------------------------------ # Public generic hexary trie database methods (`mpt` or `phk`) @@ -765,7 +744,7 @@ proc fetch*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[Blob] = result = mpt.methods.fetchFn key mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc fetch*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[Blob] = ## Variant of `fetch()" @@ -773,7 +752,7 @@ proc fetch*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[Blob] = result = phk.methods.fetchFn key phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc fetchOrEmpty*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[Blob] = @@ -786,7 +765,7 @@ proc fetchOrEmpty*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[Blob] = result = CoreDbRc[Blob].ok(EmptyBlob) mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc fetchOrEmpty*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[Blob] = ## Variant of `fetchOrEmpty()` @@ -796,7 +775,7 @@ proc fetchOrEmpty*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[Blob] = result = CoreDbRc[Blob].ok(EmptyBlob) phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc delete*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[void] = @@ -804,14 +783,14 @@ proc delete*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[void] = result = mpt.methods.deleteFn key mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc delete*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[void] = phk.setTrackNewApi PhkDeleteFn result = phk.methods.deleteFn key phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc merge*( @@ -823,7 +802,7 @@ proc merge*( result = mpt.methods.mergeFn(key, val) mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, val=val.toLenStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, val=val.toLenStr, result proc merge*( phk: CoreDxPhkRef; @@ -834,7 +813,7 @@ proc merge*( result = phk.methods.mergeFn(key, val) phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, val=val.toLenStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, val=val.toLenStr, result proc hasPath*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[bool] = @@ -845,7 +824,7 @@ proc hasPath*(mpt: CoreDxMptRef; key: openArray[byte]): CoreDbRc[bool] = result = mpt.methods.hasPathFn key mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result proc hasPath*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[bool] = ## Variant of `hasPath()` @@ -853,7 +832,7 @@ proc hasPath*(phk: CoreDxPhkRef; key: openArray[byte]): CoreDbRc[bool] = result = phk.methods.hasPathFn key phk.ifTrackNewApi: let trie = phk.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie, key=key.toStr, result + debug newApiTxt, api, elapsed, trie, key=key.toStr, result # ------------------------------------------------------------------------------ # Public trie database methods for accounts @@ -866,27 +845,29 @@ proc fetch*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[CoreDbAccount] = result = acc.methods.fetchFn address acc.ifTrackNewApi: let stoTrie = if result.isErr: "n/a" else: result.value.stoTrie.prettyText() - debug newApiTxt, ctx, elapsed, address, stoTrie, result + debug newApiTxt, api, elapsed, address, stoTrie, result + proc delete*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[void] = acc.setTrackNewApi AccDeleteFn result = acc.methods.deleteFn address - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, address, result + acc.ifTrackNewApi: debug newApiTxt, api, elapsed, address, result proc stoFlush*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[void] = ## Recursively delete all data elements from the storage trie associated to ## the account identified by the argument `address`. After successful run, ## the storage trie will be empty. ## - ## caveat: - ## This function has currently no effect on the legacy backend so it must - ## not be relied upon in general. On the legacy backend, storage tries - ## might be shared by several accounts whereas they are unique on the - ## `Aristo` backend. + ## Caveat: + ## This function has no effect on the legacy backend so it must not be + ## relied upon in general. On the legacy backend, storage tries might be + ## shared by several accounts whereas they are unique on the `Aristo` + ## backend. ## acc.setTrackNewApi AccStoFlushFn result = acc.methods.stoFlushFn address - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, address, result + acc.ifTrackNewApi: debug newApiTxt, api, elapsed, address, result + proc merge*( acc: CoreDxAccRef; @@ -896,14 +877,40 @@ proc merge*( result = acc.methods.mergeFn account acc.ifTrackNewApi: let address = account.address - debug newApiTxt, ctx, elapsed, address, result + debug newApiTxt, api, elapsed, address, result + proc hasPath*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[bool] = ## Would be named `contains` if it returned `bool` rather than `Result[]`. ## acc.setTrackNewApi AccHasPathFn result = acc.methods.hasPathFn address - acc.ifTrackNewApi: debug newApiTxt, ctx, elapsed, address, result + acc.ifTrackNewApi: debug newApiTxt, api, elapsed, address, result + + +proc recast*(statement: CoreDbAccount): CoreDbRc[Account] = + ## Convert the argument `statement` to the portable Ethereum representation + ## of an account statement. This conversion may fail if the storage root + ## hash (see `hash()` above) is currently unavailable. + ## + ## Note: + ## With the legacy backend, this function always succeeds. + ## + let stoTrie = statement.stoTrie + stoTrie.setTrackNewApi EthAccRecastFn + let rc = + if stoTrie.isNil or not stoTrie.ready: CoreDbRc[Hash256].ok(EMPTY_ROOT_HASH) + else: stoTrie.parent.methods.rootHashFn stoTrie + result = + if rc.isOk: + ok Account( + nonce: statement.nonce, + balance: statement.balance, + codeHash: statement.codeHash, + storageRoot: rc.value) + else: + err(rc.error) + stoTrie.ifTrackNewApi: debug newApiTxt, api, elapsed, stoTrie, result # ------------------------------------------------------------------------------ # Public transaction related methods @@ -915,38 +922,38 @@ proc newTransaction*(db: CoreDbRef): CoreDbRc[CoreDxTxRef] = db.setTrackNewApi BaseNewTxFn result = db.methods.beginFn() db.ifTrackNewApi: - debug newApiTxt, ctx, elapsed, newLevel=db.methods.levelFn(), result + debug newApiTxt, api, elapsed, newLevel=db.methods.levelFn(), result proc level*(tx: CoreDxTxRef): int = ## Print positive argument `tx` transaction level ## tx.setTrackNewApi TxLevelFn result = tx.methods.levelFn() - tx.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + tx.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc commit*(tx: CoreDxTxRef, applyDeletes = true): CoreDbRc[void] = tx.setTrackNewApi TxCommitFn: let prvLevel {.used.} = tx.methods.levelFn() result = tx.methods.commitFn applyDeletes - tx.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prvLevel, result + tx.ifTrackNewApi: debug newApiTxt, api, elapsed, prvLevel, result proc rollback*(tx: CoreDxTxRef): CoreDbRc[void] = tx.setTrackNewApi TxRollbackFn: let prvLevel {.used.} = tx.methods.levelFn() result = tx.methods.rollbackFn() - tx.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prvLevel, result + tx.ifTrackNewApi: debug newApiTxt, api, elapsed, prvLevel, result proc dispose*(tx: CoreDxTxRef): CoreDbRc[void] = tx.setTrackNewApi TxDisposeFn: let prvLevel {.used.} = tx.methods.levelFn() result = tx.methods.disposeFn() - tx.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prvLevel, result + tx.ifTrackNewApi: debug newApiTxt, api, elapsed, prvLevel, result proc safeDispose*(tx: CoreDxTxRef): CoreDbRc[void] = tx.setTrackNewApi TxSaveDisposeFn: let prvLevel {.used.} = tx.methods.levelFn() result = tx.methods.safeDisposeFn() - tx.ifTrackNewApi: debug newApiTxt, ctx, elapsed, prvLevel, result + tx.ifTrackNewApi: debug newApiTxt, api, elapsed, prvLevel, result # ------------------------------------------------------------------------------ # Public tracer methods @@ -969,7 +976,7 @@ proc newCapture*( ## db.setTrackNewApi BaseNewCaptureFn result = db.methods.newCaptureFn flags - db.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + db.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc recorder*(cpt: CoreDxCaptRef): CoreDbRef = ## Getter, returns a tracer replacement handle to be used as new database. @@ -984,7 +991,7 @@ proc recorder*(cpt: CoreDxCaptRef): CoreDbRef = ## cpt.setTrackNewApi CptRecorderFn result = cpt.methods.recorderFn() - cpt.ifTrackNewApi: debug newApiTxt, ctx, elapsed + cpt.ifTrackNewApi: debug newApiTxt, api, elapsed proc logDb*(cp: CoreDxCaptRef): TableRef[Blob,Blob] = ## Getter, returns the logger table for the overlay tracer database. @@ -996,13 +1003,13 @@ proc logDb*(cp: CoreDxCaptRef): TableRef[Blob,Blob] = ## cp.setTrackNewApi CptLogDbFn result = cp.methods.logDbFn() - cp.ifTrackNewApi: debug newApiTxt, ctx, elapsed + cp.ifTrackNewApi: debug newApiTxt, api, elapsed proc flags*(cp: CoreDxCaptRef):set[CoreDbCaptFlags] = ## Getter cp.setTrackNewApi CptFlagsFn result = cp.methods.getFlagsFn() - cp.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + cp.ifTrackNewApi: debug newApiTxt, api, elapsed, result proc forget*(cp: CoreDxCaptRef): CoreDbRc[void] = ## Explicitely stop recording the current tracer instance. If this call was @@ -1013,7 +1020,7 @@ proc forget*(cp: CoreDxCaptRef): CoreDbRc[void] = ## cp.setTrackNewApi CptForgetFn result = cp.methods.forgetFn() - cp.ifTrackNewApi: debug newApiTxt, ctx, elapsed, result + cp.ifTrackNewApi: debug newApiTxt, api, elapsed, result # ------------------------------------------------------------------------------ # Public methods, legacy API @@ -1028,7 +1035,7 @@ when ProvideLegacyAPI: proc backend*(dsc: CoreDbChldRefs): auto = dsc.setTrackLegaApi LegaBackendFn result = dsc.distinctBase.backend - dsc.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + dsc.ifTrackLegaApi: debug legaApiTxt, api, elapsed # ---------------- @@ -1036,201 +1043,174 @@ when ProvideLegacyAPI: ## Legacy pseudo constructor, see `toKvt()` for production constructor db.setTrackLegaApi LegaNewKvtFn result = db.newKvt().CoreDbKvtRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, result + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed, result proc get*(kvt: CoreDbKvtRef; key: openArray[byte]): Blob = kvt.setTrackLegaApi LegaKvtGetFn - result = kvt.distinctBase.getOrEmpty(key).expect $ctx - kvt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr, result + result = kvt.distinctBase.getOrEmpty(key).expect $api + kvt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr, result proc del*(kvt: CoreDbKvtRef; key: openArray[byte]): void = kvt.setTrackLegaApi LegaKvtDelFn - kvt.distinctBase.del(key).expect $ctx - kvt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr + kvt.distinctBase.del(key).expect $api + kvt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr proc put*(kvt: CoreDbKvtRef; key: openArray[byte]; val: openArray[byte]) = kvt.setTrackLegaApi LegaKvtPutFn - kvt.distinctBase.parent.newKvt().put(key, val).expect $ctx + kvt.distinctBase.parent.newKvt().put(key, val).expect $api kvt.ifTrackLegaApi: - debug legaApiTxt, ctx, elapsed, key=key.toStr, val=val.toLenStr + debug legaApiTxt, api, elapsed, key=key.toStr, val=val.toLenStr proc contains*(kvt: CoreDbKvtRef; key: openArray[byte]): bool = kvt.setTrackLegaApi LegaKvtContainsFn - result = kvt.distinctBase.hasKey(key).expect $ctx - kvt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr, result + result = kvt.distinctBase.hasKey(key).expect $api + kvt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr, result # ---------------- proc toMpt*(phk: CoreDbPhkRef): CoreDbMptRef = phk.setTrackLegaApi LegaToMptFn result = phk.distinctBase.toMpt.CoreDbMptRef - phk.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + phk.ifTrackLegaApi: debug legaApiTxt, api, elapsed proc mptPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbMptRef = db.setTrackLegaApi LegaNewMptFn let - trie = db.methods.getTrieFn(GenericTrie, root, none(EthAddress)).valueOr: - raiseAssert error.prettyText() & ": " & $ctx - mpt = db.newMpt(trie, prune).valueOr: - raiseAssert error.prettyText() & ": " & $ctx + trie = db.ctx.methods.newTrieFn( + GenericTrie, root, none(EthAddress)).valueOr: + raiseAssert error.prettyText() & ": " & $api + mpt = db.ctx.getMpt(trie, prune).valueOr: + raiseAssert error.prettyText() & ": " & $api result = mpt.CoreDbMptRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, root, prune + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed, root, prune proc mptPrune*(db: CoreDbRef; prune = true): CoreDbMptRef = db.setTrackLegaApi LegaNewMptFn - result = db.newMpt(GenericTrie, none(EthAddress), prune).CoreDbMptRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prune + result = db.ctx.getMpt(GenericTrie, none(EthAddress), prune).CoreDbMptRef + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prune # ---------------- proc toPhk*(mpt: CoreDbMptRef): CoreDbPhkRef = mpt.setTrackLegaApi LegaToPhkFn result = mpt.distinctBase.toPhk.CoreDbPhkRef - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed proc phkPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbPhkRef = db.setTrackLegaApi LegaNewPhkFn let - trie = db.methods.getTrieFn(GenericTrie, root, none(EthAddress)).valueOr: - raiseAssert error.prettyText() & ": " & $ctx - phk = db.newMpt(trie, prune).valueOr: - raiseAssert error.prettyText() & ": " & $ctx + trie = db.ctx.methods.newTrieFn( + GenericTrie, root, none(EthAddress)).valueOr: + raiseAssert error.prettyText() & ": " & $api + phk = db.ctx.getMpt(trie, prune).valueOr: + raiseAssert error.prettyText() & ": " & $api result = phk.toCoreDxPhkRef.CoreDbPhkRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, root, prune + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed, root, prune proc phkPrune*(db: CoreDbRef; prune = true): CoreDbPhkRef = db.setTrackLegaApi LegaNewPhkFn - result = db.newMpt( + result = db.ctx.getMpt( GenericTrie, none(EthAddress), prune).toCoreDxPhkRef.CoreDbPhkRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prune + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prune # ---------------- proc isPruning*(trie: CoreDbTrieRefs): bool = trie.setTrackLegaApi LegaIsPruningFn result = trie.distinctBase.isPruning() - trie.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, result + trie.ifTrackLegaApi: debug legaApiTxt, api, elapsed, result proc get*(mpt: CoreDbMptRef; key: openArray[byte]): Blob = mpt.setTrackLegaApi LegaMptGetFn - result = mpt.distinctBase.fetchOrEmpty(key).expect $ctx - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr, result + result = mpt.distinctBase.fetchOrEmpty(key).expect $api + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr, result proc get*(phk: CoreDbPhkRef; key: openArray[byte]): Blob = phk.setTrackLegaApi LegaPhkGetFn - result = phk.distinctBase.fetchOrEmpty(key).expect $ctx + result = phk.distinctBase.fetchOrEmpty(key).expect $api phk.ifTrackLegaApi: - debug legaApiTxt, ctx, elapsed, key=key.toStr, result + debug legaApiTxt, api, elapsed, key=key.toStr, result proc del*(mpt: CoreDbMptRef; key: openArray[byte]) = mpt.setTrackLegaApi LegaMptDelFn - mpt.distinctBase.delete(key).expect $ctx - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr + mpt.distinctBase.delete(key).expect $api + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr proc del*(phk: CoreDbPhkRef; key: openArray[byte]) = phk.setTrackLegaApi LegaPhkDelFn - phk.distinctBase.delete(key).expect $ctx - phk.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr + phk.distinctBase.delete(key).expect $api + phk.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr proc put*(mpt: CoreDbMptRef; key: openArray[byte]; val: openArray[byte]) = mpt.setTrackLegaApi LegaMptPutFn - mpt.distinctBase.merge(key, val).expect $ctx + mpt.distinctBase.merge(key, val).expect $api mpt.ifTrackLegaApi: - debug legaApiTxt, ctx, elapsed, key=key.toStr, val=val.toLenStr + debug legaApiTxt, api, elapsed, key=key.toStr, val=val.toLenStr proc put*(phk: CoreDbPhkRef; key: openArray[byte]; val: openArray[byte]) = phk.setTrackLegaApi LegaPhkPutFn - phk.distinctBase.merge(key, val).expect $ctx + phk.distinctBase.merge(key, val).expect $api phk.ifTrackLegaApi: - debug legaApiTxt, ctx, elapsed, key=key.toStr, val=val.toLenStr + debug legaApiTxt, api, elapsed, key=key.toStr, val=val.toLenStr proc contains*(mpt: CoreDbMptRef; key: openArray[byte]): bool = mpt.setTrackLegaApi LegaMptContainsFn - result = mpt.distinctBase.hasPath(key).expect $ctx - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr, result + result = mpt.distinctBase.hasPath(key).expect $api + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr, result proc contains*(phk: CoreDbPhkRef; key: openArray[byte]): bool = phk.setTrackLegaApi LegaPhkContainsFn - result = phk.distinctBase.hasPath(key).expect $ctx - phk.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, key=key.toStr, result + result = phk.distinctBase.hasPath(key).expect $api + phk.ifTrackLegaApi: debug legaApiTxt, api, elapsed, key=key.toStr, result proc rootHash*(mpt: CoreDbMptRef): Hash256 = mpt.setTrackLegaApi LegaMptRootHashFn result = mpt.distinctBase.methods.getTrieFn().rootHash.valueOr: - raiseAssert error.prettyText() & ": " & $ctx - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, result + raiseAssert error.prettyText() & ": " & $api + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed, result proc rootHash*(phk: CoreDbPhkRef): Hash256 = phk.setTrackLegaApi LegaPhkRootHashFn result = phk.distinctBase.methods.getTrieFn().rootHash.valueOr: - raiseAssert error.prettyText() & ": " & $ctx - phk.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, result + raiseAssert error.prettyText() & ": " & $api + phk.ifTrackLegaApi: debug legaApiTxt, api, elapsed, result # ---------------- - proc getTransactionID*(db: CoreDbRef): CoreDbTxID = - db.setTrackLegaApi LegaGetTxIdFn - result = db.methods.getIdFn().expect($ctx).CoreDbTxID - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed - - proc shortTimeReadOnly*( - id: CoreDbTxID; - action: proc() {.catchRaise.}; - ) {.catchRaise.} = - id.setTrackLegaApi LegaShortTimeRoFn - var oops = none(ref CatchableError) - proc safeFn() = - try: - action() - except CatchableError as e: - oops = some(e) - # Action has finished now - - id.distinctBase.methods.roWrapperFn(safeFn).expect $ctx - - # Delayed exception - if oops.isSome: - let - e = oops.unsafeGet - msg = "delayed and reraised" & - ", name=" & $e.name & ", msg=\"" & e.msg & "\"" - raise (ref TxWrapperApiError)(msg: msg) - id.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed - proc beginTransaction*(db: CoreDbRef): CoreDbTxRef = db.setTrackLegaApi LegaBeginTxFn - result = (db.distinctBase.methods.beginFn().expect $ctx).CoreDbTxRef + result = (db.distinctBase.methods.beginFn().expect $api).CoreDbTxRef db.ifTrackLegaApi: - debug legaApiTxt, ctx, elapsed, newLevel=db.methods.levelFn() + debug legaApiTxt, api, elapsed, newLevel=db.methods.levelFn() proc commit*(tx: CoreDbTxRef, applyDeletes = true) = tx.setTrackLegaApi LegaTxCommitFn: let prvLevel {.used.} = tx.distinctBase.methods.levelFn() - tx.distinctBase.commit(applyDeletes).expect $ctx - tx.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prvLevel + tx.distinctBase.commit(applyDeletes).expect $api + tx.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prvLevel proc rollback*(tx: CoreDbTxRef) = tx.setTrackLegaApi LegaTxCommitFn: let prvLevel {.used.} = tx.distinctBase.methods.levelFn() - tx.distinctBase.rollback().expect $ctx - tx.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prvLevel + tx.distinctBase.rollback().expect $api + tx.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prvLevel proc dispose*(tx: CoreDbTxRef) = tx.setTrackLegaApi LegaTxDisposeFn: let prvLevel {.used.} = tx.distinctBase.methods.levelFn() - tx.distinctBase.dispose().expect $ctx - tx.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prvLevel + tx.distinctBase.dispose().expect $api + tx.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prvLevel proc safeDispose*(tx: CoreDbTxRef) = tx.setTrackLegaApi LegaTxSaveDisposeFn: let prvLevel {.used.} = tx.distinctBase.methods.levelFn() - tx.distinctBase.safeDispose().expect $ctx - tx.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, prvLevel + tx.distinctBase.safeDispose().expect $api + tx.ifTrackLegaApi: debug legaApiTxt, api, elapsed, prvLevel # ---------------- @@ -1239,23 +1219,23 @@ when ProvideLegacyAPI: flags: set[CoreDbCaptFlags] = {}; ): CoreDbCaptRef = db.setTrackLegaApi LegaCaptureFn - result = db.newCapture(flags).expect($ctx).CoreDbCaptRef - db.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + result = db.newCapture(flags).expect($api).CoreDbCaptRef + db.ifTrackLegaApi: debug legaApiTxt, api, elapsed proc recorder*(cp: CoreDbCaptRef): CoreDbRef = cp.setTrackLegaApi LegaCptRecorderFn result = cp.distinctBase.recorder() - cp.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + cp.ifTrackLegaApi: debug legaApiTxt, api, elapsed proc logDb*(cp: CoreDbCaptRef): TableRef[Blob,Blob] = cp.setTrackLegaApi LegaCptLogDbFn result = cp.distinctBase.logDb() - cp.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + cp.ifTrackLegaApi: debug legaApiTxt, api, elapsed proc flags*(cp: CoreDbCaptRef): set[CoreDbCaptFlags] = cp.setTrackLegaApi LegaCptFlagsFn result = cp.distinctBase.flags() - cp.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed, result + cp.ifTrackLegaApi: debug legaApiTxt, api, elapsed, result # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/core_db/base/api_legacy_desc.nim b/nimbus/db/core_db/base/api_legacy_desc.nim index e4333aeb3..3add7b930 100644 --- a/nimbus/db/core_db/base/api_legacy_desc.nim +++ b/nimbus/db/core_db/base/api_legacy_desc.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2023-2024 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) @@ -22,14 +22,12 @@ type CoreDbMptRef* = distinct CoreDxMptRef CoreDbPhkRef* = distinct CoreDxPhkRef CoreDbTxRef* = distinct CoreDxTxRef - CoreDbTxID* = distinct CoreDxTxID CoreDbCaptRef* = distinct CoreDxCaptRef CoreDbTrieRefs* = CoreDbMptRef | CoreDbPhkRef ## Shortcut, *MPT* modules for (legacy API) - CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbTxID | - CoreDbCaptRef + CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbCaptRef ## Shortcut, all modules with a `parent` entry (for legacy API) # End diff --git a/nimbus/db/core_db/base/api_new_desc.nim b/nimbus/db/core_db/base/api_new_desc.nim index 2b2c879a8..2c48045fb 100644 --- a/nimbus/db/core_db/base/api_new_desc.nim +++ b/nimbus/db/core_db/base/api_new_desc.nim @@ -14,10 +14,10 @@ import ./base_desc type - CoreDxTrieRefs* = CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef + CoreDxTrieRefs* = CoreDbCtxRef | CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef ## Shortcut, *MPT* descriptors - CoreDxTrieRelated* = CoreDxTrieRefs | CoreDxTxRef | CoreDxTxID | CoreDxCaptRef + CoreDxTrieRelated* = CoreDxTrieRefs | CoreDxTxRef | CoreDxCaptRef ## Shortcut, descriptors for sub-modules running on an *MPT* CoreDbBackends* = CoreDbBackendRef | CoreDbKvtBackendRef | diff --git a/nimbus/db/core_db/base/api_tracking.nim b/nimbus/db/core_db/base/api_tracking.nim index 058d654d6..015bcd4d1 100644 --- a/nimbus/db/core_db/base/api_tracking.nim +++ b/nimbus/db/core_db/base/api_tracking.nim @@ -32,7 +32,7 @@ type AccGetTrieFn = "acc/getTrie" AccHasPathFn = "acc/hasPath" AccMergeFn = "acc/merge" - AccNewMptFn = "acc/newMpt" + AccGetMptFn = "acc/getMpt" AccPersistentFn = "acc/persistent" AccStoFlushFn = "acc/stoFlush" AccToMptFn = "acc/toMpt" @@ -42,13 +42,11 @@ type BaseDbTypeFn = "dbType" BaseFinishFn = "finish" - BaseGetTrieFn = "getTrie" + BaseGetCtxFn = "ctx" BaseLegacySetupFn = "compensateLegacySetup" BaseLevelFn = "level" - BaseNewAccFn = "newAccMpt" BaseNewCaptureFn = "newCapture" BaseNewKvtFn = "newKvt" - BaseNewMptFn = "newMpt" BaseNewTxFn = "newTransaction" CptFlagsFn = "cpt/flags" @@ -56,6 +54,14 @@ type CptRecorderFn = "cpt/recorder" CptForgetFn = "cpt/forget" + CtxForgetFn = "ctx/forget" + CtxFromTxFn = "ctx/fromTx" + CtxGetAccFn = "ctx/getAcc" + CtxGetAccMptFn = "ctx/getAccMpt" + CtxGetMptFn = "ctx/getMpt" + CtxNewTrieFn = "ctx/newTrie" + CtxSwapFn = "ctx/swap" + ErrorPrintFn = "$$" EthAccRecastFn = "recast" @@ -74,7 +80,6 @@ type LegaCptFlagsFn = "cpt/flags" LegaCptLogDbFn = "cpt/logDb" LegaCptRecorderFn = "cpt/recorder" - LegaGetTxIdFn = "getTransactionID" LegaIsPruningFn = "trie/isPruning" LegaKvtContainsFn = "kvt/contains" @@ -101,7 +106,6 @@ type LegaPhkPutFn = "phk/put" LegaPhkRootHashFn = "phk/rootHash" - LegaShortTimeRoFn = "shortTimeReadOnly" LegaToMptFn = "phk/toMpt" LegaToPhkFn = "mpt/toPhk" @@ -210,9 +214,9 @@ proc toStr[T](rc: CoreDbRc[T]; ifOk: static[string]): string = proc toStr*(rc: CoreDbRc[CoreDbRef]): string = rc.toStr "db" proc toStr*(rc: CoreDbRc[CoreDbAccount]): string = rc.toStr "acc" proc toStr*(rc: CoreDbRc[CoreDxKvtRef]): string = rc.toStr "kvt" -proc toStr*(rc: CoreDbRc[CoreDxTxID]): string = rc.toStr "txId" proc toStr*(rc: CoreDbRc[CoreDxTxRef]): string = rc.toStr "tx" proc toStr*(rc: CoreDbRc[CoreDxCaptRef]): string = rc.toStr "capt" +proc toStr*(rc: CoreDbRc[CoreDbCtxRef]): string = rc.toStr "ctx" proc toStr*(rc: CoreDbRc[CoreDxMptRef]): string = rc.toStr "mpt" proc toStr*(rc: CoreDbRc[CoreDxAccRef]): string = rc.toStr "acc" diff --git a/nimbus/db/core_db/base/base_desc.nim b/nimbus/db/core_db/base/base_desc.nim index 6ee0667b9..8e33d8276 100644 --- a/nimbus/db/core_db/base/base_desc.nim +++ b/nimbus/db/core_db/base/base_desc.nim @@ -52,21 +52,23 @@ type CoreDbErrorCode* = enum Unset = 0 Unspecified - RlpException + + AccAddrMissing + AccNotFound + AccTxPending + AutoFlushFailed + CtxNotFound + HashNotAvailable KvtNotFound KvtTxPending MptNotFound MptTxPending - AccNotFound - AccAddrMissing - AccTxPending - RootNotFound - AutoFlushFailed - RootUnacceptable - HashNotAvailable - TrieLocked - StorageFailed NotImplemented + RlpException + RootNotFound + RootUnacceptable + StorageFailed + TrieLocked CoreDbSubTrie* = enum StorageTrie = 0 @@ -83,51 +85,38 @@ type # -------------------------------------------------- # Sub-descriptor: Misc methods for main descriptor # -------------------------------------------------- - CoreDbBaseVerifyFn* = proc(trie: CoreDbTrieRef): bool {.noRaise.} CoreDbBaseBackendFn* = proc(): CoreDbBackendRef {.noRaise.} CoreDbBaseDestroyFn* = proc(flush = true) {.noRaise.} - CoreDbBaseTryHashFn* = proc(vid: CoreDbTrieRef): CoreDbRc[Hash256] {.noRaise.} CoreDbBaseRootHashFn* = proc( trie: CoreDbTrieRef): CoreDbRc[Hash256] {.noRaise.} CoreDbBaseTriePrintFn* = proc(vid: CoreDbTrieRef): string {.noRaise.} CoreDbBaseErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.} CoreDbBaseInitLegaSetupFn* = proc() {.noRaise.} - CoreDbBaseGetTrieFn* = proc( - trie: CoreDbSubTrie; root: Hash256; address: Option[EthAddress]; - ): CoreDbRc[CoreDbTrieRef] {.noRaise.} CoreDbBaseLevelFn* = proc(): int {.noRaise.} - CoreDbBaseKvtFn* = proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] {.noRaise.} - CoreDbBaseMptFn* = proc( - root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.} - CoreDbBaseAccFn* = proc( - root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxAccRef] {.noRaise.} - CoreDbBaseTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.} + CoreDbBaseNewKvtFn* = + proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] {.noRaise.} + CoreDbBaseGetCtxFn* = proc(): CoreDbCtxRef {.noRaise.} CoreDbBaseTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.} CoreDbBaseNewCaptFn* = proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.} CoreDbBaseGetCaptFn* = proc(): CoreDbRc[CoreDxCaptRef] {.noRaise.} CoreDbBaseFns* = object - verifyFn*: CoreDbBaseVerifyFn backendFn*: CoreDbBaseBackendFn destroyFn*: CoreDbBaseDestroyFn - tryHashFn*: CoreDbBaseTryHashFn rootHashFn*: CoreDbBaseRootHashFn triePrintFn*: CoreDbBaseTriePrintFn errorPrintFn*: CoreDbBaseErrorPrintFn legacySetupFn*: CoreDbBaseInitLegaSetupFn - getTrieFn*: CoreDbBaseGetTrieFn levelFn*: CoreDbBaseLevelFn # Kvt constructor - newKvtFn*: CoreDbBaseKvtFn + newKvtFn*: CoreDbBaseNewKvtFn - # Hexary trie constructors - newMptFn*: CoreDbBaseMptFn - newAccFn*: CoreDbBaseAccFn + # MPT context constructor + getCtxFn*: CoreDbBaseGetCtxFn # Transactions constructors - getIdFn*: CoreDbBaseTxGetIdFn beginFn*: CoreDbBaseTxBeginFn # capture/tracer constructors @@ -156,6 +145,33 @@ type persistentFn*: CoreDbKvtPersistentFn forgetFn*: CoreDbKvtForgetFn + # -------------------------------------------------- + # Sub-descriptor: MPT context methods + # -------------------------------------------------- + CoreDbCtxFromTxFn* = + proc(root: Hash256; kind: CoreDbSubTrie): CoreDbRc[CoreDbCtxRef] {.noRaise.} + CoreDbCtxSwapFn* = proc(ctx: CoreDbCtxRef): CoreDbCtxRef {.noRaise.} + CoreDbCtxNewTrieFn* = proc( + trie: CoreDbSubTrie; root: Hash256; address: Option[EthAddress]; + ): CoreDbRc[CoreDbTrieRef] {.noRaise.} + CoreDbCtxGetMptFn* = proc( + root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.} + CoreDbCtxGetAccFn* = proc( + root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxAccRef] {.noRaise.} + CoreDbCtxForgetFn* = proc() {.noRaise.} + + CoreDbCtxFns* = object + ## Methods for context maniulation + fromTxFn*: CoreDbCtxFromTxFn + swapFn*: CoreDbCtxSwapFn + newTrieFn*: CoreDbCtxNewTrieFn + getMptFn*: CoreDbCtxGetMptFn + getAccFn*: CoreDbCtxGetAccFn + forgetFn*: CoreDbCtxForgetFn + + # -------------------------------------------------- + # Sub-descriptor: MPT context methods + # -------------------------------------------------- # -------------------------------------------------- # Sub-descriptor: generic Mpt/hexary trie methods @@ -187,13 +203,13 @@ type getTrieFn*: CoreDbMptGetTrieFn isPruningFn*: CoreDbMptIsPruningFn persistentFn*: CoreDbMptPersistentFn - forgetFn*: CoreDbMptForgetFn + # ---------------------------------------------------- # Sub-descriptor: Mpt/hexary trie methods for accounts # ------------------------------------------------------ CoreDbAccBackendFn* = proc(): CoreDbAccBackendRef {.noRaise.} - CoreDbAccNewMptFn* = proc(): CoreDbRc[CoreDxMptRef] {.noRaise.} + CoreDbAccGetMptFn* = proc(): CoreDbRc[CoreDxMptRef] {.noRaise.} CoreDbAccFetchFn* = proc(k: EthAddress): CoreDbRc[CoreDbAccount] {.noRaise.} CoreDbAccDeleteFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.} CoreDbAccStoFlushFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.} @@ -207,7 +223,7 @@ type CoreDbAccFns* = object ## Methods for trie objects backendFn*: CoreDbAccBackendFn - newMptFn*: CoreDbAccNewMptFn + getMptFn*: CoreDbAccGetMptFn fetchFn*: CoreDbAccFetchFn deleteFn*: CoreDbAccDeleteFn stoFlushFn*: CoreDbAccStoFlushFn @@ -216,7 +232,7 @@ type getTrieFn*: CoreDbAccGetTrieFn isPruningFn*: CoreDbAccIsPruningFn persistentFn*: CoreDbAccPersistentFn - forgetFn*: CoreDbAccForgetFn + # -------------------------------------------------- # Sub-descriptor: Transaction frame management @@ -234,16 +250,6 @@ type disposeFn*: CoreDbTxDisposeFn safeDisposeFn*: CoreDbTxSafeDisposeFn - # -------------------------------------------------- - # Sub-descriptor: Transaction ID management - # -------------------------------------------------- - CoreDbTxIdSetIdFn* = proc(): CoreDbRc[void] {.noRaise.} - CoreDbTxIdActionFn* = proc() {.noRaise.} - CoreDbTxIdRoWrapperFn* = - proc(action: CoreDbTxIdActionFn): CoreDbRc[void] {.noRaise.} - CoreDbTxIdFns* = object - roWrapperFn*: CoreDbTxIdRoWrapperFn - # -------------------------------------------------- # Sub-descriptor: capture recorder methods @@ -259,6 +265,7 @@ type getFlagsFn*: CoreDbCaptFlagsFn forgetFn*: CoreDbCaptForgetFn + # -------------------------------------------------- # Production descriptors # -------------------------------------------------- @@ -300,6 +307,11 @@ type parent*: CoreDbRef methods*: CoreDbKvtFns + CoreDbCtxRef* = ref object of RootRef + ## Context for `CoreDxMptRef` and `CoreDxAccRef` + parent*: CoreDbRef + methods*: CoreDbCtxFns + CoreDxMptRef* = ref object of RootRef ## Hexary/Merkle-Patricia tree derived from `CoreDbRef`, will be ## initialised on-the-fly. @@ -330,11 +342,6 @@ type parent*: CoreDbRef methods*: CoreDbTxFns - CoreDxTxID* = ref object - ## Transaction ID descriptor derived from `CoreDbRef` - parent*: CoreDbRef - methods*: CoreDbTxIdFns - CoreDxCaptRef* = ref object ## Db transaction tracer derived from `CoreDbRef` parent*: CoreDbRef diff --git a/nimbus/db/core_db/base/validate.nim b/nimbus/db/core_db/base/validate.nim index 099a6cba0..a2b5bdf9d 100644 --- a/nimbus/db/core_db/base/validate.nim +++ b/nimbus/db/core_db/base/validate.nim @@ -19,8 +19,8 @@ type MethodsDesc = CoreDxKvtRef | - CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef | - CoreDxTxRef | CoreDxTxID | + CoreDbCtxRef | CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef | + CoreDxTxRef | CoreDxCaptRef ValidateDesc* = MethodsDesc | EphemMethodsDesc | CoreDbErrorRef @@ -30,20 +30,15 @@ type # ------------------------------------------------------------------------------ proc validateMethodsDesc(base: CoreDbBaseFns) = - doAssert not base.verifyFn.isNil doAssert not base.backendFn.isNil doAssert not base.destroyFn.isNil - doAssert not base.tryHashFn.isNil doAssert not base.rootHashFn.isNil doAssert not base.triePrintFn.isNil doAssert not base.errorPrintFn.isNil doAssert not base.legacySetupFn.isNil - doAssert not base.getTrieFn.isNil doAssert not base.levelFn.isNil doAssert not base.newKvtFn.isNil - doAssert not base.newMptFn.isNil - doAssert not base.newAccFn.isNil - doAssert not base.getIdFn.isNil + doAssert not base.getCtxFn.isNil doAssert not base.beginFn.isNil doAssert not base.newCaptureFn.isNil @@ -53,8 +48,16 @@ proc validateMethodsDesc(kvt: CoreDbKvtFns) = doAssert not kvt.delFn.isNil doAssert not kvt.putFn.isNil doAssert not kvt.persistentFn.isNil - doAssert not kvt.forgetFn.isNil doAssert not kvt.hasKeyFn.isNil + doAssert not kvt.forgetFn.isNil + +proc validateMethodsDesc(ctx: CoreDbCtxFns) = + doAssert not ctx.fromTxFn.isNil + doAssert not ctx.swapFn.isNil + doAssert not ctx.newTrieFn.isNil + doAssert not ctx.getMptFn.isNil + doAssert not ctx.getAccFn.isNil + doAssert not ctx.forgetFn.isNil proc validateMethodsDesc(fns: CoreDbMptFns) = doAssert not fns.backendFn.isNil @@ -65,7 +68,6 @@ proc validateMethodsDesc(fns: CoreDbMptFns) = doAssert not fns.getTrieFn.isNil doAssert not fns.isPruningFn.isNil doAssert not fns.persistentFn.isNil - doAssert not fns.forgetFn.isNil proc validateMethodsDesc(fns: CoreDbAccFns) = doAssert not fns.backendFn.isNil @@ -78,7 +80,6 @@ proc validateMethodsDesc(fns: CoreDbAccFns) = doAssert not fns.getTrieFn.isNil doAssert not fns.isPruningFn.isNil doAssert not fns.persistentFn.isNil - doAssert not fns.forgetFn.isNil # ------------ @@ -101,6 +102,11 @@ proc validateMethodsDesc(kvt: CoreDxKvtRef) = doAssert not kvt.parent.isNil kvt.methods.validateMethodsDesc +proc validateMethodsDesc(ctx: CoreDbCtxRef) = + doAssert not ctx.isNil + doAssert not ctx.parent.isNil + ctx.methods.validateMethodsDesc + proc validateMethodsDesc(mpt: CoreDxMptRef) = doAssert not mpt.isNil doAssert not mpt.parent.isNil @@ -132,11 +138,6 @@ proc validateMethodsDesc(tx: CoreDxTxRef) = doAssert not tx.methods.disposeFn.isNil doAssert not tx.methods.safeDisposeFn.isNil -proc validateMethodsDesc(id: CoreDxTxID) = - doAssert not id.isNil - doAssert not id.parent.isNil - doAssert not id.methods.roWrapperFn.isNil - proc validateMethodsDesc(db: CoreDbRef) = doAssert not db.isNil doAssert db.dbType != CoreDbType(0) diff --git a/nimbus/db/core_db/base_iterators.nim b/nimbus/db/core_db/base_iterators.nim index 195f8a8cd..58f2da17b 100644 --- a/nimbus/db/core_db/base_iterators.nim +++ b/nimbus/db/core_db/base_iterators.nim @@ -52,7 +52,7 @@ iterator pairs*(kvt: CoreDxKvtRef): (Blob, Blob) {.apiRaise.} = yield (k,v) else: raiseAssert: "Unsupported database type: " & $kvt.parent.dbType - kvt.ifTrackNewApi: debug newApiTxt, ctx, elapsed + kvt.ifTrackNewApi: debug newApiTxt, api, elapsed iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = ## Trie traversal, only supported for `CoreDxMptRef` (not `Phk`) @@ -69,7 +69,7 @@ iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = raiseAssert: "Unsupported database type: " & $mpt.parent.dbType mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie + debug newApiTxt, api, elapsed, trie iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = ## Low level trie dump, only supported for `CoreDxMptRef` (not `Phk`) @@ -89,26 +89,26 @@ iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = raiseAssert: "Unsupported database type: " & $mpt.parent.dbType mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie + debug newApiTxt, api, elapsed, trie when ProvideLegacyAPI: iterator pairs*(kvt: CoreDbKvtRef): (Blob, Blob) {.apiRaise.} = kvt.setTrackLegaApi LegaKvtPairsIt for k,v in kvt.distinctBase.pairs(): yield (k,v) - kvt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + kvt.ifTrackLegaApi: debug legaApiTxt, api, elapsed iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} = ## Trie traversal, not supported for `CoreDbPhkRef` mpt.setTrackLegaApi LegaMptPairsIt for k,v in mpt.distinctBase.pairs(): yield (k,v) - mpt.ifTrackLegaApi: debug legaApiTxt, ctx + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed iterator replicate*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} = ## Low level trie dump, not supported for `CoreDbPhkRef` mpt.setTrackLegaApi LegaMptReplicateIt for k,v in mpt.distinctBase.replicate(): yield (k,v) - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/core_db/base_iterators_persistent.nim b/nimbus/db/core_db/base_iterators_persistent.nim index 6b3a06a04..d29c0c975 100644 --- a/nimbus/db/core_db/base_iterators_persistent.nim +++ b/nimbus/db/core_db/base_iterators_persistent.nim @@ -57,7 +57,7 @@ iterator replicatePersistent*(mpt: CoreDxMptRef): (Blob, Blob) {.rlpRaise.} = raiseAssert: "Unsupported database type: " & $mpt.parent.dbType mpt.ifTrackNewApi: let trie = mpt.methods.getTrieFn() - debug newApiTxt, ctx, elapsed, trie + debug newApiTxt, api, elapsed, trie when ProvideLegacyAPI: @@ -65,7 +65,7 @@ when ProvideLegacyAPI: ## Low level trie dump, not supported for `CoreDbPhkRef` mpt.setTrackLegaApi LegaMptReplicateIt for k,v in mpt.distinctBase.replicatePersistent(): yield (k,v) - mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed + mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/core_db/core_apps_newapi.nim b/nimbus/db/core_db/core_apps_newapi.nim index 4a756c384..f14ccb673 100644 --- a/nimbus/db/core_db/core_apps_newapi.nim +++ b/nimbus/db/core_db/core_apps_newapi.nim @@ -118,11 +118,12 @@ iterator getBlockTransactionData*( ): Blob = block body: let - trie = db.getTrie(TxTrie, transactionRoot).valueOr: + ctx = db.ctx + trie = ctx.newTrie(TxTrie, transactionRoot).valueOr: warn logTxt "getBlockTransactionData()", transactionRoot, action="getTrie()", `error`=($$error) break body - transactionDb = db.newMpt(trie).valueOr: + transactionDb = ctx.getMpt(trie).valueOr: warn logTxt "getBlockTransactionData()", transactionRoot, action="newMpt()", trie=($$trie), error=($$error) break body @@ -165,11 +166,12 @@ iterator getWithdrawalsData*( ): Blob = block body: let - trie = db.getTrie(WithdrawalsTrie, withdrawalsRoot).valueOr: + ctx = db.ctx + trie = ctx.newTrie(WithdrawalsTrie, withdrawalsRoot).valueOr: warn logTxt "getWithdrawalsData()", withdrawalsRoot, action="getTrie()", error=($$error) break body - wddb = db.newMpt(trie).valueOr: + wddb = ctx.getMpt(trie).valueOr: warn logTxt "getWithdrawalsData()", withdrawalsRoot, action="newMpt()", trie=($$trie), error=($$error) break body @@ -192,11 +194,12 @@ iterator getReceipts*( {.gcsafe, raises: [RlpError].} = block body: let - trie = db.getTrie(ReceiptsTrie, receiptRoot).valueOr: + ctx = db.ctx + trie = ctx.newTrie(ReceiptsTrie, receiptRoot).valueOr: warn logTxt "getWithdrawalsData()", receiptRoot, action="getTrie()", error=($$error) break body - receiptDb = db.newMpt(trie).valueOr: + receiptDb = ctx.getMpt(trie).valueOr: warn logTxt "getWithdrawalsData()", receiptRoot, action="newMpt()", trie=($$trie), error=($$error) break body @@ -469,7 +472,7 @@ proc setScore*(db: CoreDbRef; blockHash: Hash256, score: UInt256) = return proc getTd*(db: CoreDbRef; blockHash: Hash256, td: var UInt256): bool = - const info = "getId()" + const info = "getTd()" let bytes = db.newKvt() .get(blockHashToScoreKey(blockHash).toOpenArray).valueOr: if error.error != KvtNotFound: @@ -529,7 +532,7 @@ proc persistTransactions*( const info = "persistTransactions()" let - mpt = db.newMpt(TxTrie) + mpt = db.ctx.getMpt(TxTrie) kvt = db.newKvt() # Prevent DB from coughing. db.compensateLegacySetup() @@ -560,10 +563,11 @@ proc getTransaction*( const info = "getTransaction()" let - trie = db.getTrie(TxTrie, txRoot).valueOr: + ctx = db.ctx + trie = ctx.newTrie(TxTrie, txRoot).valueOr: warn logTxt info, txRoot, action="getTrie()", error=($$error) return false - mpt = db.newMpt(trie).valueOr: + mpt = ctx.getMpt(trie).valueOr: warn logTxt info, txRoot, action="newMpt()", trie=($$trie), error=($$error) return false @@ -581,10 +585,11 @@ proc getTransactionCount*( const info = "getTransactionCount()" let - trie = db.getTrie(TxTrie, txRoot).valueOr: + ctx = db.ctx + trie = ctx.newTrie(TxTrie, txRoot).valueOr: warn logTxt info, txRoot, action="getTrie()", error=($$error) return 0 - mpt = db.newMpt(trie).valueOr: + mpt = ctx.getMpt(trie).valueOr: warn logTxt info, txRoot, action="newMpt()", trie=($$trie), error=($$error) return 0 @@ -635,7 +640,7 @@ proc persistWithdrawals*( withdrawals: openArray[Withdrawal]; ): Hash256 = const info = "persistWithdrawals()" - let mpt = db.newMpt(WithdrawalsTrie) + let mpt = db.ctx.getMpt(WithdrawalsTrie) for idx, wd in withdrawals: mpt.merge(rlp.encode(idx), rlp.encode(wd)).isOkOr: warn logTxt info, idx, action="merge()", error=($$error) @@ -781,7 +786,7 @@ proc persistReceipts*( receipts: openArray[Receipt]; ): Hash256 = const info = "persistReceipts()" - let mpt = db.newMpt(ReceiptsTrie) + let mpt = db.ctx.getMpt(ReceiptsTrie) for idx, rec in receipts: mpt.merge(rlp.encode(idx), rlp.encode(rec)).isOkOr: warn logTxt info, idx, action="merge()", error=($$error) diff --git a/nimbus/db/core_db/memory_only.nim b/nimbus/db/core_db/memory_only.nim index e646aae8c..ab2ed12f7 100644 --- a/nimbus/db/core_db/memory_only.nim +++ b/nimbus/db/core_db/memory_only.nim @@ -99,15 +99,6 @@ proc newCoreDbRef*( {.error: "Unsupported constructor " & $dbType & ".newCoreDbRef()" & " with qidLayout argument".} -# ------------------------------------------------------------------------------ -# Public template wrappers -# ------------------------------------------------------------------------------ - -template shortTimeReadOnly*(id: CoreDbTxID; body: untyped) = - proc action() = - body - id.shortTimeReadOnly action - # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/nimbus/db/ledger/backend/accounts_ledger.nim b/nimbus/db/ledger/backend/accounts_ledger.nim index d5a003e8c..6dc70a1ea 100644 --- a/nimbus/db/ledger/backend/accounts_ledger.nim +++ b/nimbus/db/ledger/backend/accounts_ledger.nim @@ -171,7 +171,7 @@ proc ledgerMethods(lc: impl.AccountsLedgerRef): LedgerFns = proc ledgerExtras(lc: impl.AccountsLedgerRef): LedgerExtras = LedgerExtras( getMptFn: proc(): CoreDbMptRef = - lc.rawTrie.CoreDxAccRef.newMpt.CoreDbMptRef, + lc.rawTrie.CoreDxAccRef.getMpt.CoreDbMptRef, rawRootHashFn: proc(): Hash256 = lc.rawTrie.rootHash()) diff --git a/nimbus/db/ledger/base.nim b/nimbus/db/ledger/base.nim index 8875dbaaa..a45d7ef11 100644 --- a/nimbus/db/ledger/base.nim +++ b/nimbus/db/ledger/base.nim @@ -94,7 +94,7 @@ proc bless*(ldg: LedgerRef; db: CoreDbRef): LedgerRef = ldg.trackApi = db.trackLedgerApi when LedgerEnableApiProfiling: ldg.profTab = db.ldgProfData() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, ldgType=ldg.ldgType + ldg.ifTrackApi: debug apiTxt, api, elapsed, ldgType=ldg.ldgType ldg # ------------------------------------------------------------------------------ @@ -117,87 +117,87 @@ proc ldgProfData*(db: CoreDbRef): LedgerProfListRef = proc accessList*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgAccessListFn ldg.methods.accessListFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr proc accessList*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256) = ldg.beginTrackApi LdgAccessListFn ldg.methods.accessList2Fn(eAddr, slot) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot proc accountExists*(ldg: LedgerRef, eAddr: EthAddress): bool = ldg.beginTrackApi LdgAccountExistsFn result = ldg.methods.accountExistsFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc addBalance*(ldg: LedgerRef, eAddr: EthAddress, delta: UInt256) = ldg.beginTrackApi LdgAddBalanceFn ldg.methods.addBalanceFn(eAddr, delta) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, delta + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, delta proc addLogEntry*(ldg: LedgerRef, log: Log) = ldg.beginTrackApi LdgAddLogEntryFn ldg.methods.addLogEntryFn log - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc beginSavepoint*(ldg: LedgerRef): LedgerSpRef = ldg.beginTrackApi LdgBeginSavepointFn result = ldg.methods.beginSavepointFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc clearStorage*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgClearStorageFn ldg.methods.clearStorageFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr proc clearTransientStorage*(ldg: LedgerRef) = ldg.beginTrackApi LdgClearTransientStorageFn ldg.methods.clearTransientStorageFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc collectWitnessData*(ldg: LedgerRef) = ldg.beginTrackApi LdgCollectWitnessDataFn ldg.methods.collectWitnessDataFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc commit*(ldg: LedgerRef, sp: LedgerSpRef) = ldg.beginTrackApi LdgCommitFn ldg.methods.commitFn sp - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc deleteAccount*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgDeleteAccountFn ldg.methods.deleteAccountFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr proc dispose*(ldg: LedgerRef, sp: LedgerSpRef) = ldg.beginTrackApi LdgDisposeFn ldg.methods.disposeFn sp - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc getAndClearLogEntries*(ldg: LedgerRef): seq[Log] = ldg.beginTrackApi LdgGetAndClearLogEntriesFn result = ldg.methods.getAndClearLogEntriesFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc getBalance*(ldg: LedgerRef, eAddr: EthAddress): UInt256 = ldg.beginTrackApi LdgGetBalanceFn result = ldg.methods.getBalanceFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc getCode*(ldg: LedgerRef, eAddr: EthAddress): Blob = ldg.beginTrackApi LdgGetCodeFn result = ldg.methods.getCodeFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result=result.toStr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result=result.toStr proc getCodeHash*(ldg: LedgerRef, eAddr: EthAddress): Hash256 = ldg.beginTrackApi LdgGetCodeHashFn result = ldg.methods.getCodeHashFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc getCodeSize*(ldg: LedgerRef, eAddr: EthAddress): int = ldg.beginTrackApi LdgGetCodeSizeFn result = ldg.methods.getCodeSizeFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc getCommittedStorage*( ldg: LedgerRef; @@ -206,22 +206,22 @@ proc getCommittedStorage*( ): UInt256 = ldg.beginTrackApi LdgGetCommittedStorageFn result = ldg.methods.getCommittedStorageFn(eAddr, slot) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, result proc getNonce*(ldg: LedgerRef, eAddr: EthAddress): AccountNonce = ldg.beginTrackApi LdgGetNonceFn result = ldg.methods.getNonceFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc getStorage*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256): UInt256 = ldg.beginTrackApi LdgGetStorageFn result = ldg.methods.getStorageFn(eAddr, slot) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, result proc getStorageRoot*(ldg: LedgerRef, eAddr: EthAddress): Hash256 = ldg.beginTrackApi LdgGetStorageRootFn result = ldg.methods.getStorageRootFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc getTransientStorage*( ldg: LedgerRef; @@ -230,112 +230,112 @@ proc getTransientStorage*( ): UInt256 = ldg.beginTrackApi LdgGetTransientStorageFn result = ldg.methods.getTransientStorageFn(eAddr, slot) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, result proc hasCodeOrNonce*(ldg: LedgerRef, eAddr: EthAddress): bool = ldg.beginTrackApi LdgHasCodeOrNonceFn result = ldg.methods.hasCodeOrNonceFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc inAccessList*(ldg: LedgerRef, eAddr: EthAddress): bool = ldg.beginTrackApi LdgInAccessListFn result = ldg.methods.inAccessListFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc inAccessList*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256): bool = ldg.beginTrackApi LdgInAccessListFn result = ldg.methods.inAccessList2Fn(eAddr, slot) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, result proc incNonce*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgIncNonceFn ldg.methods.incNonceFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr proc isDeadAccount*(ldg: LedgerRef, eAddr: EthAddress): bool = ldg.beginTrackApi LdgIsDeadAccountFn result = ldg.methods.isDeadAccountFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc isEmptyAccount*(ldg: LedgerRef, eAddr: EthAddress): bool = ldg.beginTrackApi LdgIsEmptyAccountFn result = ldg.methods.isEmptyAccountFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result proc isTopLevelClean*(ldg: LedgerRef): bool = ldg.beginTrackApi LdgIsTopLevelCleanFn result = ldg.methods.isTopLevelCleanFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result proc logEntries*(ldg: LedgerRef): seq[Log] = ldg.beginTrackApi LdgLogEntriesFn result = ldg.methods.logEntriesFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result proc makeMultiKeys*(ldg: LedgerRef): MultiKeysRef = ldg.beginTrackApi LdgMakeMultiKeysFn result = ldg.methods.makeMultiKeysFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc persist*(ldg: LedgerRef, clearEmptyAccount = false, clearCache = true) = ldg.beginTrackApi LdgPersistFn ldg.methods.persistFn(clearEmptyAccount, clearCache) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, clearEmptyAccount, clearCache + ldg.ifTrackApi: debug apiTxt, api, elapsed, clearEmptyAccount, clearCache proc ripemdSpecial*(ldg: LedgerRef) = ldg.beginTrackApi LdgRipemdSpecialFn ldg.methods.ripemdSpecialFn() - ldg.ifTrackApi: debug apiTxt, ctx + ldg.ifTrackApi: debug apiTxt, api, elapsed proc rollback*(ldg: LedgerRef, sp: LedgerSpRef) = ldg.beginTrackApi LdgRollbackFn ldg.methods.rollbackFn sp - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc rootHash*(ldg: LedgerRef): Hash256 = ldg.beginTrackApi LdgRootHashFn result = ldg.methods.rootHashFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result proc safeDispose*(ldg: LedgerRef, sp: LedgerSpRef) = ldg.beginTrackApi LdgSafeDisposeFn ldg.methods.safeDisposeFn sp - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc selfDestruct*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgSelfDestructFn ldg.methods.selfDestructFn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc selfDestruct6780*(ldg: LedgerRef, eAddr: EthAddress) = ldg.beginTrackApi LdgSelfDestruct6780Fn ldg.methods.selfDestruct6780Fn eAddr - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed proc selfDestructLen*(ldg: LedgerRef): int = ldg.beginTrackApi LdgSelfDestructLenFn result = ldg.methods.selfDestructLenFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result proc setBalance*(ldg: LedgerRef, eAddr: EthAddress, balance: UInt256) = ldg.beginTrackApi LdgSetBalanceFn ldg.methods.setBalanceFn(eAddr, balance) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, balance + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, balance proc setCode*(ldg: LedgerRef, eAddr: EthAddress, code: Blob) = ldg.beginTrackApi LdgSetCodeFn ldg.methods.setCodeFn(eAddr, code) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, code=code.toStr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, code=code.toStr proc setNonce*(ldg: LedgerRef, eAddr: EthAddress, nonce: AccountNonce) = ldg.beginTrackApi LdgSetNonceFn ldg.methods.setNonceFn(eAddr, nonce) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, nonce + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, nonce proc setStorage*(ldg: LedgerRef, eAddr: EthAddress, slot, val: UInt256) = ldg.beginTrackApi LdgSetStorageFn ldg.methods.setStorageFn(eAddr, slot, val) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, val + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, val proc setTransientStorage*( ldg: LedgerRef; @@ -345,17 +345,17 @@ proc setTransientStorage*( ) = ldg.beginTrackApi LdgSetTransientStorageFn ldg.methods.setTransientStorageFn(eAddr, slot, val) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, slot, val + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, slot, val proc subBalance*(ldg: LedgerRef, eAddr: EthAddress, delta: UInt256) = ldg.beginTrackApi LdgSubBalanceFn ldg.methods.subBalanceFn(eAddr, delta) - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, delta + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, delta proc getAccessList*(ldg: LedgerRef): AccessList = ldg.beginTrackApi LdgGetAccessListFn result = ldg.methods.getAccessListFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed # ------------------------------------------------------------------------------ # Public methods, extensions to go away @@ -364,12 +364,12 @@ proc getAccessList*(ldg: LedgerRef): AccessList = proc getMpt*(ldg: LedgerRef): CoreDbMptRef = ldg.beginTrackApi LdgGetMptFn result = ldg.extras.getMptFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result proc rawRootHash*(ldg: LedgerRef): Hash256 = ldg.beginTrackApi LdgRawRootHashFn result = ldg.extras.rawRootHashFn() - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result + ldg.ifTrackApi: debug apiTxt, api, elapsed, result # ------------------------------------------------------------------------------ # Public virtual read-only methods diff --git a/nimbus/db/ledger/base/api_tracking.nim b/nimbus/db/ledger/base/api_tracking.nim index f6f8f7443..9ddd75875 100644 --- a/nimbus/db/ledger/base/api_tracking.nim +++ b/nimbus/db/ledger/base/api_tracking.nim @@ -112,13 +112,13 @@ func toStr*(ela: Duration): string = # ------------------------------------------------------------------------------ template beginApi*(ldg: LedgerRef; s: static[LedgerFnInx]) = - const ctx {.inject,used.} = s # Generally available + const api {.inject,used.} = s # Generally available let baStart {.inject.} = getTime() # Local use only template endApiIf*(ldg: LedgerRef; code: untyped) = when CoreDbEnableApiProfiling: let elapsed {.inject,used.} = getTime() - baStart - aristo_profile.update(ldg.profTab, ctx.ord, elapsed) + aristo_profile.update(ldg.profTab, api.ord, elapsed) if ldg.trackApi: when not CoreDbEnableApiProfiling: # otherwise use variable above let elapsed {.inject,used.} = getTime() - baStart diff --git a/nimbus/db/ledger/base_iterators.nim b/nimbus/db/ledger/base_iterators.nim index bb8f1be58..f7d004a7a 100644 --- a/nimbus/db/ledger/base_iterators.nim +++ b/nimbus/db/ledger/base_iterators.nim @@ -47,7 +47,7 @@ iterator accounts*(ldg: LedgerRef): Account = yield w else: raiseAssert: "Unsupported ledger type: " & $ldg.ldgType - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed iterator addresses*(ldg: LedgerRef): EthAddress = @@ -61,7 +61,7 @@ iterator addresses*(ldg: LedgerRef): EthAddress = yield w else: raiseAssert: "Unsupported ledger type: " & $ldg.ldgType - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed iterator cachedStorage*(ldg: LedgerRef, eAddr: EthAddress): (UInt256,UInt256) = @@ -75,7 +75,7 @@ iterator cachedStorage*(ldg: LedgerRef, eAddr: EthAddress): (UInt256,UInt256) = yield w else: raiseAssert: "Unsupported ledger type: " & $ldg.ldgType - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr iterator pairs*(ldg: LedgerRef): (EthAddress,Account) = @@ -89,7 +89,7 @@ iterator pairs*(ldg: LedgerRef): (EthAddress,Account) = yield w else: raiseAssert: "Unsupported ledger type: " & $ldg.ldgType - ldg.ifTrackApi: debug apiTxt, ctx, elapsed + ldg.ifTrackApi: debug apiTxt, api, elapsed iterator storage*( @@ -107,7 +107,7 @@ iterator storage*( yield w else: raiseAssert: "Unsupported ledger type: " & $ldg.ldgType - ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr + ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/ledger/distinct_ledgers.nim b/nimbus/db/ledger/distinct_ledgers.nim index 0dc955d3a..722b2913b 100644 --- a/nimbus/db/ledger/distinct_ledgers.nim +++ b/nimbus/db/ledger/distinct_ledgers.nim @@ -90,7 +90,7 @@ proc init*( root: Hash256; pruneOk = true; ): T = - db.newAccMpt(root, pruneOk).T + db.ctx.getAccMpt(root, pruneOk).T proc init*( T: type AccountLedger; @@ -159,9 +159,10 @@ proc init*( if rc.isErr: raiseAssert "re-hash oops, error=" & $$rc.error let - trie = if stt.isNil: db.getTrie(account.address) else: stt + ctx = db.ctx + trie = if stt.isNil: ctx.newTrie(account.address) else: stt mpt = block: - let rc = db.newMpt(trie, pruneOk) + let rc = ctx.getMpt(trie, pruneOk) if rc.isErr: raiseAssert info & $$rc.error rc.value @@ -195,7 +196,7 @@ iterator storage*( info = "storage(): " let trie = account.stoTrie if not trie.isNil: - let mpt = al.distinctBase.parent.newMpt(trie).valueOr: + let mpt = al.distinctBase.parent.ctx.getMpt(trie).valueOr: raiseAssert info & $$error for (key,val) in mpt.pairs: yield (key,val)