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

View File

@ -24,8 +24,12 @@ import
type
AristoBaseRef* = ref object
parent: CoreDbRef ## Opaque top level descriptor
adb: AristoDbRef ## Aristo MPT database
api*: AristoApiRef ## Api functions can be re-directed
ctx*: AristoCoreDbCtxRef ## Currently active context
AristoCoreDbCtxRef = ref object of CoreDbCtxRef
base: AristoBaseRef ## Local base descriptor
mpt: AristoDbRef ## Aristo MPT database
AristoCoreDxAccRef = ref object of CoreDxAccRef
base: AristoBaseRef ## Local base descriptor
@ -71,11 +75,6 @@ static:
# Private helpers
# ------------------------------------------------------------------------------
template logTxt(info: static[string]): static[string] =
"CoreDb/adb " & info
# -------------------------------
func isValid(trie: CoreDbTrieRef): bool =
not trie.isNil and trie.ready
@ -177,46 +176,63 @@ func toVoidRc[T](
return ok()
err rc.error.toError(base, info, error)
# -------------------------------
proc tryHash(
base: AristoBaseRef;
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[Hash256] =
let trie = trie.AristoCoreDbTrie
if not trie.isValid:
return err(TrieInvalid.toError(base, info, HashNotAvailable))
let root = trie.to(VertexID)
if not root.isValid:
return ok(EMPTY_ROOT_HASH)
let rc = base.api.getKeyRc(trie.base.ctx.mpt, root)
if rc.isErr:
return err(rc.error.toError(base, info, HashNotAvailable))
ok rc.value.to(Hash256)
# ------------------------------------------------------------------------------
# Private `MPT` call back functions
# ------------------------------------------------------------------------------
proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
## Hexary trie database handlers
let
cMpt = cMpt # So it can savely be captured
base = cMpt.base # Will not change and can be captured
db = base.parent # Ditto
api = base.api # Ditto
mpt = base.ctx.mpt # Ditto
proc mptBackend(
cMpt: AristoCoreDxMptRef;
): CoreDbMptBackendRef =
let base = cMpt.base
base.parent.bless AristoCoreDbMptBE(adb: base.adb)
proc mptBackend(): CoreDbMptBackendRef =
db.bless AristoCoreDbMptBE(adb: mpt)
proc mptTrieFn(
cMpt: AristoCoreDxMptRef;
): CoreDbTrieRef =
proc mptTrieFn(): CoreDbTrieRef =
let trie =
if LEAST_FREE_VID <= cMpt.root.distinctBase:
assert cMpt.accPath.isValid # debug mode only
AristoCoreDbTrie(
base: cMpt.base,
base: base,
kind: StorageTrie,
stoRoot: cMpt.root,
stoAddr: cMpt.address)
else:
AristoCoreDbTrie(
base: cMpt.base,
base: base,
kind: CoreDbSubTrie(cMpt.root))
cMpt.base.parent.bless trie
db.bless trie
proc mptPersistent(
cMpt: AristoCoreDxMptRef;
info: static[string];
): CoreDbRc[void] =
let
base = cMpt.base
mpt = base.adb
api = base.api
rc = api.stow(mpt, persistent = true)
proc mptPersistent(): CoreDbRc[void] =
const info = "persistentFn()"
let rc = api.stow(mpt, persistent = true)
if rc.isOk:
ok()
elif api.level(mpt) == 0:
@ -224,25 +240,17 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
else:
err(rc.error.toError(base, info, MptTxPending))
proc mptFetch(
cMpt: AristoCoreDxMptRef;
k: openArray[byte];
info: static[string];
): CoreDbRc[Blob] =
let
base = cMpt.base
root = cMpt.root
proc mptFetch(key: openArray[byte]): CoreDbRc[Blob] =
const info = "fetchFn()"
# Some pathological behaviour observed with storage tries due to lazy
# update. The `fetchPayload()` does not now about this and would complain
# an error different from `FetchPathNotFound`.
let root = cMpt.root
if not root.isValid:
return err((VoidTrieID,MptRootMissing).toError(base, info, MptNotFound))
let
mpt = base.adb
api = base.api
rc = api.fetchPayload(mpt, root, k)
let rc = api.fetchPayload(mpt, root, key)
if rc.isOk:
api.serialise(mpt, rc.value).toRc(base, info)
elif rc.error[1] != FetchPathNotFound:
@ -250,19 +258,11 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
else:
err rc.error.toError(base, info, MptNotFound)
proc mptMerge(
cMpt: AristoCoreDxMptRef;
k: openArray[byte];
v: openArray[byte];
info: static[string];
): CoreDbRc[void] =
let
base = cMpt.base
api = base.api
mpt = base.adb
rootOk = cMpt.root.isValid
proc mptMerge(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
const info = "mergeFn()"
# Provide root ID on-the-fly
let rootOk = cMpt.root.isValid
if not rootOk:
cMpt.root = api.vidFetch(mpt, pristine=true)
@ -275,22 +275,15 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
return err(rc.error.toError(base, info))
ok()
proc mptDelete(
cMpt: AristoCoreDxMptRef;
k: openArray[byte];
info: static[string];
): CoreDbRc[void] =
let
base = cMpt.base
api = base.api
mpt = base.adb
proc mptDelete(key: openArray[byte]): CoreDbRc[void] =
const info = "deleteFn()"
if not cMpt.root.isValid and cMpt.accPath.isValid:
# This is insane but legit. A storage trie was announced for an account
# but no data have been added, yet.
return ok()
let rc = api.delete(mpt, cMpt.root, k, cMpt.accPath)
let rc = api.delete(mpt, cMpt.root, key, cMpt.accPath)
if rc.isErr:
if rc.error[1] == DelPathNotFound:
return err(rc.error.toError(base, info, MptNotFound))
@ -301,47 +294,39 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
cMpt.root = VoidTrieID
ok()
proc mptHasPath(
cMpt: AristoCoreDxMptRef;
key: openArray[byte];
info: static[string];
): CoreDbRc[bool] =
let
base = cMpt.base
mpt = base.adb
api = base.api
rc = api.hasPath(mpt, cMpt.root, key)
proc mptHasPath(key: openArray[byte]): CoreDbRc[bool] =
const info = "hasPathFn()"
let rc = api.hasPath(mpt, cMpt.root, key)
if rc.isErr:
return err(rc.error.toError(base, info))
ok(rc.value)
CoreDbMptFns(
backendFn: proc(): CoreDbMptBackendRef =
cMpt.mptBackend(),
mptBackend(),
fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] =
cMpt.mptFetch(k, "fetchFn()"),
mptFetch(k),
deleteFn: proc(k: openArray[byte]): CoreDbRc[void] =
cMpt.mptDelete(k, "deleteFn()"),
mptDelete(k),
mergeFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
cMpt.mptMerge(k, v, "mergeFn()"),
mptMerge(k, v),
hasPathFn: proc(k: openArray[byte]): CoreDbRc[bool] =
cMpt.mptHasPath(k, "hasPathFn()"),
mptHasPath(k),
getTrieFn: proc(): CoreDbTrieRef =
cMpt.mptTrieFn(),
mptTrieFn(),
isPruningFn: proc(): bool =
true,
persistentFn: proc(): CoreDbRc[void] =
cMpt.mptPersistent("persistentFn()"),
forgetFn: proc(): CoreDbRc[void] =
discard)
mptPersistent())
# ------------------------------------------------------------------------------
# Private account call back functions
@ -349,30 +334,25 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
## Hexary trie database handlers
let
cAcc = cAcc # So it can savely be captured
base = cAcc.base # Will not change and can be captured
db = base.parent # Ditto
api = base.api # Ditto
mpt = base.ctx.mpt # Ditto
proc accBackend(
cAcc: AristoCoreDxAccRef;
): CoreDbAccBackendRef =
let base = cAcc.base
base.parent.bless AristoCoreDbAccBE(adb: base.adb)
proc accBackend(): CoreDbAccBackendRef =
db.bless AristoCoreDbAccBE(adb: mpt)
proc getTrieFn(
cMpt: AristoCoreDxAccRef;
): CoreDbTrieRef =
let base = cAcc.base
base.parent.bless AristoCoreDbTrie(
proc getTrieFn(): CoreDbTrieRef =
db.bless AristoCoreDbTrie(
base: base,
kind: AccountsTrie)
proc accPersistent(
cAcc: AristoCoreDxAccRef;
info: static[string];
): CoreDbRc[void] =
let
base = cAcc.base
mpt = base.adb
api = base.api
rc = api.stow(mpt, persistent = true)
proc accPersistent(): CoreDbRc[void] =
const info = "persistentFn()"
let rc = api.stow(mpt, persistent = true)
if rc.isOk:
ok()
elif api.level(mpt) == 0:
@ -380,64 +360,45 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
else:
err(rc.error.toError(base, info, AccTxPending))
proc accCloneMpt(
cAcc: AristoCoreDxAccRef;
info: static[string];
): CoreDbRc[CoreDxMptRef] =
proc accCloneMpt(): CoreDbRc[CoreDxMptRef] =
ok(AristoCoreDxMptRef(
base: cAcc.base,
base: base,
root: AccountsTrieID))
proc accFetch(
cAcc: AristoCoreDxAccRef;
address: EthAddress;
info: static[string];
): CoreDbRc[CoreDbAccount] =
let
base = cAcc.base
api = base.api
mpt = base.adb
pyl = block:
let
key = address.keccakHash.data
rc = api.fetchPayload(mpt, AccountsTrieID, key)
if rc.isOk:
rc.value
elif rc.error[1] != FetchPathNotFound:
return err(rc.error.toError(base, info))
else:
return err(rc.error.toError(base, info, AccNotFound))
proc accFetch(address: EthAddress): CoreDbRc[CoreDbAccount] =
const info = "fetchFn()"
let pyl = block:
let
key = address.keccakHash.data
rc = api.fetchPayload(mpt, AccountsTrieID, key)
if rc.isOk:
rc.value
elif rc.error[1] != FetchPathNotFound:
return err(rc.error.toError(base, info))
else:
return err(rc.error.toError(base, info, AccNotFound))
if pyl.pType != AccountData:
let vePair = (pyl.account.storageID, PayloadTypeUnsupported)
return err(vePair.toError(base, info & "/" & $pyl.pType))
let vidErrPair = (pyl.account.storageID, PayloadTypeUnsupported)
return err(vidErrPair.toError(base, info & "/" & $pyl.pType))
ok cAcc.toCoreDbAccount(pyl.account, address)
proc accMerge(
cAcc: AristoCoreDxAccRef;
acc: CoreDbAccount;
info: static[string];
): CoreDbRc[void] =
proc accMerge(account: CoreDbAccount): CoreDbRc[void] =
const info = "mergeFn()"
let
base = cAcc.base
api = base.api
mpt = base.adb
key = acc.address.keccakHash.data
val = acc.toPayloadRef()
key = account.address.keccakHash.data
val = account.toPayloadRef()
rc = api.mergePayload(mpt, AccountsTrieID, key, val)
if rc.isErr:
return err(rc.error.toError(base, info))
ok()
proc accDelete(
cAcc: AristoCoreDxAccRef;
address: EthAddress;
info: static[string];
): CoreDbRc[void] =
proc accDelete(address: EthAddress): CoreDbRc[void] =
const info = "deleteFn()"
let
base = cAcc.base
api = base.api
mpt = base.adb
key = address.keccakHash.data
rc = api.delete(mpt, AccountsTrieID, key, VOID_PATH_ID)
if rc.isErr:
@ -446,15 +407,10 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
return err(rc.error.toError(base, info))
ok()
proc accStoFlush(
cAcc: AristoCoreDxAccRef;
address: EthAddress;
info: static[string];
): CoreDbRc[void] =
proc accStoFlush(address: EthAddress): CoreDbRc[void] =
const info = "stoFlushFn()"
let
base = cAcc.base
api = base.api
mpt = base.adb
key = address.keccakHash.data
pyl = api.fetchPayload(mpt, AccountsTrieID, key).valueOr:
return ok()
@ -468,53 +424,185 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
return err(rc.error.toError(base, info))
ok()
proc accHasPath(
cAcc: AristoCoreDxAccRef;
address: EthAddress;
info: static[string];
): CoreDbRc[bool] =
proc accHasPath(address: EthAddress): CoreDbRc[bool] =
const info = "hasPathFn()"
let
base = cAcc.base
api = cAcc.base.api
mpt = cAcc.base.adb
key = address.keccakHash.data
rc = api.hasPath(mpt, AccountsTrieID, key)
if rc.isErr:
return err(rc.error.toError(base, info))
ok(rc.value)
CoreDbAccFns(
backendFn: proc(): CoreDbAccBackendRef =
cAcc.accBackend(),
accBackend(),
newMptFn: proc(): CoreDbRc[CoreDxMptRef] =
cAcc.accCloneMpt("newMptFn()"),
getMptFn: proc(): CoreDbRc[CoreDxMptRef] =
accCloneMpt(),
fetchFn: proc(address: EthAddress): CoreDbRc[CoreDbAccount] =
cAcc.accFetch(address, "fetchFn()"),
accFetch(address),
deleteFn: proc(address: EthAddress): CoreDbRc[void] =
cAcc.accDelete(address, "deleteFn()"),
accDelete(address),
stoFlushFn: proc(address: EthAddress): CoreDbRc[void] =
cAcc.accStoFlush(address, "stoFlushFn()"),
accStoFlush(address),
mergeFn: proc(acc: CoreDbAccount): CoreDbRc[void] =
cAcc.accMerge(acc, "mergeFn()"),
accMerge(acc),
hasPathFn: proc(address: EthAddress): CoreDbRc[bool] =
cAcc.accHasPath(address, "hasPathFn()"),
accHasPath(address),
getTrieFn: proc(): CoreDbTrieRef =
cAcc.getTrieFn(),
getTrieFn(),
isPruningFn: proc(): bool =
true,
persistentFn: proc(): CoreDbRc[void] =
cAcc.accPersistent("persistentFn()"),
accPersistent())
forgetFn: proc(): CoreDbRc[void] =
# ------------------------------------------------------------------------------
# Private context call back functions
# ------------------------------------------------------------------------------
proc ctxMethods(cCtx: AristoCoreDbCtxRef): CoreDbCtxFns =
let
cCtx = cCtx # So it can savely be captured
base = cCtx.base # Will not change and can be captured
db = base.parent # Ditto
api = base.api # Ditto
mpt = base.ctx.mpt # Ditto
proc ctxNewTrie(
kind: CoreDbSubTrie;
root: Hash256;
address: Option[EthAddress];
info: static[string];
): CoreDbRc[CoreDbTrieRef] =
let trie = AristoCoreDbTrie(
base: base,
kind: kind)
if kind == StorageTrie:
if address.isNone:
let error = aristo.UtilsAccPathMissing
return err(error.toError(base, info, AccAddrMissing))
trie.stoAddr = address.unsafeGet
if not root.isValid:
return ok(db.bless trie)
# Reset non-dynamic trie when instantiating. This applies to root IDs beween
# `VertexID(2) .. LEAST_FREE_VID`. It emulates the behaviour of a new empty
# MPT on the legacy database.
if AccountsTrie < kind and kind.ord < LEAST_FREE_VID:
trie.reset = true
# Update hashes in order to verify the trie state root.
? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable)
# Make sure that the hash is available as state root on the main trie
let rc = api.getKeyRc(mpt, VertexID kind)
if rc.isErr:
doAssert rc.error == GetKeyNotFound
elif rc.value == root.to(HashKey):
return ok(db.bless trie)
err(aristo.GenericError.toError(base, info, RootNotFound))
proc ctxGetMpt(
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[CoreDxMptRef] =
let
trie = AristoCoreDbTrie(trie)
var
reset = false
newMpt: AristoCoreDxMptRef
if not trie.isValid:
reset = true
newMpt = AristoCoreDxMptRef(
root: GenericTrieID,
accPath: VOID_PATH_ID)
elif trie.kind == StorageTrie:
newMpt = AristoCoreDxMptRef(
root: trie.stoRoot,
accPath: trie.stoAddr.to(PathID),
address: trie.stoAddr)
if trie.stoRoot.isValid:
if trie.stoRoot.distinctBase < LEAST_FREE_VID:
let error = (trie.stoRoot,MptRootUnacceptable)
return err(error.toError(base, info, RootUnacceptable))
# Verify path if there is a particular storge root VID
let rc = api.hikeUp(newMpt.accPath.to(NibblesSeq), AccountsTrieID, mpt)
if rc.isErr:
return err(rc.error[1].toError(base, info, AccNotFound))
else:
reset = AccountsTrie < trie.kind
newMpt = AristoCoreDxMptRef(
root: VertexID(trie.kind),
accPath: VOID_PATH_ID)
# Reset trie. This a emulates the behaviour of a new empty MPT on the
# legacy database.
if reset:
let rc = api.delTree(mpt, newMpt.root, VOID_PATH_ID)
if rc.isErr:
return err(rc.error.toError(base, info, AutoFlushFailed))
trie.reset = false
newMpt.base = base
newMpt.methods = newMpt.mptMethods()
ok(db.bless newMpt)
proc ctxGetAcc(
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[CoreDxAccRef] =
let trie = AristoCoreDbTrie(trie)
if trie.kind != AccountsTrie:
let error = (AccountsTrieID, AccRootUnacceptable)
return err(error.toError(base, info, RootUnacceptable))
let acc = AristoCoreDxAccRef(base: base)
acc.methods = acc.accMethods()
ok(db.bless acc)
CoreDbCtxFns(
fromTxFn: proc(root: Hash256; kind: CoreDbSubTrie): CoreDbRc[CoreDbCtxRef] =
const info = "fromTxFn()"
err(aristo.NotImplemented.toError(base, info, base_desc.NotImplemented)),
swapFn: proc(cty: CoreDbCtxRef): CoreDbCtxRef =
doAssert not cty.isNil
base.ctx.swap(AristoCoreDbCtxRef(cty)),
newTrieFn: proc(
trie: CoreDbSubTrie;
root: Hash256;
address: Option[EthAddress];
): CoreDbRc[CoreDbTrieRef] =
ctxNewTrie(trie, root, address, "newTrieFn()"),
getMptFn: proc(trie: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxMptRef] =
ctxGetMpt(trie, "newMptFn()"),
getAccFn: proc(trie: CoreDbTrieRef; prune: bool): CoreDbRc[CoreDxAccRef] =
ctxGetAcc(trie, "newAccFn()"),
forgetFn: proc() =
api.forget(mpt).isOkOr:
raiseAssert "forgetFn(): " & $error
discard)
# ------------------------------------------------------------------------------
@ -546,7 +634,7 @@ func toVoidRc*[T](
# ---------------------
func to*(dsc: CoreDxMptRef, T: type AristoDbRef): T =
AristoCoreDxMptRef(dsc).base.adb
AristoCoreDxMptRef(dsc).base.ctx.mpt
func rootID*(dsc: CoreDxMptRef): VertexID =
dsc.AristoCoreDxMptRef.root
@ -561,31 +649,12 @@ proc txBegin*(
base: AristoBaseRef;
info: static[string];
): CoreDbRc[AristoTxRef] =
base.api.txBegin(base.adb).toRc(base, info)
base.api.txBegin(base.ctx.mpt).toRc(base, info)
# ---------------------
proc getLevel*(base: AristoBaseRef): int =
base.api.level(base.adb)
proc tryHash*(
base: AristoBaseRef;
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[Hash256] =
let trie = trie.AristoCoreDbTrie
if not trie.isValid:
return err(TrieInvalid.toError(base, info, HashNotAvailable))
let root = trie.to(VertexID)
if not root.isValid:
return ok(EMPTY_ROOT_HASH)
let rc = base.api.getKeyRc(trie.base.adb, root)
if rc.isErr:
return err(rc.error.toError(base, info, HashNotAvailable))
ok rc.value.to(Hash256)
base.api.level(base.ctx.mpt)
proc triePrint*(
base: AristoBaseRef;
@ -626,7 +695,7 @@ proc rootHash*(
let
api = base.api
mpt = base.adb
mpt = base.ctx.mpt
? api.hashify(mpt).toVoidRc(base, info, HashNotAvailable)
let key = block:
@ -638,145 +707,29 @@ proc rootHash*(
ok key.to(Hash256)
proc newTrie*(
base: AristoBaseRef;
kind: CoreDbSubTrie;
root: Hash256;
address: Option[EthAddress];
info: static[string];
): CoreDbRc[CoreDbTrieRef] =
let
adb = base.adb
api = base.api
trie = AristoCoreDbTrie(
base: base,
kind: kind)
if kind == StorageTrie:
if address.isNone:
let error = aristo.UtilsAccPathMissing
return err(error.toError(base, info, AccAddrMissing))
trie.stoAddr = address.unsafeGet
if not root.isValid:
return ok(base.parent.bless trie)
# Reset non-dynamic trie when instantiating. This applies to root IDs beween
# `VertexID(2) .. LEAST_FREE_VID`. It emulates the behaviour of a new empty
# MPT on the legacy database.
if AccountsTrie < kind and kind.ord < LEAST_FREE_VID:
trie.reset = true
# Update hashes in order to verify the trie state root.
? api.hashify(adb).toVoidRc(base, info, HashNotAvailable)
# Make sure that the hash is available as state root on the main trie
let rc = api.getKeyRc(adb, VertexID kind)
if rc.isErr:
doAssert rc.error == GetKeyNotFound
elif rc.value == root.to(HashKey):
return ok(base.parent.bless trie)
err(aristo.GenericError.toError(base, info, RootNotFound))
# ------------------------------------------------------------------------------
# Public constructors and related
# ------------------------------------------------------------------------------
proc verify*(base: AristoBaseRef; trie: CoreDbTrieRef): bool =
let trie = trie.AristoCoreDbTrie
if not trie.base.isNil:
if trie.kind != StorageTrie:
return true
if LEAST_FREE_VID < trie.stoRoot.distinctBase:
let path = trie.stoAddr.to(PathID).to(NibblesSeq)
if base.api.hikeUp(path, AccountsTrieID, base.adb).isOk:
return true
false
proc newMptHandler*(
base: AristoBaseRef;
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[CoreDxMptRef] =
let
trie = AristoCoreDbTrie(trie)
api = base.api
var
reset = false
mpt: AristoCoreDxMptRef
if not trie.isValid:
reset = true
mpt = AristoCoreDxMptRef(
root: GenericTrieID,
accPath: VOID_PATH_ID)
elif trie.kind == StorageTrie:
mpt = AristoCoreDxMptRef(
root: trie.stoRoot,
accPath: trie.stoAddr.to(PathID),
address: trie.stoAddr)
if trie.stoRoot.isValid:
if trie.stoRoot.distinctBase < LEAST_FREE_VID:
let error = (trie.stoRoot,MptRootUnacceptable)
return err(error.toError(base, info, RootUnacceptable))
# Verify path if there is a particular storge root VID
let rc = api.hikeUp(mpt.accPath.to(NibblesSeq), AccountsTrieID, base.adb)
if rc.isErr:
return err(rc.error[1].toError(base, info, AccNotFound))
else:
reset = AccountsTrie < trie.kind
mpt = AristoCoreDxMptRef(
root: VertexID(trie.kind),
accPath: VOID_PATH_ID)
# Reset trie. This a emulates the behaviour of a new empty MPT on the
# legacy database.
if reset:
let rc = base.api.delTree(base.adb, mpt.root, VOID_PATH_ID)
if rc.isErr:
return err(rc.error.toError(base, info, AutoFlushFailed))
trie.reset = false
mpt.base = base
mpt.methods = mpt.mptMethods()
ok(base.parent.bless mpt)
proc newAccHandler*(
base: AristoBaseRef;
trie: CoreDbTrieRef;
info: static[string];
): CoreDbRc[CoreDxAccRef] =
let trie = AristoCoreDbTrie(trie)
if trie.kind != AccountsTrie:
let error = (AccountsTrieID, AccRootUnacceptable)
return err(error.toError(base, info, RootUnacceptable))
let acc = AristoCoreDxAccRef(base: base)
acc.methods = acc.accMethods()
ok(base.parent.bless acc)
proc destroy*(base: AristoBaseRef; flush: bool) =
base.api.finish(base.adb, flush)
base.api.finish(base.ctx.mpt, flush)
func init*(T: type AristoBaseRef; db: CoreDbRef; adb: AristoDbRef): T =
result = T(
parent: db,
api: AristoApiRef.init(),
adb: adb)
api: AristoApiRef.init())
# Create initial context
result.ctx = db.bless AristoCoreDbCtxRef(
base: result,
mpt: adb)
result.ctx.methods = result.ctx.ctxMethods
when CoreDbEnableApiProfiling:
let profApi = AristoApiProfRef.init(result.api, adb.backend)
result.api = profApi
result.adb.backend = profApi.be
result.ctx.mpt.backend = profApi.be
# ------------------------------------------------------------------------------
# End

View File

@ -28,6 +28,7 @@ type
kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor
tdb: TrieDatabaseRef ## Descriptor reference copy captured with closures
top: LegacyCoreDxTxRef ## Top transaction (if any)
ctx: LegacyCoreDbCtxRef ## Cache, there is only one context here
level: int ## Debugging
LegacyDbClose* = proc() {.gcsafe, raises: [].}
@ -40,6 +41,10 @@ type
address: Option[EthAddress] ## For storage tree debugging
accPath: Blob ## For storage tree debugging
LegacyCoreDbCtxRef = ref object of CoreDbCtxRef
## Context (there is only one context here)
base: LegacyDbRef
LegacyCoreDxTxRef = ref object of CoreDxTxRef
ltx: DbTransaction ## Legacy transaction descriptor
back: LegacyCoreDxTxRef ## Previous transaction
@ -312,9 +317,6 @@ proc mptMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbMptFns =
if 0 < db.txLevel():
const info = "persistentFn()"
return err(db.bless(MptTxPending, LegacyCoreDbError(ctx: info)))
ok(),
forgetFn: proc(): CoreDbRc[void] =
ok())
proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
@ -323,7 +325,7 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
backendFn: proc(): CoreDbAccBackendRef =
db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)),
newMptFn: proc(): CoreDbRc[CoreDxMptRef] =
getMptFn: proc(): CoreDbRc[CoreDxMptRef] =
let xMpt = HexaryChildDbRef(trie: mpt.trie)
ok(db.bless CoreDxMptRef(methods: xMpt.mptMethods db)),
@ -367,11 +369,68 @@ proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
if 0 < db.txLevel():
const info = "persistentFn()"
return err(db.bless(AccTxPending, LegacyCoreDbError(ctx: info)))
ok(),
forgetFn: proc(): CoreDbRc[void] =
ok())
proc ctxMethods(ctx: LegacyCoreDbCtxRef): CoreDbCtxFns =
let
db = ctx.base
tdb = db.tdb
CoreDbCtxFns(
fromTxFn: proc(
root: Hash256;
kind: CoreDbSubTrie;
): CoreDbRc[CoreDbCtxRef] =
# This is not 100% on the tx layer but should work anyway with
# the application as it emulates sort of `Aristo` behaviour.
if db.tdb.contains root.data:
return ok(ctx)
err(db.bless(CtxNotFound, LegacyCoreDbError(ctx: "fromTxFn()"))),
swapFn: proc(cty: CoreDbCtxRef): CoreDbCtxRef =
doAssert cty == ctx
ctx,
newTrieFn: proc(
kind: CoreDbSubTrie;
root: Hash256;
address: Option[EthAddress];
): CoreDbRc[CoreDbTrieRef] =
var trie = LegacyCoreDbTrie(root: root)
when CoreDbEnableApiTracking:
trie.kind = kind
trie.address = address
if address.isSome:
trie.accPath = @(address.unsafeGet.keccakHash.data)
ok(db.bless trie),
getMptFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxMptRef] =
var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune))
when CoreDbEnableApiTracking:
if not trie.isNil and trie.ready:
let trie = trie.LegacyCoreDbTrie
mpt.kind = trie.kind
mpt.address = trie.address
mpt.accPath = trie.accPath
ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)),
getAccFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxAccRef] =
var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune))
when CoreDbEnableApiTracking:
if not trie.isNil and trie.ready:
if trie.LegacyCoreDbTrie.kind != AccountsTrie:
let ctx = LegacyCoreDbError(
ctx: "newAccFn()",
msg: "got " & $trie.LegacyCoreDbTrie.kind)
return err(db.bless(RootUnacceptable, ctx))
mpt.kind = AccountsTrie
ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)),
forgetFn: proc() =
discard)
proc txMethods(tx: CoreDxTxRef): CoreDbTxFns =
let tx = tx.LegacyCoreDxTxRef
@ -405,12 +464,6 @@ proc txMethods(tx: CoreDxTxRef): CoreDbTxFns =
tx.pop()
ok())
proc tidMethods(tid: TransactionID; tdb: TrieDatabaseRef): CoreDbTxIdFns =
CoreDbTxIdFns(
roWrapperFn: proc(action: CoreDbTxIdActionFn): CoreDbRc[void] =
tdb.shortTimeReadOnly(tid, action())
ok())
proc cptMethods(cpt: RecorderRef; db: LegacyDbRef): CoreDbCaptFns =
CoreDbCaptFns(
recorderFn: proc(): CoreDbRef =
@ -436,16 +489,6 @@ proc baseMethods(
): CoreDbBaseFns =
let tdb = db.tdb
CoreDbBaseFns(
verifyFn: proc(trie: CoreDbTrieRef): bool =
when CoreDbEnableApiTracking:
let trie = trie.LegacyCoreDbTrie
if trie.kind == StorageTrie:
if trie.root != EMPTY_ROOT_HASH and trie.address.isNone:
return false
else:
discard # at the moment
true,
backendFn: proc(): CoreDbBackendRef =
db.bless(LegacyCoreDbBE(base: db)),
@ -456,9 +499,6 @@ proc baseMethods(
if not closeDb.isNil:
closeDb(),
tryHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
ok(trie.lroot),
rootHashFn: proc(trie: CoreDbTrieRef): CoreDbRc[Hash256] =
ok(trie.lroot),
@ -471,46 +511,11 @@ proc baseMethods(
legacySetupFn: proc() =
db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]),
getTrieFn: proc(
kind: CoreDbSubTrie;
root: Hash256;
address: Option[EthAddress];
): CoreDbRc[CoreDbTrieRef] =
var trie = LegacyCoreDbTrie(root: root)
when CoreDbEnableApiTracking:
trie.kind = kind
trie.address = address
if address.isSome:
trie.accPath = @(address.unsafeGet.keccakHash.data)
ok(db.bless trie),
newKvtFn: proc(sharedTable = true): CoreDbRc[CoreDxKvtRef] =
ok(db.kvt),
newMptFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxMptRef] =
var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune))
when CoreDbEnableApiTracking:
if not trie.isNil and trie.ready:
let trie = trie.LegacyCoreDbTrie
mpt.kind = trie.kind
mpt.address = trie.address
mpt.accPath = trie.accPath
ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)),
newAccFn: proc(trie: CoreDbTrieRef, prune: bool): CoreDbRc[CoreDxAccRef] =
var mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, trie.lroot, prune))
when CoreDbEnableApiTracking:
if not trie.isNil and trie.ready:
if trie.LegacyCoreDbTrie.kind != AccountsTrie:
let ctx = LegacyCoreDbError(
ctx: "newAccFn()",
msg: "got " & $trie.LegacyCoreDbTrie.kind)
return err(db.bless(RootUnacceptable, ctx))
mpt.kind = AccountsTrie
ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)),
getIdFn: proc(): CoreDbRc[CoreDxTxID] =
ok(db.bless CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb))),
getCtxFn: proc(): CoreDbCtxRef =
db.ctx,
beginFn: proc(): CoreDbRc[CoreDxTxRef] =
db.top = LegacyCoreDxTxRef(
@ -543,6 +548,12 @@ proc init*(
# Base descriptor
db.dbType = dbType
db.methods = db.baseMethods(dbType, closeDb)
# Blind context layer
let ctx = LegacyCoreDbCtxRef(base: db)
ctx.methods = ctx.ctxMethods
db.ctx = db.bless ctx
db.bless
# ------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -112,13 +112,13 @@ func toStr*(ela: Duration): string =
# ------------------------------------------------------------------------------
template beginApi*(ldg: LedgerRef; s: static[LedgerFnInx]) =
const ctx {.inject,used.} = s # Generally available
const api {.inject,used.} = s # Generally available
let baStart {.inject.} = getTime() # Local use only
template endApiIf*(ldg: LedgerRef; code: untyped) =
when CoreDbEnableApiProfiling:
let elapsed {.inject,used.} = getTime() - baStart
aristo_profile.update(ldg.profTab, ctx.ord, elapsed)
aristo_profile.update(ldg.profTab, api.ord, elapsed)
if ldg.trackApi:
when not CoreDbEnableApiProfiling: # otherwise use variable above
let elapsed {.inject,used.} = getTime() - baStart

View File

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

View File

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