Skip to content

Commit

Permalink
Simplify state root api (#2864)
Browse files Browse the repository at this point in the history
`updateOk` is obsolete and always set to true - callers should not have
to care about this detail

also take the opportunity to clean up storage root naming
  • Loading branch information
arnetheduck authored Nov 22, 2024
1 parent ac2f3a4 commit 652539e
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 84 deletions.
30 changes: 13 additions & 17 deletions nimbus/db/aristo/aristo_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,11 @@ type
{.noRaise.}
## Fetch an account record from the database indexed by `accPath`.

AristoApiFetchAccountStateRootFn* =
AristoApiFetchStateRootFn* =
proc(db: AristoDbRef;
updateOk: bool;
): Result[Hash32,AristoError]
{.noRaise.}
## Fetch the Merkle hash of the account root. Force update if the
## argument `updateOK` is set `true`.
## Fetch the Merkle hash of the account root.

AristoApiFetchStorageDataFn* =
proc(db: AristoDbRef;
Expand All @@ -113,11 +111,9 @@ type
AristoApiFetchStorageRootFn* =
proc(db: AristoDbRef;
accPath: Hash32;
updateOk: bool;
): Result[Hash32,AristoError]
{.noRaise.}
## Fetch the Merkle hash of the storage root related to `accPath`. Force
## update if the argument `updateOK` is set `true`.
## Fetch the Merkle hash of the storage root related to `accPath`.

AristoApiFindTxFn* =
proc(db: AristoDbRef;
Expand Down Expand Up @@ -425,7 +421,7 @@ type
fetchLastSavedState*: AristoApiFetchLastSavedStateFn

fetchAccountRecord*: AristoApiFetchAccountRecordFn
fetchAccountStateRoot*: AristoApiFetchAccountStateRootFn
fetchStateRoot*: AristoApiFetchStateRootFn
fetchStorageData*: AristoApiFetchStorageDataFn
fetchStorageRoot*: AristoApiFetchStorageRootFn

Expand Down Expand Up @@ -472,7 +468,7 @@ type
AristoApiProfFetchLastSavedStateFn = "fetchLastSavedState"

AristoApiProfFetchAccountRecordFn = "fetchAccountRecord"
AristoApiProfFetchAccountStateRootFn = "fetchAccountStateRoot"
AristoApiProfFetchStateRootFn = "fetchStateRoot"
AristoApiProfFetchStorageDataFn = "fetchStorageData"
AristoApiProfFetchStorageRootFn = "fetchStorageRoot"

Expand Down Expand Up @@ -534,7 +530,7 @@ when AutoValidateApiHooks:
doAssert not api.fetchLastSavedState.isNil

doAssert not api.fetchAccountRecord.isNil
doAssert not api.fetchAccountStateRoot.isNil
doAssert not api.fetchStateRoot.isNil
doAssert not api.fetchStorageData.isNil
doAssert not api.fetchStorageRoot.isNil

Expand Down Expand Up @@ -601,7 +597,7 @@ func init*(api: var AristoApiObj) =
api.fetchLastSavedState = fetchLastSavedState

api.fetchAccountRecord = fetchAccountRecord
api.fetchAccountStateRoot = fetchAccountStateRoot
api.fetchStateRoot = fetchStateRoot
api.fetchStorageData = fetchStorageData
api.fetchStorageRoot = fetchStorageRoot

Expand Down Expand Up @@ -650,7 +646,7 @@ func dup*(api: AristoApiRef): AristoApiRef =

fetchLastSavedState: api.fetchLastSavedState,
fetchAccountRecord: api.fetchAccountRecord,
fetchAccountStateRoot: api.fetchAccountStateRoot,
fetchStateRoot: api.fetchStateRoot,
fetchStorageData: api.fetchStorageData,
fetchStorageRoot: api.fetchStorageRoot,

Expand Down Expand Up @@ -742,20 +738,20 @@ func init*(
AristoApiProfFetchAccountRecordFn.profileRunner:
result = api.fetchAccountRecord(a, b)

profApi.fetchAccountStateRoot =
profApi.fetchStateRoot =
proc(a: AristoDbRef; b: bool): auto =
AristoApiProfFetchAccountStateRootFn.profileRunner:
result = api.fetchAccountStateRoot(a, b)
AristoApiProfFetchStateRootFn.profileRunner:
result = api.fetchStateRoot(a, b)

profApi.fetchStorageData =
proc(a: AristoDbRef; b, stoPath: Hash32): auto =
AristoApiProfFetchStorageDataFn.profileRunner:
result = api.fetchStorageData(a, b, stoPath)

profApi.fetchStorageRoot =
proc(a: AristoDbRef; b: Hash32; c: bool): auto =
proc(a: AristoDbRef; b: Hash32): auto =
AristoApiProfFetchStorageRootFn.profileRunner:
result = api.fetchStorageRoot(a, b, c)
result = api.fetchStorageRoot(a, b)

profApi.findTx =
proc(a: AristoDbRef; b: RootedVertexID; c: HashKey): auto =
Expand Down
25 changes: 8 additions & 17 deletions nimbus/db/aristo/aristo_fetch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,13 @@ proc retrieveAccountLeaf(
proc retrieveMerkleHash(
db: AristoDbRef;
root: VertexID;
updateOk: bool;
): Result[Hash32,AristoError] =
let key =
if updateOk:
db.computeKey((root, root)).valueOr:
if error == GetVtxNotFound:
return ok(EMPTY_ROOT_HASH)
return err(error)
else:
let (key, _) = db.getKeyRc((root, root)).valueOr:
if error == GetKeyNotFound:
return ok(EMPTY_ROOT_HASH) # empty sub-tree
return err(error)
key
db.computeKey((root, root)).valueOr:
if error == GetVtxNotFound:
return ok(EMPTY_ROOT_HASH)
return err(error)

ok key.to(Hash32)

proc hasAccountPayload(
Expand Down Expand Up @@ -219,12 +212,11 @@ proc fetchAccountRecord*(

ok leafVtx.lData.account

proc fetchAccountStateRoot*(
proc fetchStateRoot*(
db: AristoDbRef;
updateOk: bool;
): Result[Hash32,AristoError] =
## Fetch the Merkle hash of the account root.
db.retrieveMerkleHash(VertexID(1), updateOk)
db.retrieveMerkleHash(VertexID(1))

proc hasPathAccount*(
db: AristoDbRef;
Expand All @@ -248,14 +240,13 @@ proc fetchStorageData*(
proc fetchStorageRoot*(
db: AristoDbRef;
accPath: Hash32;
updateOk: bool;
): Result[Hash32,AristoError] =
## Fetch the Merkle hash of the storage root related to `accPath`.
let stoID = db.fetchStorageIdImpl(accPath).valueOr:
if error == FetchPathNotFound:
return ok(EMPTY_ROOT_HASH) # no sub-tree
return err(error)
db.retrieveMerkleHash(stoID, updateOk)
db.retrieveMerkleHash(stoID)

proc hasPathStorage*(
db: AristoDbRef;
Expand Down
20 changes: 9 additions & 11 deletions nimbus/db/core_db/backend/aristo_trace.nim
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ proc jLogger(
func to(w: AristoApiProfNames; T: type TracePfx): T =
case w:
of AristoApiProfFetchAccountRecordFn,
AristoApiProfFetchAccountStateRootFn,
AristoApiProfFetchStateRootFn,
AristoApiProfDeleteAccountRecordFn,
AristoApiProfMergeAccountRecordFn:
return TrpAccounts
Expand Down Expand Up @@ -466,26 +466,25 @@ proc ariTraceRecorder(tr: TraceRecorderRef) =
debug logTxt $info, level, accPath, accRec
ok accRec

tracerApi.fetchAccountStateRoot =
tracerApi.fetchStateRoot =
proc(mpt: AristoDbRef;
updateOk: bool;
): Result[Hash32,AristoError] =
const info = AristoApiProfFetchAccountStateRootFn
const info = AristoApiProfFetchStateRootFn

when CoreDbNoisyCaptJournal:
let level = tr.topLevel()

# Find entry on DB
let state = api.fetchAccountStateRoot(mpt, updateOk).valueOr:
let state = api.fetchStateRoot(mpt).valueOr:
when CoreDbNoisyCaptJournal:
debug logTxt $info, level, updateOk, error
debug logTxt $info, level, error
tr.jLogger logRecord(info, TrqFind, error)
return err(error)

tr.jLogger logRecord(info, TrqFind, state)

when CoreDbNoisyCaptJournal:
debug logTxt $info, level, updateOk, state
debug logTxt $info, level, state
ok state

tracerApi.fetchStorageData =
Expand Down Expand Up @@ -514,24 +513,23 @@ proc ariTraceRecorder(tr: TraceRecorderRef) =
tracerApi.fetchStorageRoot =
proc(mpt: AristoDbRef;
accPath: Hash32;
updateOk: bool;
): Result[Hash32,AristoError] =
const info = AristoApiProfFetchStorageRootFn

when CoreDbNoisyCaptJournal:
let level = tr.topLevel()

# Find entry on DB
let state = api.fetchStorageRoot(mpt, accPath, updateOk).valueOr:
let state = api.fetchStorageRoot(mpt, accPath).valueOr:
when CoreDbNoisyCaptJournal:
debug logTxt $info, level, accPath, updateOk, error
debug logTxt $info, level, accPath, error
tr.jLogger(accPath, logRecord(info, TrqFind, error))
return err(error)

tr.jLogger(accPath, logRecord(info, TrqFind, state))

when CoreDbNoisyCaptJournal:
debug logTxt $info, level, accPath, updateOk, state
debug logTxt $info, level, accPath, state
ok state

tracerApi.deleteAccountRecord =
Expand Down
41 changes: 16 additions & 25 deletions nimbus/db/core_db/base.nim
Original file line number Diff line number Diff line change
Expand Up @@ -530,21 +530,17 @@ proc hasPath*(
acc.ifTrackNewApi:
debug logTxt, api, elapsed, accPath=($$accPath), result

proc stateRoot*(acc: CoreDbAccRef; updateOk = false): CoreDbRc[Hash32] =
proc getStateRoot*(acc: CoreDbAccRef): CoreDbRc[Hash32] =
## This function retrieves the Merkle state hash of the accounts
## column (if available.)
##
## If the argument `updateOk` is set `true`, the Merkle hashes of the
## database will be updated first (if needed, at all).
##
acc.setTrackNewApi AccStateFn
result = block:
let rc = acc.call(fetchAccountStateRoot, acc.mpt, updateOk)
let rc = acc.call(fetchStateRoot, acc.mpt)
if rc.isOk:
ok(rc.value)
else:
err(rc.error.toError $api)
acc.ifTrackNewApi: debug logTxt, api, elapsed, updateOK, result
acc.ifTrackNewApi: debug logTxt, api, elapsed, result

# ------------ storage ---------------

Expand Down Expand Up @@ -647,36 +643,32 @@ proc slotMerge*(
debug logTxt, api, elapsed, accPath=($$accPath),
stoPath=($$stoPath), stoData, result

proc slotState*(
proc slotStorageRoot*(
acc: CoreDbAccRef;
accPath: Hash32;
updateOk = false;
): CoreDbRc[Hash32] =
## This function retrieves the Merkle state hash of the storage data
## column (if available) related to the account indexed by the key
## `accPath`.`.
##
## If the argument `updateOk` is set `true`, the Merkle hashes of the
## database will be updated first (if needed, at all).
##
acc.setTrackNewApi AccSlotStateFn
acc.setTrackNewApi AccSlotStorageRootFn
result = block:
let rc = acc.call(fetchStorageRoot, acc.mpt, accPath, updateOk)
let rc = acc.call(fetchStorageRoot, acc.mpt, accPath)
if rc.isOk:
ok(rc.value)
else:
err(rc.error.toError $api)
acc.ifTrackNewApi:
debug logTxt, api, elapsed, accPath=($$accPath), updateOk, result
debug logTxt, api, elapsed, accPath=($$accPath), result

proc slotStateEmpty*(
proc slotStorageEmpty*(
acc: CoreDbAccRef;
accPath: Hash32;
): CoreDbRc[bool] =
## This function returns `true` if the storage data column is empty or
## missing.
##
acc.setTrackNewApi AccSlotStateEmptyFn
acc.setTrackNewApi AccSlotStorageEmptyFn
result = block:
let rc = acc.call(hasStorageData, acc.mpt, accPath)
if rc.isOk:
Expand All @@ -686,12 +678,12 @@ proc slotStateEmpty*(
acc.ifTrackNewApi:
debug logTxt, api, elapsed, accPath=($$accPath), result

proc slotStateEmptyOrVoid*(
proc slotStorageEmptyOrVoid*(
acc: CoreDbAccRef;
accPath: Hash32;
): bool =
## Convenience wrapper, returns `true` where `slotStateEmpty()` would fail.
acc.setTrackNewApi AccSlotStateEmptyOrVoidFn
## Convenience wrapper, returns `true` where `slotStorageEmpty()` would fail.
acc.setTrackNewApi AccSlotStorageEmptyOrVoidFn
result = block:
let rc = acc.call(hasStorageData, acc.mpt, accPath)
if rc.isOk:
Expand All @@ -707,14 +699,13 @@ proc recast*(
acc: CoreDbAccRef;
accPath: Hash32;
accRec: CoreDbAccount;
updateOk = false;
): CoreDbRc[Account] =
## Complete the argument `accRec` to the portable Ethereum representation
## of an account statement. This conversion may fail if the storage colState
## hash (see `slotState()` above) is currently unavailable.
## hash (see `slotStorageRoot()` above) is currently unavailable.
##
acc.setTrackNewApi AccRecastFn
let rc = acc.call(fetchStorageRoot, acc.mpt, accPath, updateOk)
let rc = acc.call(fetchStorageRoot, acc.mpt, accPath)
result = block:
if rc.isOk:
ok Account(
Expand All @@ -725,8 +716,8 @@ proc recast*(
else:
err(rc.error.toError $api)
acc.ifTrackNewApi:
let slotState = if rc.isOk: $$(rc.value) else: "n/a"
debug logTxt, api, elapsed, accPath=($$accPath), slotState, result
let storageRoot = if rc.isOk: $$(rc.value) else: "n/a"
debug logTxt, api, elapsed, accPath=($$accPath), storageRoot, result

# ------------------------------------------------------------------------------
# Public transaction related methods
Expand Down
6 changes: 3 additions & 3 deletions nimbus/db/core_db/base/api_tracking.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ type
AccSlotHasPathFn = "slotHasPath"
AccSlotMergeFn = "slotMerge"
AccSlotProofFn = "slotProof"
AccSlotStateFn = "slotState"
AccSlotStateEmptyFn = "slotStateEmpty"
AccSlotStateEmptyOrVoidFn = "slotStateEmptyOrVoid"
AccSlotStorageRootFn = "slotStorageRoot"
AccSlotStorageEmptyFn = "slotStorageEmpty"
AccSlotStorageEmptyOrVoidFn = "slotStorageEmptyOrVoid"
AccSlotPairsIt = "slotPairs"

BaseFinishFn = "finish"
Expand Down
Loading

0 comments on commit 652539e

Please sign in to comment.