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
This commit is contained in:
Jordan Hrycaj 2024-03-18 19:40:23 +00:00 committed by GitHub
parent 5379302ce9
commit 14a5f46d13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 866 additions and 941 deletions

View File

@ -65,36 +65,39 @@ proc txMethods(
kTx: KvtTxRef; kTx: KvtTxRef;
): CoreDbTxFns = ): CoreDbTxFns =
## To be constructed by some `CoreDbBaseFns` function ## To be constructed by some `CoreDbBaseFns` function
let
adbBase = db.adbBase
kdbBase = db.kdbBase
adbApi = adbBase.api
kdbApi = kdbBase.api
CoreDbTxFns( CoreDbTxFns(
levelFn: proc(): int = levelFn: proc(): int =
aTx.level, aTx.level,
commitFn: proc(ignore: bool): CoreDbRc[void] = commitFn: proc(ignore: bool): CoreDbRc[void] =
const info = "commitFn()" const info = "commitFn()"
? db.adbBase.api.commit(aTx).toVoidRc(db.adbBase, info) ? adbApi.commit(aTx).toVoidRc(adbBase, info)
? db.kdbBase.api.commit(kTx).toVoidRc(db.kdbBase, info) ? kdbApi.commit(kTx).toVoidRc(kdbBase, info)
ok(), ok(),
rollbackFn: proc(): CoreDbRc[void] = rollbackFn: proc(): CoreDbRc[void] =
const info = "rollbackFn()" const info = "rollbackFn()"
? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) ? adbApi.rollback(aTx).toVoidRc(adbBase, info)
? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info) ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info)
ok(), ok(),
disposeFn: proc(): CoreDbRc[void] = disposeFn: proc(): CoreDbRc[void] =
const info = "disposeFn()" const info = "disposeFn()"
if db.adbBase.api.isTop(aTx): if adbApi.isTop(aTx): ? adbApi.rollback(aTx).toVoidRc(adbBase, info)
? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) if kdbApi.isTop(kTx): ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info)
if db.kdbBase.api.isTop(kTx):
? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info)
ok(), ok(),
safeDisposeFn: proc(): CoreDbRc[void] = safeDisposeFn: proc(): CoreDbRc[void] =
const info = "safeDisposeFn()" const info = "safeDisposeFn()"
if db.adbBase.api.isTop(aTx): if adbApi.isTop(aTx): ? adbApi.rollback(aTx).toVoidRc(adbBase, info)
? db.adbBase.api.rollback(aTx).toVoidRc(db.adbBase, info) if kdbApi.isTop(kTx): ? kdbApi.rollback(kTx).toVoidRc(kdbBase, info)
if db.kdbBase.api.isTop(kTx):
? db.kdbBase.api.rollback(kTx).toVoidRc(db.kdbBase, info)
ok()) ok())
@ -104,9 +107,6 @@ proc baseMethods(
K: typedesc; K: typedesc;
): CoreDbBaseFns = ): CoreDbBaseFns =
CoreDbBaseFns( CoreDbBaseFns(
verifyFn: proc(trie: CoreDbTrieRef): bool =
db.adbBase.verify(trie),
backendFn: proc(): CoreDbBackendRef = backendFn: proc(): CoreDbBackendRef =
db.bless(AristoCoreDbBE()), db.bless(AristoCoreDbBE()),
@ -117,9 +117,6 @@ proc baseMethods(
levelFn: proc(): int = levelFn: proc(): int =
db.adbBase.getLevel, db.adbBase.getLevel,
tryHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
db.adbBase.tryHash(trie, "tryHashFn()"),
rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
db.adbBase.rootHash(trie, "rootHashFn()"), db.adbBase.rootHash(trie, "rootHashFn()"),
@ -132,27 +129,11 @@ proc baseMethods(
legacySetupFn: proc() = legacySetupFn: proc() =
discard, 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] = newKvtFn: proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] =
db.kdbBase.newKvtHandler(sharedTable, "newKvtFn()"), db.kdbBase.newKvtHandler(sharedTable, "newKvtFn()"),
newMptFn: proc( getCtxFn: proc(): CoreDbCtxRef =
trie: CoreDbTrieRef; db.adbBase.ctx,
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()")),
beginFn: proc(): CoreDbRc[CoreDxTxRef] = beginFn: proc(): CoreDbRc[CoreDxTxRef] =
const info = "beginFn()" const info = "beginFn()"
@ -161,9 +142,6 @@ proc baseMethods(
kTx = ? db.kdbBase.txBegin(info) kTx = ? db.kdbBase.txBegin(info)
ok(db.bless CoreDxTxRef(methods: db.txMethods(aTx, kTx))), ok(db.bless CoreDxTxRef(methods: db.txMethods(aTx, kTx))),
getIdFn: proc(): CoreDbRc[CoreDxTxID] =
CoreDxTxID.notImplemented(db, "getIdFn()"),
newCaptureFn: proc(flags: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] = newCaptureFn: proc(flags: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] =
CoreDxCaptRef.notImplemented(db, "capture()")) CoreDxCaptRef.notImplemented(db, "capture()"))
@ -256,14 +234,10 @@ func toAristoProfData*(
result.kvt = db.AristoCoreDbRef.kdbBase.api.KvtApiProfRef.data result.kvt = db.AristoCoreDbRef.kdbBase.api.KvtApiProfRef.data
func toAristoApi*(dsc: CoreDxKvtRef): KvtApiRef = func toAristoApi*(dsc: CoreDxKvtRef): KvtApiRef =
doAssert not dsc.parent.isNil
doAssert dsc.parent.isAristo
if dsc.parent.isAristo: if dsc.parent.isAristo:
return AristoCoreDbRef(dsc.parent).kdbBase.api return AristoCoreDbRef(dsc.parent).kdbBase.api
func toAristoApi*(dsc: CoreDxMptRef): AristoApiRef = func toAristoApi*(dsc: CoreDxMptRef): AristoApiRef =
doAssert not dsc.parent.isNil
doAssert dsc.parent.isAristo
if dsc.parent.isAristo: if dsc.parent.isAristo:
return AristoCoreDbRef(dsc.parent).adbBase.api return AristoCoreDbRef(dsc.parent).adbBase.api

View File

@ -24,8 +24,12 @@ import
type type
AristoBaseRef* = ref object AristoBaseRef* = ref object
parent: CoreDbRef ## Opaque top level descriptor parent: CoreDbRef ## Opaque top level descriptor
adb: AristoDbRef ## Aristo MPT database
api*: AristoApiRef ## Api functions can be re-directed 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 AristoCoreDxAccRef = ref object of CoreDxAccRef
base: AristoBaseRef ## Local base descriptor base: AristoBaseRef ## Local base descriptor
@ -71,11 +75,6 @@ static:
# Private helpers # Private helpers
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
template logTxt(info: static[string]): static[string] =
"CoreDb/adb " & info
# -------------------------------
func isValid(trie: CoreDbTrieRef): bool = func isValid(trie: CoreDbTrieRef): bool =
not trie.isNil and trie.ready not trie.isNil and trie.ready
@ -177,46 +176,63 @@ func toVoidRc[T](
return ok() return ok()
err rc.error.toError(base, info, error) 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 # Private `MPT` call back functions
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns = proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
## Hexary trie database handlers ## 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( proc mptBackend(): CoreDbMptBackendRef =
cMpt: AristoCoreDxMptRef; db.bless AristoCoreDbMptBE(adb: mpt)
): CoreDbMptBackendRef =
let base = cMpt.base
base.parent.bless AristoCoreDbMptBE(adb: base.adb)
proc mptTrieFn( proc mptTrieFn(): CoreDbTrieRef =
cMpt: AristoCoreDxMptRef;
): CoreDbTrieRef =
let trie = let trie =
if LEAST_FREE_VID <= cMpt.root.distinctBase: if LEAST_FREE_VID <= cMpt.root.distinctBase:
assert cMpt.accPath.isValid # debug mode only assert cMpt.accPath.isValid # debug mode only
AristoCoreDbTrie( AristoCoreDbTrie(
base: cMpt.base, base: base,
kind: StorageTrie, kind: StorageTrie,
stoRoot: cMpt.root, stoRoot: cMpt.root,
stoAddr: cMpt.address) stoAddr: cMpt.address)
else: else:
AristoCoreDbTrie( AristoCoreDbTrie(
base: cMpt.base, base: base,
kind: CoreDbSubTrie(cMpt.root)) kind: CoreDbSubTrie(cMpt.root))
cMpt.base.parent.bless trie db.bless trie
proc mptPersistent( proc mptPersistent(): CoreDbRc[void] =
cMpt: AristoCoreDxMptRef; const info = "persistentFn()"
info: static[string];
): CoreDbRc[void] = let rc = api.stow(mpt, persistent = true)
let
base = cMpt.base
mpt = base.adb
api = base.api
rc = api.stow(mpt, persistent = true)
if rc.isOk: if rc.isOk:
ok() ok()
elif api.level(mpt) == 0: elif api.level(mpt) == 0:
@ -224,25 +240,17 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
else: else:
err(rc.error.toError(base, info, MptTxPending)) err(rc.error.toError(base, info, MptTxPending))
proc mptFetch( proc mptFetch(key: openArray[byte]): CoreDbRc[Blob] =
cMpt: AristoCoreDxMptRef; const info = "fetchFn()"
k: openArray[byte];
info: static[string];
): CoreDbRc[Blob] =
let
base = cMpt.base
root = cMpt.root
# Some pathological behaviour observed with storage tries due to lazy # Some pathological behaviour observed with storage tries due to lazy
# update. The `fetchPayload()` does not now about this and would complain # update. The `fetchPayload()` does not now about this and would complain
# an error different from `FetchPathNotFound`. # an error different from `FetchPathNotFound`.
let root = cMpt.root
if not root.isValid: if not root.isValid:
return err((VoidTrieID,MptRootMissing).toError(base, info, MptNotFound)) return err((VoidTrieID,MptRootMissing).toError(base, info, MptNotFound))
let let rc = api.fetchPayload(mpt, root, key)
mpt = base.adb
api = base.api
rc = api.fetchPayload(mpt, root, k)
if rc.isOk: if rc.isOk:
api.serialise(mpt, rc.value).toRc(base, info) api.serialise(mpt, rc.value).toRc(base, info)
elif rc.error[1] != FetchPathNotFound: elif rc.error[1] != FetchPathNotFound:
@ -250,19 +258,11 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
else: else:
err rc.error.toError(base, info, MptNotFound) err rc.error.toError(base, info, MptNotFound)
proc mptMerge( proc mptMerge(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
cMpt: AristoCoreDxMptRef; const info = "mergeFn()"
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
# Provide root ID on-the-fly # Provide root ID on-the-fly
let rootOk = cMpt.root.isValid
if not rootOk: if not rootOk:
cMpt.root = api.vidFetch(mpt, pristine=true) cMpt.root = api.vidFetch(mpt, pristine=true)
@ -275,22 +275,15 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok() ok()
proc mptDelete( proc mptDelete(key: openArray[byte]): CoreDbRc[void] =
cMpt: AristoCoreDxMptRef; const info = "deleteFn()"
k: openArray[byte];
info: static[string];
): CoreDbRc[void] =
let
base = cMpt.base
api = base.api
mpt = base.adb
if not cMpt.root.isValid and cMpt.accPath.isValid: if not cMpt.root.isValid and cMpt.accPath.isValid:
# This is insane but legit. A storage trie was announced for an account # This is insane but legit. A storage trie was announced for an account
# but no data have been added, yet. # but no data have been added, yet.
return ok() 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.isErr:
if rc.error[1] == DelPathNotFound: if rc.error[1] == DelPathNotFound:
return err(rc.error.toError(base, info, MptNotFound)) return err(rc.error.toError(base, info, MptNotFound))
@ -301,47 +294,39 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
cMpt.root = VoidTrieID cMpt.root = VoidTrieID
ok() ok()
proc mptHasPath( proc mptHasPath(key: openArray[byte]): CoreDbRc[bool] =
cMpt: AristoCoreDxMptRef; const info = "hasPathFn()"
key: openArray[byte];
info: static[string]; let rc = api.hasPath(mpt, cMpt.root, key)
): CoreDbRc[bool] =
let
base = cMpt.base
mpt = base.adb
api = base.api
rc = api.hasPath(mpt, cMpt.root, key)
if rc.isErr: if rc.isErr:
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok(rc.value) ok(rc.value)
CoreDbMptFns( CoreDbMptFns(
backendFn: proc(): CoreDbMptBackendRef = backendFn: proc(): CoreDbMptBackendRef =
cMpt.mptBackend(), mptBackend(),
fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] = fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] =
cMpt.mptFetch(k, "fetchFn()"), mptFetch(k),
deleteFn: proc(k: openArray[byte]): CoreDbRc[void] = deleteFn: proc(k: openArray[byte]): CoreDbRc[void] =
cMpt.mptDelete(k, "deleteFn()"), mptDelete(k),
mergeFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] = 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] = hasPathFn: proc(k: openArray[byte]): CoreDbRc[bool] =
cMpt.mptHasPath(k, "hasPathFn()"), mptHasPath(k),
getTrieFn: proc(): CoreDbTrieRef = getTrieFn: proc(): CoreDbTrieRef =
cMpt.mptTrieFn(), mptTrieFn(),
isPruningFn: proc(): bool = isPruningFn: proc(): bool =
true, true,
persistentFn: proc(): CoreDbRc[void] = persistentFn: proc(): CoreDbRc[void] =
cMpt.mptPersistent("persistentFn()"), mptPersistent())
forgetFn: proc(): CoreDbRc[void] =
discard)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Private account call back functions # Private account call back functions
@ -349,30 +334,25 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns = proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
## Hexary trie database handlers ## 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( proc accBackend(): CoreDbAccBackendRef =
cAcc: AristoCoreDxAccRef; db.bless AristoCoreDbAccBE(adb: mpt)
): CoreDbAccBackendRef =
let base = cAcc.base
base.parent.bless AristoCoreDbAccBE(adb: base.adb)
proc getTrieFn( proc getTrieFn(): CoreDbTrieRef =
cMpt: AristoCoreDxAccRef; db.bless AristoCoreDbTrie(
): CoreDbTrieRef =
let base = cAcc.base
base.parent.bless AristoCoreDbTrie(
base: base, base: base,
kind: AccountsTrie) kind: AccountsTrie)
proc accPersistent( proc accPersistent(): CoreDbRc[void] =
cAcc: AristoCoreDxAccRef; const info = "persistentFn()"
info: static[string];
): CoreDbRc[void] = let rc = api.stow(mpt, persistent = true)
let
base = cAcc.base
mpt = base.adb
api = base.api
rc = api.stow(mpt, persistent = true)
if rc.isOk: if rc.isOk:
ok() ok()
elif api.level(mpt) == 0: elif api.level(mpt) == 0:
@ -380,24 +360,15 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
else: else:
err(rc.error.toError(base, info, AccTxPending)) err(rc.error.toError(base, info, AccTxPending))
proc accCloneMpt( proc accCloneMpt(): CoreDbRc[CoreDxMptRef] =
cAcc: AristoCoreDxAccRef;
info: static[string];
): CoreDbRc[CoreDxMptRef] =
ok(AristoCoreDxMptRef( ok(AristoCoreDxMptRef(
base: cAcc.base, base: base,
root: AccountsTrieID)) root: AccountsTrieID))
proc accFetch( proc accFetch(address: EthAddress): CoreDbRc[CoreDbAccount] =
cAcc: AristoCoreDxAccRef; const info = "fetchFn()"
address: EthAddress;
info: static[string]; let pyl = block:
): CoreDbRc[CoreDbAccount] =
let
base = cAcc.base
api = base.api
mpt = base.adb
pyl = block:
let let
key = address.keccakHash.data key = address.keccakHash.data
rc = api.fetchPayload(mpt, AccountsTrieID, key) rc = api.fetchPayload(mpt, AccountsTrieID, key)
@ -409,35 +380,25 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
return err(rc.error.toError(base, info, AccNotFound)) return err(rc.error.toError(base, info, AccNotFound))
if pyl.pType != AccountData: if pyl.pType != AccountData:
let vePair = (pyl.account.storageID, PayloadTypeUnsupported) let vidErrPair = (pyl.account.storageID, PayloadTypeUnsupported)
return err(vePair.toError(base, info & "/" & $pyl.pType)) return err(vidErrPair.toError(base, info & "/" & $pyl.pType))
ok cAcc.toCoreDbAccount(pyl.account, address) ok cAcc.toCoreDbAccount(pyl.account, address)
proc accMerge( proc accMerge(account: CoreDbAccount): CoreDbRc[void] =
cAcc: AristoCoreDxAccRef; const info = "mergeFn()"
acc: CoreDbAccount;
info: static[string];
): CoreDbRc[void] =
let let
base = cAcc.base key = account.address.keccakHash.data
api = base.api val = account.toPayloadRef()
mpt = base.adb
key = acc.address.keccakHash.data
val = acc.toPayloadRef()
rc = api.mergePayload(mpt, AccountsTrieID, key, val) rc = api.mergePayload(mpt, AccountsTrieID, key, val)
if rc.isErr: if rc.isErr:
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok() ok()
proc accDelete( proc accDelete(address: EthAddress): CoreDbRc[void] =
cAcc: AristoCoreDxAccRef; const info = "deleteFn()"
address: EthAddress;
info: static[string];
): CoreDbRc[void] =
let let
base = cAcc.base
api = base.api
mpt = base.adb
key = address.keccakHash.data key = address.keccakHash.data
rc = api.delete(mpt, AccountsTrieID, key, VOID_PATH_ID) rc = api.delete(mpt, AccountsTrieID, key, VOID_PATH_ID)
if rc.isErr: if rc.isErr:
@ -446,15 +407,10 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok() ok()
proc accStoFlush( proc accStoFlush(address: EthAddress): CoreDbRc[void] =
cAcc: AristoCoreDxAccRef; const info = "stoFlushFn()"
address: EthAddress;
info: static[string];
): CoreDbRc[void] =
let let
base = cAcc.base
api = base.api
mpt = base.adb
key = address.keccakHash.data key = address.keccakHash.data
pyl = api.fetchPayload(mpt, AccountsTrieID, key).valueOr: pyl = api.fetchPayload(mpt, AccountsTrieID, key).valueOr:
return ok() return ok()
@ -468,53 +424,185 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok() ok()
proc accHasPath( proc accHasPath(address: EthAddress): CoreDbRc[bool] =
cAcc: AristoCoreDxAccRef; const info = "hasPathFn()"
address: EthAddress;
info: static[string];
): CoreDbRc[bool] =
let let
base = cAcc.base
api = cAcc.base.api
mpt = cAcc.base.adb
key = address.keccakHash.data key = address.keccakHash.data
rc = api.hasPath(mpt, AccountsTrieID, key) rc = api.hasPath(mpt, AccountsTrieID, key)
if rc.isErr: if rc.isErr:
return err(rc.error.toError(base, info)) return err(rc.error.toError(base, info))
ok(rc.value) ok(rc.value)
CoreDbAccFns( CoreDbAccFns(
backendFn: proc(): CoreDbAccBackendRef = backendFn: proc(): CoreDbAccBackendRef =
cAcc.accBackend(), accBackend(),
newMptFn: proc(): CoreDbRc[CoreDxMptRef] = getMptFn: proc(): CoreDbRc[CoreDxMptRef] =
cAcc.accCloneMpt("newMptFn()"), accCloneMpt(),
fetchFn: proc(address: EthAddress): CoreDbRc[CoreDbAccount] = fetchFn: proc(address: EthAddress): CoreDbRc[CoreDbAccount] =
cAcc.accFetch(address, "fetchFn()"), accFetch(address),
deleteFn: proc(address: EthAddress): CoreDbRc[void] = deleteFn: proc(address: EthAddress): CoreDbRc[void] =
cAcc.accDelete(address, "deleteFn()"), accDelete(address),
stoFlushFn: proc(address: EthAddress): CoreDbRc[void] = stoFlushFn: proc(address: EthAddress): CoreDbRc[void] =
cAcc.accStoFlush(address, "stoFlushFn()"), accStoFlush(address),
mergeFn: proc(acc: CoreDbAccount): CoreDbRc[void] = mergeFn: proc(acc: CoreDbAccount): CoreDbRc[void] =
cAcc.accMerge(acc, "mergeFn()"), accMerge(acc),
hasPathFn: proc(address: EthAddress): CoreDbRc[bool] = hasPathFn: proc(address: EthAddress): CoreDbRc[bool] =
cAcc.accHasPath(address, "hasPathFn()"), accHasPath(address),
getTrieFn: proc(): CoreDbTrieRef = getTrieFn: proc(): CoreDbTrieRef =
cAcc.getTrieFn(), getTrieFn(),
isPruningFn: proc(): bool = isPruningFn: proc(): bool =
true, true,
persistentFn: proc(): CoreDbRc[void] = 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) discard)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -546,7 +634,7 @@ func toVoidRc*[T](
# --------------------- # ---------------------
func to*(dsc: CoreDxMptRef, T: type AristoDbRef): T = func to*(dsc: CoreDxMptRef, T: type AristoDbRef): T =
AristoCoreDxMptRef(dsc).base.adb AristoCoreDxMptRef(dsc).base.ctx.mpt
func rootID*(dsc: CoreDxMptRef): VertexID = func rootID*(dsc: CoreDxMptRef): VertexID =
dsc.AristoCoreDxMptRef.root dsc.AristoCoreDxMptRef.root
@ -561,31 +649,12 @@ proc txBegin*(
base: AristoBaseRef; base: AristoBaseRef;
info: static[string]; info: static[string];
): CoreDbRc[AristoTxRef] = ): CoreDbRc[AristoTxRef] =
base.api.txBegin(base.adb).toRc(base, info) base.api.txBegin(base.ctx.mpt).toRc(base, info)
# --------------------- # ---------------------
proc getLevel*(base: AristoBaseRef): int = proc getLevel*(base: AristoBaseRef): int =
base.api.level(base.adb) base.api.level(base.ctx.mpt)
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)
proc triePrint*( proc triePrint*(
base: AristoBaseRef; base: AristoBaseRef;
@ -626,7 +695,7 @@ proc rootHash*(
let let
api = base.api api = base.api
mpt = base.adb mpt = base.ctx.mpt
? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable) ? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable)
let key = block: let key = block:
@ -638,145 +707,29 @@ proc rootHash*(
ok key.to(Hash256) 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 # 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) = 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 = func init*(T: type AristoBaseRef; db: CoreDbRef; adb: AristoDbRef): T =
result = T( result = T(
parent: db, parent: db,
api: AristoApiRef.init(), api: AristoApiRef.init())
adb: adb)
# Create initial context
result.ctx = db.bless AristoCoreDbCtxRef(
base: result,
mpt: adb)
result.ctx.methods = result.ctx.ctxMethods
when CoreDbEnableApiProfiling: when CoreDbEnableApiProfiling:
let profApi = AristoApiProfRef.init(result.api, adb.backend) let profApi = AristoApiProfRef.init(result.api, adb.backend)
result.api = profApi result.api = profApi
result.adb.backend = profApi.be result.ctx.mpt.backend = profApi.be
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End

View File

@ -28,6 +28,7 @@ type
kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor
tdb: TrieDatabaseRef ## Descriptor reference copy captured with closures tdb: TrieDatabaseRef ## Descriptor reference copy captured with closures
top: LegacyCoreDxTxRef ## Top transaction (if any) top: LegacyCoreDxTxRef ## Top transaction (if any)
ctx: LegacyCoreDbCtxRef ## Cache, there is only one context here
level: int ## Debugging level: int ## Debugging
LegacyDbClose* = proc() {.gcsafe, raises: [].} LegacyDbClose* = proc() {.gcsafe, raises: [].}
@ -40,6 +41,10 @@ type
address: Option[EthAddress] ## For storage tree debugging address: Option[EthAddress] ## For storage tree debugging
accPath: Blob ## 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 LegacyCoreDxTxRef = ref object of CoreDxTxRef
ltx: DbTransaction ## Legacy transaction descriptor ltx: DbTransaction ## Legacy transaction descriptor
back: LegacyCoreDxTxRef ## Previous transaction back: LegacyCoreDxTxRef ## Previous transaction
@ -312,9 +317,6 @@ proc mptMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbMptFns =
if 0 < db.txLevel(): if 0 < db.txLevel():
const info = "persistentFn()" const info = "persistentFn()"
return err(db.bless(MptTxPending, LegacyCoreDbError(ctx: info))) return err(db.bless(MptTxPending, LegacyCoreDbError(ctx: info)))
ok(),
forgetFn: proc(): CoreDbRc[void] =
ok()) ok())
proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns = proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
@ -323,7 +325,7 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
backendFn: proc(): CoreDbAccBackendRef = backendFn: proc(): CoreDbAccBackendRef =
db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)), db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)),
newMptFn: proc(): CoreDbRc[CoreDxMptRef] = getMptFn: proc(): CoreDbRc[CoreDxMptRef] =
let xMpt = HexaryChildDbRef(trie: mpt.trie) let xMpt = HexaryChildDbRef(trie: mpt.trie)
ok(db.bless CoreDxMptRef(methods: xMpt.mptMethods db)), ok(db.bless CoreDxMptRef(methods: xMpt.mptMethods db)),
@ -367,11 +369,68 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
if 0 < db.txLevel(): if 0 < db.txLevel():
const info = "persistentFn()" const info = "persistentFn()"
return err(db.bless(AccTxPending, LegacyCoreDbError(ctx: info))) return err(db.bless(AccTxPending, LegacyCoreDbError(ctx: info)))
ok(),
forgetFn: proc(): CoreDbRc[void] =
ok()) 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 = proc txMethods(tx: CoreDxTxRef): CoreDbTxFns =
let tx = tx.LegacyCoreDxTxRef let tx = tx.LegacyCoreDxTxRef
@ -405,12 +464,6 @@ proc txMethods(tx: CoreDxTxRef): CoreDbTxFns =
tx.pop() tx.pop()
ok()) 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 = proc cptMethods(cpt: RecorderRef; db: LegacyDbRef): CoreDbCaptFns =
CoreDbCaptFns( CoreDbCaptFns(
recorderFn: proc(): CoreDbRef = recorderFn: proc(): CoreDbRef =
@ -436,16 +489,6 @@ proc baseMethods(
): CoreDbBaseFns = ): CoreDbBaseFns =
let tdb = db.tdb let tdb = db.tdb
CoreDbBaseFns( 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 = backendFn: proc(): CoreDbBackendRef =
db.bless(LegacyCoreDbBE(base: db)), db.bless(LegacyCoreDbBE(base: db)),
@ -456,9 +499,6 @@ proc baseMethods(
if not closeDb.isNil: if not closeDb.isNil:
closeDb(), closeDb(),
tryHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
ok(trie.lroot),
rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] = rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
ok(trie.lroot), ok(trie.lroot),
@ -471,46 +511,11 @@ proc baseMethods(
legacySetupFn: proc() = legacySetupFn: proc() =
db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]), 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] = newKvtFn: proc(sharedTable = true): CoreDbRc[CoreDxKvtRef] =
ok(db.kvt), ok(db.kvt),
newMptFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxMptRef] = getCtxFn: proc(): CoreDbCtxRef =
var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune)) db.ctx,
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))),
beginFn: proc(): CoreDbRc[CoreDxTxRef] = beginFn: proc(): CoreDbRc[CoreDxTxRef] =
db.top = LegacyCoreDxTxRef( db.top = LegacyCoreDxTxRef(
@ -543,6 +548,12 @@ proc init*(
# Base descriptor # Base descriptor
db.dbType = dbType db.dbType = dbType
db.methods = db.baseMethods(dbType, closeDb) 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 db.bless
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
# Nimbus # Nimbus
# Copyright (c) 2018-2023 Status Research & Development GmbH # Copyright (c) 2023-2024 Status Research & Development GmbH
# Licensed under either of # Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0) # http://www.apache.org/licenses/LICENSE-2.0)
@ -22,14 +22,12 @@ type
CoreDbMptRef* = distinct CoreDxMptRef CoreDbMptRef* = distinct CoreDxMptRef
CoreDbPhkRef* = distinct CoreDxPhkRef CoreDbPhkRef* = distinct CoreDxPhkRef
CoreDbTxRef* = distinct CoreDxTxRef CoreDbTxRef* = distinct CoreDxTxRef
CoreDbTxID* = distinct CoreDxTxID
CoreDbCaptRef* = distinct CoreDxCaptRef CoreDbCaptRef* = distinct CoreDxCaptRef
CoreDbTrieRefs* = CoreDbMptRef | CoreDbPhkRef CoreDbTrieRefs* = CoreDbMptRef | CoreDbPhkRef
## Shortcut, *MPT* modules for (legacy API) ## Shortcut, *MPT* modules for (legacy API)
CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbTxID | CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbCaptRef
CoreDbCaptRef
## Shortcut, all modules with a `parent` entry (for legacy API) ## Shortcut, all modules with a `parent` entry (for legacy API)
# End # End

View File

@ -14,10 +14,10 @@ import
./base_desc ./base_desc
type type
CoreDxTrieRefs* = CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef CoreDxTrieRefs* = CoreDbCtxRef | CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef
## Shortcut, *MPT* descriptors ## Shortcut, *MPT* descriptors
CoreDxTrieRelated* = CoreDxTrieRefs | CoreDxTxRef | CoreDxTxID | CoreDxCaptRef CoreDxTrieRelated* = CoreDxTrieRefs | CoreDxTxRef | CoreDxCaptRef
## Shortcut, descriptors for sub-modules running on an *MPT* ## Shortcut, descriptors for sub-modules running on an *MPT*
CoreDbBackends* = CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbBackends* = CoreDbBackendRef | CoreDbKvtBackendRef |

View File

@ -32,7 +32,7 @@ type
AccGetTrieFn = "acc/getTrie" AccGetTrieFn = "acc/getTrie"
AccHasPathFn = "acc/hasPath" AccHasPathFn = "acc/hasPath"
AccMergeFn = "acc/merge" AccMergeFn = "acc/merge"
AccNewMptFn = "acc/newMpt" AccGetMptFn = "acc/getMpt"
AccPersistentFn = "acc/persistent" AccPersistentFn = "acc/persistent"
AccStoFlushFn = "acc/stoFlush" AccStoFlushFn = "acc/stoFlush"
AccToMptFn = "acc/toMpt" AccToMptFn = "acc/toMpt"
@ -42,13 +42,11 @@ type
BaseDbTypeFn = "dbType" BaseDbTypeFn = "dbType"
BaseFinishFn = "finish" BaseFinishFn = "finish"
BaseGetTrieFn = "getTrie" BaseGetCtxFn = "ctx"
BaseLegacySetupFn = "compensateLegacySetup" BaseLegacySetupFn = "compensateLegacySetup"
BaseLevelFn = "level" BaseLevelFn = "level"
BaseNewAccFn = "newAccMpt"
BaseNewCaptureFn = "newCapture" BaseNewCaptureFn = "newCapture"
BaseNewKvtFn = "newKvt" BaseNewKvtFn = "newKvt"
BaseNewMptFn = "newMpt"
BaseNewTxFn = "newTransaction" BaseNewTxFn = "newTransaction"
CptFlagsFn = "cpt/flags" CptFlagsFn = "cpt/flags"
@ -56,6 +54,14 @@ type
CptRecorderFn = "cpt/recorder" CptRecorderFn = "cpt/recorder"
CptForgetFn = "cpt/forget" 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 = "$$" ErrorPrintFn = "$$"
EthAccRecastFn = "recast" EthAccRecastFn = "recast"
@ -74,7 +80,6 @@ type
LegaCptFlagsFn = "cpt/flags" LegaCptFlagsFn = "cpt/flags"
LegaCptLogDbFn = "cpt/logDb" LegaCptLogDbFn = "cpt/logDb"
LegaCptRecorderFn = "cpt/recorder" LegaCptRecorderFn = "cpt/recorder"
LegaGetTxIdFn = "getTransactionID"
LegaIsPruningFn = "trie/isPruning" LegaIsPruningFn = "trie/isPruning"
LegaKvtContainsFn = "kvt/contains" LegaKvtContainsFn = "kvt/contains"
@ -101,7 +106,6 @@ type
LegaPhkPutFn = "phk/put" LegaPhkPutFn = "phk/put"
LegaPhkRootHashFn = "phk/rootHash" LegaPhkRootHashFn = "phk/rootHash"
LegaShortTimeRoFn = "shortTimeReadOnly"
LegaToMptFn = "phk/toMpt" LegaToMptFn = "phk/toMpt"
LegaToPhkFn = "mpt/toPhk" 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[CoreDbRef]): string = rc.toStr "db"
proc toStr*(rc: CoreDbRc[CoreDbAccount]): string = rc.toStr "acc" proc toStr*(rc: CoreDbRc[CoreDbAccount]): string = rc.toStr "acc"
proc toStr*(rc: CoreDbRc[CoreDxKvtRef]): string = rc.toStr "kvt" 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[CoreDxTxRef]): string = rc.toStr "tx"
proc toStr*(rc: CoreDbRc[CoreDxCaptRef]): string = rc.toStr "capt" 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[CoreDxMptRef]): string = rc.toStr "mpt"
proc toStr*(rc: CoreDbRc[CoreDxAccRef]): string = rc.toStr "acc" proc toStr*(rc: CoreDbRc[CoreDxAccRef]): string = rc.toStr "acc"

View File

@ -52,21 +52,23 @@ type
CoreDbErrorCode* = enum CoreDbErrorCode* = enum
Unset = 0 Unset = 0
Unspecified Unspecified
RlpException
AccAddrMissing
AccNotFound
AccTxPending
AutoFlushFailed
CtxNotFound
HashNotAvailable
KvtNotFound KvtNotFound
KvtTxPending KvtTxPending
MptNotFound MptNotFound
MptTxPending MptTxPending
AccNotFound
AccAddrMissing
AccTxPending
RootNotFound
AutoFlushFailed
RootUnacceptable
HashNotAvailable
TrieLocked
StorageFailed
NotImplemented NotImplemented
RlpException
RootNotFound
RootUnacceptable
StorageFailed
TrieLocked
CoreDbSubTrie* = enum CoreDbSubTrie* = enum
StorageTrie = 0 StorageTrie = 0
@ -83,51 +85,38 @@ type
# -------------------------------------------------- # --------------------------------------------------
# Sub-descriptor: Misc methods for main descriptor # Sub-descriptor: Misc methods for main descriptor
# -------------------------------------------------- # --------------------------------------------------
CoreDbBaseVerifyFn* = proc(trie: CoreDbTrieRef): bool {.noRaise.}
CoreDbBaseBackendFn* = proc(): CoreDbBackendRef {.noRaise.} CoreDbBaseBackendFn* = proc(): CoreDbBackendRef {.noRaise.}
CoreDbBaseDestroyFn* = proc(flush = true) {.noRaise.} CoreDbBaseDestroyFn* = proc(flush = true) {.noRaise.}
CoreDbBaseTryHashFn* = proc(vid: CoreDbTrieRef): CoreDbRc[Hash256] {.noRaise.}
CoreDbBaseRootHashFn* = proc( CoreDbBaseRootHashFn* = proc(
trie: CoreDbTrieRef): CoreDbRc[Hash256] {.noRaise.} trie: CoreDbTrieRef): CoreDbRc[Hash256] {.noRaise.}
CoreDbBaseTriePrintFn* = proc(vid: CoreDbTrieRef): string {.noRaise.} CoreDbBaseTriePrintFn* = proc(vid: CoreDbTrieRef): string {.noRaise.}
CoreDbBaseErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.} CoreDbBaseErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.}
CoreDbBaseInitLegaSetupFn* = proc() {.noRaise.} CoreDbBaseInitLegaSetupFn* = proc() {.noRaise.}
CoreDbBaseGetTrieFn* = proc(
trie: CoreDbSubTrie; root: Hash256; address: Option[EthAddress];
): CoreDbRc[CoreDbTrieRef] {.noRaise.}
CoreDbBaseLevelFn* = proc(): int {.noRaise.} CoreDbBaseLevelFn* = proc(): int {.noRaise.}
CoreDbBaseKvtFn* = proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] {.noRaise.} CoreDbBaseNewKvtFn* =
CoreDbBaseMptFn* = proc( proc(sharedTable: bool): CoreDbRc[CoreDxKvtRef] {.noRaise.}
root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.} CoreDbBaseGetCtxFn* = proc(): CoreDbCtxRef {.noRaise.}
CoreDbBaseAccFn* = proc(
root: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxAccRef] {.noRaise.}
CoreDbBaseTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.}
CoreDbBaseTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.} CoreDbBaseTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.}
CoreDbBaseNewCaptFn* = CoreDbBaseNewCaptFn* =
proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.} proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.}
CoreDbBaseGetCaptFn* = proc(): CoreDbRc[CoreDxCaptRef] {.noRaise.} CoreDbBaseGetCaptFn* = proc(): CoreDbRc[CoreDxCaptRef] {.noRaise.}
CoreDbBaseFns* = object CoreDbBaseFns* = object
verifyFn*: CoreDbBaseVerifyFn
backendFn*: CoreDbBaseBackendFn backendFn*: CoreDbBaseBackendFn
destroyFn*: CoreDbBaseDestroyFn destroyFn*: CoreDbBaseDestroyFn
tryHashFn*: CoreDbBaseTryHashFn
rootHashFn*: CoreDbBaseRootHashFn rootHashFn*: CoreDbBaseRootHashFn
triePrintFn*: CoreDbBaseTriePrintFn triePrintFn*: CoreDbBaseTriePrintFn
errorPrintFn*: CoreDbBaseErrorPrintFn errorPrintFn*: CoreDbBaseErrorPrintFn
legacySetupFn*: CoreDbBaseInitLegaSetupFn legacySetupFn*: CoreDbBaseInitLegaSetupFn
getTrieFn*: CoreDbBaseGetTrieFn
levelFn*: CoreDbBaseLevelFn levelFn*: CoreDbBaseLevelFn
# Kvt constructor # Kvt constructor
newKvtFn*: CoreDbBaseKvtFn newKvtFn*: CoreDbBaseNewKvtFn
# Hexary trie constructors # MPT context constructor
newMptFn*: CoreDbBaseMptFn getCtxFn*: CoreDbBaseGetCtxFn
newAccFn*: CoreDbBaseAccFn
# Transactions constructors # Transactions constructors
getIdFn*: CoreDbBaseTxGetIdFn
beginFn*: CoreDbBaseTxBeginFn beginFn*: CoreDbBaseTxBeginFn
# capture/tracer constructors # capture/tracer constructors
@ -156,6 +145,33 @@ type
persistentFn*: CoreDbKvtPersistentFn persistentFn*: CoreDbKvtPersistentFn
forgetFn*: CoreDbKvtForgetFn 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 # Sub-descriptor: generic Mpt/hexary trie methods
@ -187,13 +203,13 @@ type
getTrieFn*: CoreDbMptGetTrieFn getTrieFn*: CoreDbMptGetTrieFn
isPruningFn*: CoreDbMptIsPruningFn isPruningFn*: CoreDbMptIsPruningFn
persistentFn*: CoreDbMptPersistentFn persistentFn*: CoreDbMptPersistentFn
forgetFn*: CoreDbMptForgetFn
# ---------------------------------------------------- # ----------------------------------------------------
# Sub-descriptor: Mpt/hexary trie methods for accounts # Sub-descriptor: Mpt/hexary trie methods for accounts
# ------------------------------------------------------ # ------------------------------------------------------
CoreDbAccBackendFn* = proc(): CoreDbAccBackendRef {.noRaise.} CoreDbAccBackendFn* = proc(): CoreDbAccBackendRef {.noRaise.}
CoreDbAccNewMptFn* = proc(): CoreDbRc[CoreDxMptRef] {.noRaise.} CoreDbAccGetMptFn* = proc(): CoreDbRc[CoreDxMptRef] {.noRaise.}
CoreDbAccFetchFn* = proc(k: EthAddress): CoreDbRc[CoreDbAccount] {.noRaise.} CoreDbAccFetchFn* = proc(k: EthAddress): CoreDbRc[CoreDbAccount] {.noRaise.}
CoreDbAccDeleteFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.} CoreDbAccDeleteFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.}
CoreDbAccStoFlushFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.} CoreDbAccStoFlushFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.}
@ -207,7 +223,7 @@ type
CoreDbAccFns* = object CoreDbAccFns* = object
## Methods for trie objects ## Methods for trie objects
backendFn*: CoreDbAccBackendFn backendFn*: CoreDbAccBackendFn
newMptFn*: CoreDbAccNewMptFn getMptFn*: CoreDbAccGetMptFn
fetchFn*: CoreDbAccFetchFn fetchFn*: CoreDbAccFetchFn
deleteFn*: CoreDbAccDeleteFn deleteFn*: CoreDbAccDeleteFn
stoFlushFn*: CoreDbAccStoFlushFn stoFlushFn*: CoreDbAccStoFlushFn
@ -216,7 +232,7 @@ type
getTrieFn*: CoreDbAccGetTrieFn getTrieFn*: CoreDbAccGetTrieFn
isPruningFn*: CoreDbAccIsPruningFn isPruningFn*: CoreDbAccIsPruningFn
persistentFn*: CoreDbAccPersistentFn persistentFn*: CoreDbAccPersistentFn
forgetFn*: CoreDbAccForgetFn
# -------------------------------------------------- # --------------------------------------------------
# Sub-descriptor: Transaction frame management # Sub-descriptor: Transaction frame management
@ -234,16 +250,6 @@ type
disposeFn*: CoreDbTxDisposeFn disposeFn*: CoreDbTxDisposeFn
safeDisposeFn*: CoreDbTxSafeDisposeFn 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 # Sub-descriptor: capture recorder methods
@ -259,6 +265,7 @@ type
getFlagsFn*: CoreDbCaptFlagsFn getFlagsFn*: CoreDbCaptFlagsFn
forgetFn*: CoreDbCaptForgetFn forgetFn*: CoreDbCaptForgetFn
# -------------------------------------------------- # --------------------------------------------------
# Production descriptors # Production descriptors
# -------------------------------------------------- # --------------------------------------------------
@ -300,6 +307,11 @@ type
parent*: CoreDbRef parent*: CoreDbRef
methods*: CoreDbKvtFns methods*: CoreDbKvtFns
CoreDbCtxRef* = ref object of RootRef
## Context for `CoreDxMptRef` and `CoreDxAccRef`
parent*: CoreDbRef
methods*: CoreDbCtxFns
CoreDxMptRef* = ref object of RootRef CoreDxMptRef* = ref object of RootRef
## Hexary/Merkle-Patricia tree derived from `CoreDbRef`, will be ## Hexary/Merkle-Patricia tree derived from `CoreDbRef`, will be
## initialised on-the-fly. ## initialised on-the-fly.
@ -330,11 +342,6 @@ type
parent*: CoreDbRef parent*: CoreDbRef
methods*: CoreDbTxFns methods*: CoreDbTxFns
CoreDxTxID* = ref object
## Transaction ID descriptor derived from `CoreDbRef`
parent*: CoreDbRef
methods*: CoreDbTxIdFns
CoreDxCaptRef* = ref object CoreDxCaptRef* = ref object
## Db transaction tracer derived from `CoreDbRef` ## Db transaction tracer derived from `CoreDbRef`
parent*: CoreDbRef parent*: CoreDbRef

View File

@ -19,8 +19,8 @@ type
MethodsDesc = MethodsDesc =
CoreDxKvtRef | CoreDxKvtRef |
CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef | CoreDbCtxRef | CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef |
CoreDxTxRef | CoreDxTxID | CoreDxTxRef |
CoreDxCaptRef CoreDxCaptRef
ValidateDesc* = MethodsDesc | EphemMethodsDesc | CoreDbErrorRef ValidateDesc* = MethodsDesc | EphemMethodsDesc | CoreDbErrorRef
@ -30,20 +30,15 @@ type
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
proc validateMethodsDesc(base: CoreDbBaseFns) = proc validateMethodsDesc(base: CoreDbBaseFns) =
doAssert not base.verifyFn.isNil
doAssert not base.backendFn.isNil doAssert not base.backendFn.isNil
doAssert not base.destroyFn.isNil doAssert not base.destroyFn.isNil
doAssert not base.tryHashFn.isNil
doAssert not base.rootHashFn.isNil doAssert not base.rootHashFn.isNil
doAssert not base.triePrintFn.isNil doAssert not base.triePrintFn.isNil
doAssert not base.errorPrintFn.isNil doAssert not base.errorPrintFn.isNil
doAssert not base.legacySetupFn.isNil doAssert not base.legacySetupFn.isNil
doAssert not base.getTrieFn.isNil
doAssert not base.levelFn.isNil doAssert not base.levelFn.isNil
doAssert not base.newKvtFn.isNil doAssert not base.newKvtFn.isNil
doAssert not base.newMptFn.isNil doAssert not base.getCtxFn.isNil
doAssert not base.newAccFn.isNil
doAssert not base.getIdFn.isNil
doAssert not base.beginFn.isNil doAssert not base.beginFn.isNil
doAssert not base.newCaptureFn.isNil doAssert not base.newCaptureFn.isNil
@ -53,8 +48,16 @@ proc validateMethodsDesc(kvt: CoreDbKvtFns) =
doAssert not kvt.delFn.isNil doAssert not kvt.delFn.isNil
doAssert not kvt.putFn.isNil doAssert not kvt.putFn.isNil
doAssert not kvt.persistentFn.isNil doAssert not kvt.persistentFn.isNil
doAssert not kvt.forgetFn.isNil
doAssert not kvt.hasKeyFn.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) = proc validateMethodsDesc(fns: CoreDbMptFns) =
doAssert not fns.backendFn.isNil doAssert not fns.backendFn.isNil
@ -65,7 +68,6 @@ proc validateMethodsDesc(fns: CoreDbMptFns) =
doAssert not fns.getTrieFn.isNil doAssert not fns.getTrieFn.isNil
doAssert not fns.isPruningFn.isNil doAssert not fns.isPruningFn.isNil
doAssert not fns.persistentFn.isNil doAssert not fns.persistentFn.isNil
doAssert not fns.forgetFn.isNil
proc validateMethodsDesc(fns: CoreDbAccFns) = proc validateMethodsDesc(fns: CoreDbAccFns) =
doAssert not fns.backendFn.isNil doAssert not fns.backendFn.isNil
@ -78,7 +80,6 @@ proc validateMethodsDesc(fns: CoreDbAccFns) =
doAssert not fns.getTrieFn.isNil doAssert not fns.getTrieFn.isNil
doAssert not fns.isPruningFn.isNil doAssert not fns.isPruningFn.isNil
doAssert not fns.persistentFn.isNil doAssert not fns.persistentFn.isNil
doAssert not fns.forgetFn.isNil
# ------------ # ------------
@ -101,6 +102,11 @@ proc validateMethodsDesc(kvt: CoreDxKvtRef) =
doAssert not kvt.parent.isNil doAssert not kvt.parent.isNil
kvt.methods.validateMethodsDesc kvt.methods.validateMethodsDesc
proc validateMethodsDesc(ctx: CoreDbCtxRef) =
doAssert not ctx.isNil
doAssert not ctx.parent.isNil
ctx.methods.validateMethodsDesc
proc validateMethodsDesc(mpt: CoreDxMptRef) = proc validateMethodsDesc(mpt: CoreDxMptRef) =
doAssert not mpt.isNil doAssert not mpt.isNil
doAssert not mpt.parent.isNil doAssert not mpt.parent.isNil
@ -132,11 +138,6 @@ proc validateMethodsDesc(tx: CoreDxTxRef) =
doAssert not tx.methods.disposeFn.isNil doAssert not tx.methods.disposeFn.isNil
doAssert not tx.methods.safeDisposeFn.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) = proc validateMethodsDesc(db: CoreDbRef) =
doAssert not db.isNil doAssert not db.isNil
doAssert db.dbType != CoreDbType(0) doAssert db.dbType != CoreDbType(0)

View File

@ -52,7 +52,7 @@ iterator pairs*(kvt: CoreDxKvtRef): (Blob, Blob) {.apiRaise.} =
yield (k,v) yield (k,v)
else: else:
raiseAssert: "Unsupported database type: " & $kvt.parent.dbType 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.} = iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} =
## Trie traversal, only supported for `CoreDxMptRef` (not `Phk`) ## 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 raiseAssert: "Unsupported database type: " & $mpt.parent.dbType
mpt.ifTrackNewApi: mpt.ifTrackNewApi:
let trie = mpt.methods.getTrieFn() let trie = mpt.methods.getTrieFn()
debug newApiTxt, ctx, elapsed, trie debug newApiTxt, api, elapsed, trie
iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} = iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} =
## Low level trie dump, only supported for `CoreDxMptRef` (not `Phk`) ## 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 raiseAssert: "Unsupported database type: " & $mpt.parent.dbType
mpt.ifTrackNewApi: mpt.ifTrackNewApi:
let trie = mpt.methods.getTrieFn() let trie = mpt.methods.getTrieFn()
debug newApiTxt, ctx, elapsed, trie debug newApiTxt, api, elapsed, trie
when ProvideLegacyAPI: when ProvideLegacyAPI:
iterator pairs*(kvt: CoreDbKvtRef): (Blob, Blob) {.apiRaise.} = iterator pairs*(kvt: CoreDbKvtRef): (Blob, Blob) {.apiRaise.} =
kvt.setTrackLegaApi LegaKvtPairsIt kvt.setTrackLegaApi LegaKvtPairsIt
for k,v in kvt.distinctBase.pairs(): yield (k,v) 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.} = iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
## Trie traversal, not supported for `CoreDbPhkRef` ## Trie traversal, not supported for `CoreDbPhkRef`
mpt.setTrackLegaApi LegaMptPairsIt mpt.setTrackLegaApi LegaMptPairsIt
for k,v in mpt.distinctBase.pairs(): yield (k,v) 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.} = iterator replicate*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
## Low level trie dump, not supported for `CoreDbPhkRef` ## Low level trie dump, not supported for `CoreDbPhkRef`
mpt.setTrackLegaApi LegaMptReplicateIt mpt.setTrackLegaApi LegaMptReplicateIt
for k,v in mpt.distinctBase.replicate(): yield (k,v) for k,v in mpt.distinctBase.replicate(): yield (k,v)
mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End

View File

@ -57,7 +57,7 @@ iterator replicatePersistent*(mpt: CoreDxMptRef): (Blob, Blob) {.rlpRaise.} =
raiseAssert: "Unsupported database type: " & $mpt.parent.dbType raiseAssert: "Unsupported database type: " & $mpt.parent.dbType
mpt.ifTrackNewApi: mpt.ifTrackNewApi:
let trie = mpt.methods.getTrieFn() let trie = mpt.methods.getTrieFn()
debug newApiTxt, ctx, elapsed, trie debug newApiTxt, api, elapsed, trie
when ProvideLegacyAPI: when ProvideLegacyAPI:
@ -65,7 +65,7 @@ when ProvideLegacyAPI:
## Low level trie dump, not supported for `CoreDbPhkRef` ## Low level trie dump, not supported for `CoreDbPhkRef`
mpt.setTrackLegaApi LegaMptReplicateIt mpt.setTrackLegaApi LegaMptReplicateIt
for k,v in mpt.distinctBase.replicatePersistent(): yield (k,v) for k,v in mpt.distinctBase.replicatePersistent(): yield (k,v)
mpt.ifTrackLegaApi: debug legaApiTxt, ctx, elapsed mpt.ifTrackLegaApi: debug legaApiTxt, api, elapsed
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End

View File

@ -118,11 +118,12 @@ iterator getBlockTransactionData*(
): Blob = ): Blob =
block body: block body:
let let
trie = db.getTrie(TxTrie, transactionRoot).valueOr: ctx = db.ctx
trie = ctx.newTrie(TxTrie, transactionRoot).valueOr:
warn logTxt "getBlockTransactionData()", warn logTxt "getBlockTransactionData()",
transactionRoot, action="getTrie()", `error`=($$error) transactionRoot, action="getTrie()", `error`=($$error)
break body break body
transactionDb = db.newMpt(trie).valueOr: transactionDb = ctx.getMpt(trie).valueOr:
warn logTxt "getBlockTransactionData()", transactionRoot, warn logTxt "getBlockTransactionData()", transactionRoot,
action="newMpt()", trie=($$trie), error=($$error) action="newMpt()", trie=($$trie), error=($$error)
break body break body
@ -165,11 +166,12 @@ iterator getWithdrawalsData*(
): Blob = ): Blob =
block body: block body:
let let
trie = db.getTrie(WithdrawalsTrie, withdrawalsRoot).valueOr: ctx = db.ctx
trie = ctx.newTrie(WithdrawalsTrie, withdrawalsRoot).valueOr:
warn logTxt "getWithdrawalsData()", warn logTxt "getWithdrawalsData()",
withdrawalsRoot, action="getTrie()", error=($$error) withdrawalsRoot, action="getTrie()", error=($$error)
break body break body
wddb = db.newMpt(trie).valueOr: wddb = ctx.getMpt(trie).valueOr:
warn logTxt "getWithdrawalsData()", warn logTxt "getWithdrawalsData()",
withdrawalsRoot, action="newMpt()", trie=($$trie), error=($$error) withdrawalsRoot, action="newMpt()", trie=($$trie), error=($$error)
break body break body
@ -192,11 +194,12 @@ iterator getReceipts*(
{.gcsafe, raises: [RlpError].} = {.gcsafe, raises: [RlpError].} =
block body: block body:
let let
trie = db.getTrie(ReceiptsTrie, receiptRoot).valueOr: ctx = db.ctx
trie = ctx.newTrie(ReceiptsTrie, receiptRoot).valueOr:
warn logTxt "getWithdrawalsData()", warn logTxt "getWithdrawalsData()",
receiptRoot, action="getTrie()", error=($$error) receiptRoot, action="getTrie()", error=($$error)
break body break body
receiptDb = db.newMpt(trie).valueOr: receiptDb = ctx.getMpt(trie).valueOr:
warn logTxt "getWithdrawalsData()", warn logTxt "getWithdrawalsData()",
receiptRoot, action="newMpt()", trie=($$trie), error=($$error) receiptRoot, action="newMpt()", trie=($$trie), error=($$error)
break body break body
@ -469,7 +472,7 @@ proc setScore*(db: CoreDbRef; blockHash: Hash256, score: UInt256) =
return return
proc getTd*(db: CoreDbRef; blockHash: Hash256, td: var UInt256): bool = proc getTd*(db: CoreDbRef; blockHash: Hash256, td: var UInt256): bool =
const info = "getId()" const info = "getTd()"
let bytes = db.newKvt() let bytes = db.newKvt()
.get(blockHashToScoreKey(blockHash).toOpenArray).valueOr: .get(blockHashToScoreKey(blockHash).toOpenArray).valueOr:
if error.error != KvtNotFound: if error.error != KvtNotFound:
@ -529,7 +532,7 @@ proc persistTransactions*(
const const
info = "persistTransactions()" info = "persistTransactions()"
let let
mpt = db.newMpt(TxTrie) mpt = db.ctx.getMpt(TxTrie)
kvt = db.newKvt() kvt = db.newKvt()
# Prevent DB from coughing. # Prevent DB from coughing.
db.compensateLegacySetup() db.compensateLegacySetup()
@ -560,10 +563,11 @@ proc getTransaction*(
const const
info = "getTransaction()" info = "getTransaction()"
let let
trie = db.getTrie(TxTrie, txRoot).valueOr: ctx = db.ctx
trie = ctx.newTrie(TxTrie, txRoot).valueOr:
warn logTxt info, txRoot, action="getTrie()", error=($$error) warn logTxt info, txRoot, action="getTrie()", error=($$error)
return false return false
mpt = db.newMpt(trie).valueOr: mpt = ctx.getMpt(trie).valueOr:
warn logTxt info, warn logTxt info,
txRoot, action="newMpt()", trie=($$trie), error=($$error) txRoot, action="newMpt()", trie=($$trie), error=($$error)
return false return false
@ -581,10 +585,11 @@ proc getTransactionCount*(
const const
info = "getTransactionCount()" info = "getTransactionCount()"
let let
trie = db.getTrie(TxTrie, txRoot).valueOr: ctx = db.ctx
trie = ctx.newTrie(TxTrie, txRoot).valueOr:
warn logTxt info, txRoot, action="getTrie()", error=($$error) warn logTxt info, txRoot, action="getTrie()", error=($$error)
return 0 return 0
mpt = db.newMpt(trie).valueOr: mpt = ctx.getMpt(trie).valueOr:
warn logTxt info, txRoot, warn logTxt info, txRoot,
action="newMpt()", trie=($$trie), error=($$error) action="newMpt()", trie=($$trie), error=($$error)
return 0 return 0
@ -635,7 +640,7 @@ proc persistWithdrawals*(
withdrawals: openArray[Withdrawal]; withdrawals: openArray[Withdrawal];
): Hash256 = ): Hash256 =
const info = "persistWithdrawals()" const info = "persistWithdrawals()"
let mpt = db.newMpt(WithdrawalsTrie) let mpt = db.ctx.getMpt(WithdrawalsTrie)
for idx, wd in withdrawals: for idx, wd in withdrawals:
mpt.merge(rlp.encode(idx), rlp.encode(wd)).isOkOr: mpt.merge(rlp.encode(idx), rlp.encode(wd)).isOkOr:
warn logTxt info, idx, action="merge()", error=($$error) warn logTxt info, idx, action="merge()", error=($$error)
@ -781,7 +786,7 @@ proc persistReceipts*(
receipts: openArray[Receipt]; receipts: openArray[Receipt];
): Hash256 = ): Hash256 =
const info = "persistReceipts()" const info = "persistReceipts()"
let mpt = db.newMpt(ReceiptsTrie) let mpt = db.ctx.getMpt(ReceiptsTrie)
for idx, rec in receipts: for idx, rec in receipts:
mpt.merge(rlp.encode(idx), rlp.encode(rec)).isOkOr: mpt.merge(rlp.encode(idx), rlp.encode(rec)).isOkOr:
warn logTxt info, idx, action="merge()", error=($$error) warn logTxt info, idx, action="merge()", error=($$error)

View File

@ -99,15 +99,6 @@ proc newCoreDbRef*(
{.error: "Unsupported constructor " & $dbType & ".newCoreDbRef()" & {.error: "Unsupported constructor " & $dbType & ".newCoreDbRef()" &
" with qidLayout argument".} " with qidLayout argument".}
# ------------------------------------------------------------------------------
# Public template wrappers
# ------------------------------------------------------------------------------
template shortTimeReadOnly*(id: CoreDbTxID; body: untyped) =
proc action() =
body
id.shortTimeReadOnly action
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -171,7 +171,7 @@ proc ledgerMethods(lc: impl.AccountsLedgerRef): LedgerFns =
proc ledgerExtras(lc: impl.AccountsLedgerRef): LedgerExtras = proc ledgerExtras(lc: impl.AccountsLedgerRef): LedgerExtras =
LedgerExtras( LedgerExtras(
getMptFn: proc(): CoreDbMptRef = getMptFn: proc(): CoreDbMptRef =
lc.rawTrie.CoreDxAccRef.newMpt.CoreDbMptRef, lc.rawTrie.CoreDxAccRef.getMpt.CoreDbMptRef,
rawRootHashFn: proc(): Hash256 = rawRootHashFn: proc(): Hash256 =
lc.rawTrie.rootHash()) lc.rawTrie.rootHash())

View File

@ -94,7 +94,7 @@ proc bless*(ldg: LedgerRef; db: CoreDbRef): LedgerRef =
ldg.trackApi = db.trackLedgerApi ldg.trackApi = db.trackLedgerApi
when LedgerEnableApiProfiling: when LedgerEnableApiProfiling:
ldg.profTab = db.ldgProfData() ldg.profTab = db.ldgProfData()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, ldgType=ldg.ldgType ldg.ifTrackApi: debug apiTxt, api, elapsed, ldgType=ldg.ldgType
ldg ldg
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -117,87 +117,87 @@ proc ldgProfData*(db: CoreDbRef): LedgerProfListRef =
proc accessList*(ldg: LedgerRef, eAddr: EthAddress) = proc accessList*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgAccessListFn ldg.beginTrackApi LdgAccessListFn
ldg.methods.accessListFn eAddr 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) = proc accessList*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256) =
ldg.beginTrackApi LdgAccessListFn ldg.beginTrackApi LdgAccessListFn
ldg.methods.accessList2Fn(eAddr, slot) 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 = proc accountExists*(ldg: LedgerRef, eAddr: EthAddress): bool =
ldg.beginTrackApi LdgAccountExistsFn ldg.beginTrackApi LdgAccountExistsFn
result = ldg.methods.accountExistsFn eAddr 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) = proc addBalance*(ldg: LedgerRef, eAddr: EthAddress, delta: UInt256) =
ldg.beginTrackApi LdgAddBalanceFn ldg.beginTrackApi LdgAddBalanceFn
ldg.methods.addBalanceFn(eAddr, delta) 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) = proc addLogEntry*(ldg: LedgerRef, log: Log) =
ldg.beginTrackApi LdgAddLogEntryFn ldg.beginTrackApi LdgAddLogEntryFn
ldg.methods.addLogEntryFn log ldg.methods.addLogEntryFn log
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc beginSavepoint*(ldg: LedgerRef): LedgerSpRef = proc beginSavepoint*(ldg: LedgerRef): LedgerSpRef =
ldg.beginTrackApi LdgBeginSavepointFn ldg.beginTrackApi LdgBeginSavepointFn
result = ldg.methods.beginSavepointFn() result = ldg.methods.beginSavepointFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc clearStorage*(ldg: LedgerRef, eAddr: EthAddress) = proc clearStorage*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgClearStorageFn ldg.beginTrackApi LdgClearStorageFn
ldg.methods.clearStorageFn eAddr ldg.methods.clearStorageFn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr
proc clearTransientStorage*(ldg: LedgerRef) = proc clearTransientStorage*(ldg: LedgerRef) =
ldg.beginTrackApi LdgClearTransientStorageFn ldg.beginTrackApi LdgClearTransientStorageFn
ldg.methods.clearTransientStorageFn() ldg.methods.clearTransientStorageFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc collectWitnessData*(ldg: LedgerRef) = proc collectWitnessData*(ldg: LedgerRef) =
ldg.beginTrackApi LdgCollectWitnessDataFn ldg.beginTrackApi LdgCollectWitnessDataFn
ldg.methods.collectWitnessDataFn() ldg.methods.collectWitnessDataFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc commit*(ldg: LedgerRef, sp: LedgerSpRef) = proc commit*(ldg: LedgerRef, sp: LedgerSpRef) =
ldg.beginTrackApi LdgCommitFn ldg.beginTrackApi LdgCommitFn
ldg.methods.commitFn sp ldg.methods.commitFn sp
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc deleteAccount*(ldg: LedgerRef, eAddr: EthAddress) = proc deleteAccount*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgDeleteAccountFn ldg.beginTrackApi LdgDeleteAccountFn
ldg.methods.deleteAccountFn eAddr ldg.methods.deleteAccountFn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr
proc dispose*(ldg: LedgerRef, sp: LedgerSpRef) = proc dispose*(ldg: LedgerRef, sp: LedgerSpRef) =
ldg.beginTrackApi LdgDisposeFn ldg.beginTrackApi LdgDisposeFn
ldg.methods.disposeFn sp ldg.methods.disposeFn sp
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc getAndClearLogEntries*(ldg: LedgerRef): seq[Log] = proc getAndClearLogEntries*(ldg: LedgerRef): seq[Log] =
ldg.beginTrackApi LdgGetAndClearLogEntriesFn ldg.beginTrackApi LdgGetAndClearLogEntriesFn
result = ldg.methods.getAndClearLogEntriesFn() result = ldg.methods.getAndClearLogEntriesFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc getBalance*(ldg: LedgerRef, eAddr: EthAddress): UInt256 = proc getBalance*(ldg: LedgerRef, eAddr: EthAddress): UInt256 =
ldg.beginTrackApi LdgGetBalanceFn ldg.beginTrackApi LdgGetBalanceFn
result = ldg.methods.getBalanceFn eAddr 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 = proc getCode*(ldg: LedgerRef, eAddr: EthAddress): Blob =
ldg.beginTrackApi LdgGetCodeFn ldg.beginTrackApi LdgGetCodeFn
result = ldg.methods.getCodeFn eAddr 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 = proc getCodeHash*(ldg: LedgerRef, eAddr: EthAddress): Hash256 =
ldg.beginTrackApi LdgGetCodeHashFn ldg.beginTrackApi LdgGetCodeHashFn
result = ldg.methods.getCodeHashFn eAddr 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 = proc getCodeSize*(ldg: LedgerRef, eAddr: EthAddress): int =
ldg.beginTrackApi LdgGetCodeSizeFn ldg.beginTrackApi LdgGetCodeSizeFn
result = ldg.methods.getCodeSizeFn eAddr result = ldg.methods.getCodeSizeFn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result
proc getCommittedStorage*( proc getCommittedStorage*(
ldg: LedgerRef; ldg: LedgerRef;
@ -206,22 +206,22 @@ proc getCommittedStorage*(
): UInt256 = ): UInt256 =
ldg.beginTrackApi LdgGetCommittedStorageFn ldg.beginTrackApi LdgGetCommittedStorageFn
result = ldg.methods.getCommittedStorageFn(eAddr, slot) 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 = proc getNonce*(ldg: LedgerRef, eAddr: EthAddress): AccountNonce =
ldg.beginTrackApi LdgGetNonceFn ldg.beginTrackApi LdgGetNonceFn
result = ldg.methods.getNonceFn eAddr 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 = proc getStorage*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256): UInt256 =
ldg.beginTrackApi LdgGetStorageFn ldg.beginTrackApi LdgGetStorageFn
result = ldg.methods.getStorageFn(eAddr, slot) 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 = proc getStorageRoot*(ldg: LedgerRef, eAddr: EthAddress): Hash256 =
ldg.beginTrackApi LdgGetStorageRootFn ldg.beginTrackApi LdgGetStorageRootFn
result = ldg.methods.getStorageRootFn eAddr result = ldg.methods.getStorageRootFn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr, result ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr, result
proc getTransientStorage*( proc getTransientStorage*(
ldg: LedgerRef; ldg: LedgerRef;
@ -230,112 +230,112 @@ proc getTransientStorage*(
): UInt256 = ): UInt256 =
ldg.beginTrackApi LdgGetTransientStorageFn ldg.beginTrackApi LdgGetTransientStorageFn
result = ldg.methods.getTransientStorageFn(eAddr, slot) 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 = proc hasCodeOrNonce*(ldg: LedgerRef, eAddr: EthAddress): bool =
ldg.beginTrackApi LdgHasCodeOrNonceFn ldg.beginTrackApi LdgHasCodeOrNonceFn
result = ldg.methods.hasCodeOrNonceFn eAddr 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 = proc inAccessList*(ldg: LedgerRef, eAddr: EthAddress): bool =
ldg.beginTrackApi LdgInAccessListFn ldg.beginTrackApi LdgInAccessListFn
result = ldg.methods.inAccessListFn eAddr 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 = proc inAccessList*(ldg: LedgerRef, eAddr: EthAddress, slot: UInt256): bool =
ldg.beginTrackApi LdgInAccessListFn ldg.beginTrackApi LdgInAccessListFn
result = ldg.methods.inAccessList2Fn(eAddr, slot) 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) = proc incNonce*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgIncNonceFn ldg.beginTrackApi LdgIncNonceFn
ldg.methods.incNonceFn eAddr 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 = proc isDeadAccount*(ldg: LedgerRef, eAddr: EthAddress): bool =
ldg.beginTrackApi LdgIsDeadAccountFn ldg.beginTrackApi LdgIsDeadAccountFn
result = ldg.methods.isDeadAccountFn eAddr 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 = proc isEmptyAccount*(ldg: LedgerRef, eAddr: EthAddress): bool =
ldg.beginTrackApi LdgIsEmptyAccountFn ldg.beginTrackApi LdgIsEmptyAccountFn
result = ldg.methods.isEmptyAccountFn eAddr 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 = proc isTopLevelClean*(ldg: LedgerRef): bool =
ldg.beginTrackApi LdgIsTopLevelCleanFn ldg.beginTrackApi LdgIsTopLevelCleanFn
result = ldg.methods.isTopLevelCleanFn() result = ldg.methods.isTopLevelCleanFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result ldg.ifTrackApi: debug apiTxt, api, elapsed, result
proc logEntries*(ldg: LedgerRef): seq[Log] = proc logEntries*(ldg: LedgerRef): seq[Log] =
ldg.beginTrackApi LdgLogEntriesFn ldg.beginTrackApi LdgLogEntriesFn
result = ldg.methods.logEntriesFn() result = ldg.methods.logEntriesFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result ldg.ifTrackApi: debug apiTxt, api, elapsed, result
proc makeMultiKeys*(ldg: LedgerRef): MultiKeysRef = proc makeMultiKeys*(ldg: LedgerRef): MultiKeysRef =
ldg.beginTrackApi LdgMakeMultiKeysFn ldg.beginTrackApi LdgMakeMultiKeysFn
result = ldg.methods.makeMultiKeysFn() result = ldg.methods.makeMultiKeysFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc persist*(ldg: LedgerRef, clearEmptyAccount = false, clearCache = true) = proc persist*(ldg: LedgerRef, clearEmptyAccount = false, clearCache = true) =
ldg.beginTrackApi LdgPersistFn ldg.beginTrackApi LdgPersistFn
ldg.methods.persistFn(clearEmptyAccount, clearCache) 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) = proc ripemdSpecial*(ldg: LedgerRef) =
ldg.beginTrackApi LdgRipemdSpecialFn ldg.beginTrackApi LdgRipemdSpecialFn
ldg.methods.ripemdSpecialFn() ldg.methods.ripemdSpecialFn()
ldg.ifTrackApi: debug apiTxt, ctx ldg.ifTrackApi: debug apiTxt, api, elapsed
proc rollback*(ldg: LedgerRef, sp: LedgerSpRef) = proc rollback*(ldg: LedgerRef, sp: LedgerSpRef) =
ldg.beginTrackApi LdgRollbackFn ldg.beginTrackApi LdgRollbackFn
ldg.methods.rollbackFn sp ldg.methods.rollbackFn sp
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc rootHash*(ldg: LedgerRef): Hash256 = proc rootHash*(ldg: LedgerRef): Hash256 =
ldg.beginTrackApi LdgRootHashFn ldg.beginTrackApi LdgRootHashFn
result = ldg.methods.rootHashFn() result = ldg.methods.rootHashFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result ldg.ifTrackApi: debug apiTxt, api, elapsed, result
proc safeDispose*(ldg: LedgerRef, sp: LedgerSpRef) = proc safeDispose*(ldg: LedgerRef, sp: LedgerSpRef) =
ldg.beginTrackApi LdgSafeDisposeFn ldg.beginTrackApi LdgSafeDisposeFn
ldg.methods.safeDisposeFn sp ldg.methods.safeDisposeFn sp
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc selfDestruct*(ldg: LedgerRef, eAddr: EthAddress) = proc selfDestruct*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgSelfDestructFn ldg.beginTrackApi LdgSelfDestructFn
ldg.methods.selfDestructFn eAddr ldg.methods.selfDestructFn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc selfDestruct6780*(ldg: LedgerRef, eAddr: EthAddress) = proc selfDestruct6780*(ldg: LedgerRef, eAddr: EthAddress) =
ldg.beginTrackApi LdgSelfDestruct6780Fn ldg.beginTrackApi LdgSelfDestruct6780Fn
ldg.methods.selfDestruct6780Fn eAddr ldg.methods.selfDestruct6780Fn eAddr
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
proc selfDestructLen*(ldg: LedgerRef): int = proc selfDestructLen*(ldg: LedgerRef): int =
ldg.beginTrackApi LdgSelfDestructLenFn ldg.beginTrackApi LdgSelfDestructLenFn
result = ldg.methods.selfDestructLenFn() 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) = proc setBalance*(ldg: LedgerRef, eAddr: EthAddress, balance: UInt256) =
ldg.beginTrackApi LdgSetBalanceFn ldg.beginTrackApi LdgSetBalanceFn
ldg.methods.setBalanceFn(eAddr, balance) 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) = proc setCode*(ldg: LedgerRef, eAddr: EthAddress, code: Blob) =
ldg.beginTrackApi LdgSetCodeFn ldg.beginTrackApi LdgSetCodeFn
ldg.methods.setCodeFn(eAddr, code) 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) = proc setNonce*(ldg: LedgerRef, eAddr: EthAddress, nonce: AccountNonce) =
ldg.beginTrackApi LdgSetNonceFn ldg.beginTrackApi LdgSetNonceFn
ldg.methods.setNonceFn(eAddr, nonce) 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) = proc setStorage*(ldg: LedgerRef, eAddr: EthAddress, slot, val: UInt256) =
ldg.beginTrackApi LdgSetStorageFn ldg.beginTrackApi LdgSetStorageFn
ldg.methods.setStorageFn(eAddr, slot, val) 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*( proc setTransientStorage*(
ldg: LedgerRef; ldg: LedgerRef;
@ -345,17 +345,17 @@ proc setTransientStorage*(
) = ) =
ldg.beginTrackApi LdgSetTransientStorageFn ldg.beginTrackApi LdgSetTransientStorageFn
ldg.methods.setTransientStorageFn(eAddr, slot, val) 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) = proc subBalance*(ldg: LedgerRef, eAddr: EthAddress, delta: UInt256) =
ldg.beginTrackApi LdgSubBalanceFn ldg.beginTrackApi LdgSubBalanceFn
ldg.methods.subBalanceFn(eAddr, delta) 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 = proc getAccessList*(ldg: LedgerRef): AccessList =
ldg.beginTrackApi LdgGetAccessListFn ldg.beginTrackApi LdgGetAccessListFn
result = ldg.methods.getAccessListFn() result = ldg.methods.getAccessListFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Public methods, extensions to go away # Public methods, extensions to go away
@ -364,12 +364,12 @@ proc getAccessList*(ldg: LedgerRef): AccessList =
proc getMpt*(ldg: LedgerRef): CoreDbMptRef = proc getMpt*(ldg: LedgerRef): CoreDbMptRef =
ldg.beginTrackApi LdgGetMptFn ldg.beginTrackApi LdgGetMptFn
result = ldg.extras.getMptFn() result = ldg.extras.getMptFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result ldg.ifTrackApi: debug apiTxt, api, elapsed, result
proc rawRootHash*(ldg: LedgerRef): Hash256 = proc rawRootHash*(ldg: LedgerRef): Hash256 =
ldg.beginTrackApi LdgRawRootHashFn ldg.beginTrackApi LdgRawRootHashFn
result = ldg.extras.rawRootHashFn() result = ldg.extras.rawRootHashFn()
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, result ldg.ifTrackApi: debug apiTxt, api, elapsed, result
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Public virtual read-only methods # Public virtual read-only methods

View File

@ -112,13 +112,13 @@ func toStr*(ela: Duration): string =
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
template beginApi*(ldg: LedgerRef; s: static[LedgerFnInx]) = 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 let baStart {.inject.} = getTime() # Local use only
template endApiIf*(ldg: LedgerRef; code: untyped) = template endApiIf*(ldg: LedgerRef; code: untyped) =
when CoreDbEnableApiProfiling: when CoreDbEnableApiProfiling:
let elapsed {.inject,used.} = getTime() - baStart 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: if ldg.trackApi:
when not CoreDbEnableApiProfiling: # otherwise use variable above when not CoreDbEnableApiProfiling: # otherwise use variable above
let elapsed {.inject,used.} = getTime() - baStart let elapsed {.inject,used.} = getTime() - baStart

View File

@ -47,7 +47,7 @@ iterator accounts*(ldg: LedgerRef): Account =
yield w yield w
else: else:
raiseAssert: "Unsupported ledger type: " & $ldg.ldgType raiseAssert: "Unsupported ledger type: " & $ldg.ldgType
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
iterator addresses*(ldg: LedgerRef): EthAddress = iterator addresses*(ldg: LedgerRef): EthAddress =
@ -61,7 +61,7 @@ iterator addresses*(ldg: LedgerRef): EthAddress =
yield w yield w
else: else:
raiseAssert: "Unsupported ledger type: " & $ldg.ldgType 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) = iterator cachedStorage*(ldg: LedgerRef, eAddr: EthAddress): (UInt256,UInt256) =
@ -75,7 +75,7 @@ iterator cachedStorage*(ldg: LedgerRef, eAddr: EthAddress): (UInt256,UInt256) =
yield w yield w
else: else:
raiseAssert: "Unsupported ledger type: " & $ldg.ldgType 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) = iterator pairs*(ldg: LedgerRef): (EthAddress,Account) =
@ -89,7 +89,7 @@ iterator pairs*(ldg: LedgerRef): (EthAddress,Account) =
yield w yield w
else: else:
raiseAssert: "Unsupported ledger type: " & $ldg.ldgType raiseAssert: "Unsupported ledger type: " & $ldg.ldgType
ldg.ifTrackApi: debug apiTxt, ctx, elapsed ldg.ifTrackApi: debug apiTxt, api, elapsed
iterator storage*( iterator storage*(
@ -107,7 +107,7 @@ iterator storage*(
yield w yield w
else: else:
raiseAssert: "Unsupported ledger type: " & $ldg.ldgType raiseAssert: "Unsupported ledger type: " & $ldg.ldgType
ldg.ifTrackApi: debug apiTxt, ctx, elapsed, eAddr ldg.ifTrackApi: debug apiTxt, api, elapsed, eAddr
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# End # End

View File

@ -90,7 +90,7 @@ proc init*(
root: Hash256; root: Hash256;
pruneOk = true; pruneOk = true;
): T = ): T =
db.newAccMpt(root, pruneOk).T db.ctx.getAccMpt(root, pruneOk).T
proc init*( proc init*(
T: type AccountLedger; T: type AccountLedger;
@ -159,9 +159,10 @@ proc init*(
if rc.isErr: if rc.isErr:
raiseAssert "re-hash oops, error=" & $$rc.error raiseAssert "re-hash oops, error=" & $$rc.error
let 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: mpt = block:
let rc = db.newMpt(trie, pruneOk) let rc = ctx.getMpt(trie, pruneOk)
if rc.isErr: if rc.isErr:
raiseAssert info & $$rc.error raiseAssert info & $$rc.error
rc.value rc.value
@ -195,7 +196,7 @@ iterator storage*(
info = "storage(): " info = "storage(): "
let trie = account.stoTrie let trie = account.stoTrie
if not trie.isNil: if not trie.isNil:
let mpt = al.distinctBase.parent.newMpt(trie).valueOr: let mpt = al.distinctBase.parent.ctx.getMpt(trie).valueOr:
raiseAssert info & $$error raiseAssert info & $$error
for (key,val) in mpt.pairs: for (key,val) in mpt.pairs:
yield (key,val) yield (key,val)