Aristo uses pre classified tree types cont2 (#2397)

* Provide dedicated functions for fetching accounts and storage trees

why:
  Different prototypes for each class `account`, `generic` and
  `storage`.

* Remove `fetchPayload()` and other cruft from API, `aristo_fetch`, etc.

* Fix typos, debugging left overs, comments
This commit is contained in:
Jordan Hrycaj 2024-06-19 12:40:00 +00:00 committed by GitHub
parent 035ef696a6
commit e7be0d185c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 408 additions and 257 deletions

View File

@ -108,15 +108,30 @@ type
## Merkle hash tag for vertex with ID 1 and a bespoke `uint64` identifier
## (may be interpreted as block number.)
AristoApiFetchPayloadFn* =
AristoApiFetchAccountPayloadFn* =
proc(db: AristoDbRef;
path: openArray[byte];
): Result[AristoAccount,AristoError]
{.noRaise.}
## Fetch an account record from the database indexed by `path`.
AristoApiFetchGenericDataFn* =
proc(db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[PayloadRef,(VertexID,AristoError)]
): Result[Blob,AristoError]
{.noRaise.}
## Cascaded attempt to traverse the `Aristo Trie` and fetch the value
## of a leaf vertex. This function is complementary to some `mergeXXX()`
## function.
## For a generic sub-tree starting at `root`, fetch the data record
## indexed by `path`.
AristoApiFetchStorageDataFn* =
proc(db: AristoDbRef;
path: openArray[byte];
accPath: PathID;
): Result[Blob,AristoError]
{.noRaise.}
## For a storage tree related to account `accPath`, fetch the data
## record from the database indexed by `path`.
AristoApiFindTxFn* =
proc(db: AristoDbRef;
@ -205,15 +220,31 @@ type
## Add keys to the `Patricia Trie` so that it becomes a `Merkle
## Patricia Tree`.
AristoApiHasPathFn* =
AristoApiHasPathAccountFn* =
proc(db: AristoDbRef;
path: openArray[byte];
): Result[bool,AristoError]
{.noRaise.}
## For an account record indexed by `path` query whether this record
## exists on the database.
AristoApiHasPathGenericFn* =
proc(db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[bool,(VertexID,AristoError)]
): Result[bool,AristoError]
{.noRaise.}
## Variant of `fetchPayload()` without returning data. It returns
## `true` iff the database `db` contains a leaf item with the argument
## path.
## For a generic sub-tree starting at `root` and indexed by `path`,
## mquery whether this record exists on the database.
AristoApiHasPathStorageFn* =
proc(db: AristoDbRef;
path: openArray[byte];
accPath: PathID;
): Result[bool,AristoError]
{.noRaise.}
## For a storage tree related to account `accPath`, query whether the
## data record indexed by `path` exists on the database.
AristoApiHikeUpFn* =
proc(path: NibblesSeq;
@ -384,14 +415,18 @@ type
deleteStorageData*: AristoApiDeleteStorageDataFn
deleteStorageTree*: AristoApiDeleteStorageTreeFn
fetchLastSavedState*: AristoApiFetchLastSavedStateFn
fetchPayload*: AristoApiFetchPayloadFn
fetchAccountPayload*: AristoApiFetchAccountPayloadFn
fetchGenericData*: AristoApiFetchGenericDataFn
fetchStorageData*: AristoApiFetchStorageDataFn
findTx*: AristoApiFindTxFn
finish*: AristoApiFinishFn
forget*: AristoApiForgetFn
forkTx*: AristoApiForkTxFn
getKeyRc*: AristoApiGetKeyRcFn
hashify*: AristoApiHashifyFn
hasPath*: AristoApiHasPathFn
hasPathAccount*: AristoApiHasPathAccountFn
hasPathGeneric*: AristoApiHasPathGenericFn
hasPathStorage*: AristoApiHasPathStorageFn
hikeUp*: AristoApiHikeUpFn
isTop*: AristoApiIsTopFn
level*: AristoApiLevelFn
@ -419,14 +454,18 @@ type
AristoApiProfDeleteStorageDataFn = "deleteStorageData"
AristoApiProfDeleteStorageTreeFn = "deleteStorageTree"
AristoApiProfFetchLastSavedStateFn = "fetchPayload"
AristoApiProfFetchPayloadFn = "fetchPayload"
AristoApiProfFetchAccountPayloadFn = "fetchAccountPayload"
AristoApiProfFetchGenericDataFn = "fetchGenericData"
AristoApiProfFetchStorageDataFn = "fetchStorageData"
AristoApiProfFindTxFn = "findTx"
AristoApiProfFinishFn = "finish"
AristoApiProfForgetFn = "forget"
AristoApiProfForkTxFn = "forkTx"
AristoApiProfGetKeyRcFn = "getKeyRc"
AristoApiProfHashifyFn = "hashify"
AristoApiProfHasPathFn = "hasPath"
AristoApiProfHasPathAccountFn = "hasPathAccount"
AristoApiProfHasPathGenericFn = "hasPathGeneric"
AristoApiProfHasPathStorageFn = "hasPathStorage"
AristoApiProfHikeUpFn = "hikeUp"
AristoApiProfIsTopFn = "isTop"
AristoApiProfLevelFn = "level"
@ -470,14 +509,18 @@ when AutoValidateApiHooks:
doAssert not api.deleteStorageData.isNil
doAssert not api.deleteStorageTree.isNil
doAssert not api.fetchLastSavedState.isNil
doAssert not api.fetchPayload.isNil
doAssert not api.fetchAccountPayload.isNil
doAssert not api.fetchGenericData.isNil
doAssert not api.fetchStorageData.isNil
doAssert not api.findTx.isNil
doAssert not api.finish.isNil
doAssert not api.forget.isNil
doAssert not api.forkTx.isNil
doAssert not api.getKeyRc.isNil
doAssert not api.hashify.isNil
doAssert not api.hasPath.isNil
doAssert not api.hasPathAccount.isNil
doAssert not api.hasPathGeneric.isNil
doAssert not api.hasPathStorage.isNil
doAssert not api.hikeUp.isNil
doAssert not api.isTop.isNil
doAssert not api.level.isNil
@ -525,14 +568,18 @@ func init*(api: var AristoApiObj) =
api.deleteStorageData = deleteStorageData
api.deleteStorageTree = deleteStorageTree
api.fetchLastSavedState = fetchLastSavedState
api.fetchPayload = fetchPayload
api.fetchAccountPayload = fetchAccountPayload
api.fetchGenericData = fetchGenericData
api.fetchStorageData = fetchStorageData
api.findTx = findTx
api.finish = finish
api.forget = forget
api.forkTx = forkTx
api.getKeyRc = getKeyRc
api.hashify = hashify
api.hasPath = hasPath
api.hasPathAccount = hasPathAccount
api.hasPathGeneric = hasPathGeneric
api.hasPathStorage = hasPathStorage
api.hikeUp = hikeUp
api.isTop = isTop
api.level = level
@ -563,14 +610,18 @@ func dup*(api: AristoApiRef): AristoApiRef =
deleteStorageData: api.deleteStorageData,
deleteStorageTree: api.deleteStorageTree,
fetchLastSavedState: api.fetchLastSavedState,
fetchPayload: api.fetchPayload,
fetchAccountPayload: api.fetchAccountPayload,
fetchGenericData: api.fetchGenericData,
fetchStorageData: api.fetchStorageData,
findTx: api.findTx,
finish: api.finish,
forget: api.forget,
forkTx: api.forkTx,
getKeyRc: api.getKeyRc,
hashify: api.hashify,
hasPath: api.hasPath,
hasPathAccount: api.hasPathAccount,
hasPathGeneric: api.hasPathGeneric,
hasPathStorage: api.hasPathStorage,
hikeUp: api.hikeUp,
isTop: api.isTop,
level: api.level,
@ -650,10 +701,20 @@ func init*(
AristoApiProfFetchLastSavedStateFn.profileRunner:
result = api.fetchLastSavedState(a)
profApi.fetchPayload =
profApi.fetchAccountPayload =
proc(a: AristoDbRef; b: openArray[byte]): auto =
AristoApiProfFetchAccountPayloadFn.profileRunner:
result = api.fetchAccountPayload(a, b)
profApi.fetchGenericData =
proc(a: AristoDbRef; b: VertexID; c: openArray[byte]): auto =
AristoApiProfFetchPayloadFn.profileRunner:
result = api.fetchPayload(a, b, c)
AristoApiProfFetchGenericDataFn.profileRunner:
result = api.fetchGenericData(a, b, c)
profApi.fetchStorageData =
proc(a: AristoDbRef; b: openArray[byte]; c: PathID;): auto =
AristoApiProfFetchStorageDataFn.profileRunner:
result = api.fetchStorageData(a, b, c)
profApi.findTx =
proc(a: AristoDbRef; b: VertexID; c: HashKey): auto =
@ -685,10 +746,20 @@ func init*(
AristoApiProfHashifyFn.profileRunner:
result = api.hashify(a)
profApi.hasPath =
profApi.hasPathAccount =
proc(a: AristoDbRef; b: openArray[byte]): auto =
AristoApiProfHasPathAccountFn.profileRunner:
result = api.hasPathAccount(a, b)
profApi.hasPathGeneric =
proc(a: AristoDbRef; b: VertexID; c: openArray[byte]): auto =
AristoApiProfHasPathFn.profileRunner:
result = api.hasPath(a, b, c)
AristoApiProfHasPathGenericFn.profileRunner:
result = api.hasPathGeneric(a, b, c)
profApi.hasPathStorage =
proc(a: AristoDbRef; b: openArray[byte]; c: PathID;): auto =
AristoApiProfHasPathStorageFn.profileRunner:
result = api.hasPathStorage(a, b, c)
profApi.hikeUp =
proc(a: NibblesSeq; b: VertexID; c: AristoDbRef): auto =

View File

@ -19,7 +19,7 @@ import
std/[sets, typetraits],
eth/[common, trie/nibbles],
results,
"."/[aristo_desc, aristo_get, aristo_hike, aristo_layers, aristo_path,
"."/[aristo_desc, aristo_get, aristo_hike, aristo_layers,
aristo_utils, aristo_vid]
type

View File

@ -239,9 +239,9 @@ proc forget*(db: AristoDbRef): Result[void,AristoError] =
## comments on `fork()`.)
##
if db.isCentre:
err(NotAllowedOnCentre)
err(DescNotAllowedOnCentre)
elif db notin db.dudes.peers:
err(StaleDescriptor)
err(DescStaleDescriptor)
else:
db.dudes.peers.excl db # Unlink argument `db` from peers list
ok()
@ -252,7 +252,7 @@ proc forgetOthers*(db: AristoDbRef): Result[void,AristoError] =
##
if not db.dudes.isNil:
if db.dudes.centre != db:
return err(MustBeOnCentre)
return err(DescMustBeOnCentre)
db.dudes = DudesRef(nil)
ok()

View File

@ -11,21 +11,16 @@
type
AristoError* = enum
NothingSerious = 0
# Miscelaneous/unclassified handy helpers
GenericError
# Rlp decoder, `read()`
Rlp2Or17ListEntries
RlpBlobExpected
RlpBranchHashKeyExpected
RlpEmptyBlobExpected
RlpExtHashKeyExpected
RlpHashKeyExpected
RlpNonEmptyBlobExpected
RlpOtherException
RlpRlpException
AccRootUnacceptable
MptRootUnacceptable
MptRootMissing
NotImplemented
TrieInvalid
# Serialise decoder
SerCantResolveStorageRoot
# Data record transcoders, `deblobify()` and `blobify()`
BlobifyBranchMissingRefs
@ -37,6 +32,51 @@ type
BlobifyStateSrcLenGarbled
BlobifyStateTrgLenGarbled
# Cache checker `checkCache()`
CheckAnyVidDeadStorageRoot
CheckAnyVidSharedStorageRoot
CheckAnyVtxEmptyKeyMissing
CheckAnyVtxEmptyKeyExpected
CheckAnyVtxEmptyKeyMismatch
CheckAnyVtxBranchLinksMissing
CheckAnyVtxExtPfxMissing
CheckAnyVtxLockWithoutKey
CheckAnyVTopUnset
CheckBeCacheGarbledVTop
CheckBeCacheIsDirty
CheckBeCacheKeyCantCompile
CheckBeCacheKeyDangling
CheckBeCacheKeyMismatch
CheckBeCacheKeyMissing
CheckBeCacheKeyNonEmpty
CheckBeCacheVidUnsynced
CheckBeCacheVtxDangling
CheckBeFifoSrcTrgMismatch
CheckBeFifoTrgNotStateRoot
CheckBeGarbledVTop
CheckBeKeyCantCompile
CheckBeKeyInvalid
CheckBeKeyMismatch
CheckBeKeyMissing
CheckBeVtxBranchLinksMissing
CheckBeVtxExtPfxMissing
CheckBeVtxInvalid
CheckBeVtxMissing
CheckStkKeyStrayZeroEntry
CheckStkVtxIncomplete
CheckStkVtxKeyMismatch
CheckStkVtxKeyMissing
CheckRlxVidVtxMismatch
CheckRlxVtxIncomplete
CheckRlxVtxKeyMissing
CheckRlxVtxKeyMismatch
# De-serialiser from `blobify.nim`
DeblobNilArgument
DeblobUnknown
DeblobVtxTooShort
@ -64,8 +104,68 @@ type
DeblobFilterTrpVtxSizeGarbled
DeblobFilterSizeGarbled
# Converter `asNode()`, currenly for unit tests only
CacheMissingNodekeys
# Deletion of vertex paths, `deleteXxx()`
DelAccRootNotAccepted
DelBranchExpexted
DelBranchLocked
DelBranchWithoutRefs
DelDanglingStoTrie
DelExtLocked
DelLeafExpexted
DelLeafLocked
DelLeafUnexpected
DelPathNotFound
DelPathTagError
DelRootVidMissing
DelStoAccMissing
DelStoRootMissing
DelStoRootNotAccepted
DelSubTreeAccRoot
DelSubTreeVoidRoot
DelVidStaleVtx
# Functions from `aristo_desc.nim`
DescMustBeOnCentre
DescNotAllowedOnCentre
DescStaleDescriptor
# Functions from `aristo_filter.nim`
FilBackendMissing
FilBackendRoMode
FilNilFilterRejected
FilSiblingsCommitUnfinshed
FilSrcTrgInconsistent
FilStateRootMismatch
FilTrgSrcMismatch
# Fetch functions from `aristo_fetch.nim`
FetchPathNotFound
FetchLeafKeyInvalid
FetchPathInvalid
FetchRootVidMissing
FetchAccRootNotAccepted
FetchStoRootNotAccepted
# Get functions from `aristo_get.nim`
GetFilNotFound
GetFqsNotFound
GetKeyNotFound
GetKeyUpdateNeeded
GetLstNotFound
GetTuvNotFound
GetVtxNotFound
# Update `Merkle` hashes `hashify()`
HashifyVtxUnresolved
HashifyRootVtxUnresolved
HashifyProofHashMismatch
# Path function `hikeUp()`
HikeBranchMissingEdge
@ -79,10 +179,6 @@ type
HikeNoLegs
HikeRootMissing
# Path/nibble/key conversions in `aisto_path.nim`
PathExpected64Nibbles
PathAtMost64Nibbles
PathExpectedLeaf
# Merge leaf `merge()`
MergeAssemblyFailed # Ooops, internal error
@ -119,61 +215,6 @@ type
MergeRootKeysOverflow
MergeRootVidMissing
# Update `Merkle` hashes `hashify()`
HashifyVtxUnresolved
HashifyRootVtxUnresolved
HashifyProofHashMismatch
# Cache checker `checkCache()`
CheckStkKeyStrayZeroEntry
CheckStkVtxIncomplete
CheckStkVtxKeyMismatch
CheckStkVtxKeyMissing
CheckRlxVidVtxMismatch
CheckRlxVtxIncomplete
CheckRlxVtxKeyMissing
CheckRlxVtxKeyMismatch
CheckAnyVidDeadStorageRoot
CheckAnyVidSharedStorageRoot
CheckAnyVtxEmptyKeyMissing
CheckAnyVtxEmptyKeyExpected
CheckAnyVtxEmptyKeyMismatch
CheckAnyVtxBranchLinksMissing
CheckAnyVtxExtPfxMissing
CheckAnyVtxLockWithoutKey
CheckAnyVTopUnset
# Backend structural check `checkBE()`
CheckBeVtxInvalid
CheckBeVtxMissing
CheckBeVtxBranchLinksMissing
CheckBeVtxExtPfxMissing
CheckBeKeyInvalid
CheckBeKeyMissing
CheckBeKeyCantCompile
CheckBeKeyMismatch
CheckBeGarbledVTop
CheckBeCacheIsDirty
CheckBeCacheKeyMissing
CheckBeCacheKeyNonEmpty
CheckBeCacheVidUnsynced
CheckBeCacheKeyDangling
CheckBeCacheVtxDangling
CheckBeCacheKeyCantCompile
CheckBeCacheKeyMismatch
CheckBeCacheGarbledVTop
CheckBeFifoSrcTrgMismatch
CheckBeFifoTrgNotStateRoot
# Jornal check `checkJournal()`
CheckJrnCachedQidOverlap
CheckJrnSavedQidMissing
CheckJrnSavedQidStale
CheckJrnLinkingGap
# Neighbour vertex, tree traversal `nearbyRight()` and `nearbyLeft()`
NearbyBeyondRange
@ -189,50 +230,12 @@ type
NearbyUnexpectedVtx
NearbyVidInvalid
# Deletion of vertices, `delete()`
DelAccRootNotAccepted
DelBranchExpexted
DelBranchLocked
DelBranchWithoutRefs
DelDanglingStoTrie
DelExtLocked
DelLeafExpexted
DelLeafLocked
DelLeafUnexpected
DelPathNotFound
DelPathTagError
DelRootVidMissing
DelStoAccMissing
DelStoRootMissing
DelStoRootNotAccepted
DelSubTreeAccRoot
DelSubTreeVoidRoot
DelVidStaleVtx
# Functions from `aristo_filter.nim`
FilBackendMissing
FilBackendRoMode
FilNilFilterRejected
FilSiblingsCommitUnfinshed
FilSrcTrgInconsistent
FilStateRootMismatch
FilTrgSrcMismatch
# Path/nibble/key conversions in `aisto_path.nim`
PathExpected64Nibbles
PathAtMost64Nibbles
PathExpectedLeaf
# Get functions from `aristo_get.nim`
GetLeafMissing
GetKeyUpdateNeeded
GetLeafNotFound
GetVtxNotFound
GetKeyNotFound
GetFilNotFound
GetTuvNotFound
GetLstNotFound
GetFqsNotFound
# Fetch functions from `aristo_fetch.nim`
FetchPathNotFound
LeafKeyInvalid
# RocksDB backend
RdbBeCantCreateDataDir
@ -256,6 +259,23 @@ type
RdbGuestInstanceUnsupported
RdbHashKeyExpected
# Rlp decoder, `read()`
Rlp2Or17ListEntries
RlpBlobExpected
RlpBranchHashKeyExpected
RlpEmptyBlobExpected
RlpExtHashKeyExpected
RlpHashKeyExpected
RlpNonEmptyBlobExpected
RlpOtherException
RlpRlpException
# Serialise decoder
SerCantResolveStorageRoot
# Transaction wrappers
TxAccRootMissing
TxArgStaleTx
@ -267,38 +287,23 @@ type
TxNotFound
TxNotTopTx
TxPendingTx
TxPrettyPointlessLayer
TxStackGarbled
TxStackUnderflow
TxPrettyPointlessLayer
TxStateRootMismatch
# Functions from `aristo_desc.nim`
MustBeOnCentre
NotAllowedOnCentre
StaleDescriptor
# Functions from `aristo_utils.nim`
AccRlpDecodingError
AccStorageKeyMissing
AccVtxUnsupported
AccNodeUnsupported
PayloadTypeUnsupported
UtilsAccInaccessible
UtilsAccLeafPayloadExpected
UtilsAccNodeUnsupported
UtilsAccPathMissing
UtilsAccPathWithoutLeaf
UtilsAccInaccessible
UtilsAccStorageKeyMissing
UtilsAccVtxUnsupported
UtilsAccWrongStorageRoot
UtilsPayloadTypeUnsupported
UtilsStoRootInaccessible
UtilsStoRootMissing
UtilsAccLeafPayloadExpected
# Miscelaneous handy helpers
AccRootUnacceptable
MptRootUnacceptable
MptRootMissing
NotImplemented
TrieInvalid
VidContextLocked
# End

View File

@ -14,70 +14,76 @@
{.push raises: [].}
import
eth/trie/nibbles,
std/typetraits,
eth/[common, trie/nibbles],
results,
"."/[aristo_desc, aristo_get, aristo_hike]
"."/[aristo_desc, aristo_get, aristo_hike, aristo_utils]
# ------------------------------------------------------------------------------
# Private functions
# ------------------------------------------------------------------------------
proc fetchPayloadImpl(
rc: Result[Hike,(VertexID,AristoError,Hike)];
): Result[PayloadRef,(VertexID,AristoError)] =
if rc.isErr:
if rc.error[1] in HikeAcceptableStopsNotFound:
return err((rc.error[0], FetchPathNotFound))
return err((rc.error[0], rc.error[1]))
ok rc.value.legs[^1].wp.vtx.lData
func mustBeGeneric(
root: VertexID;
): Result[void,AristoError] =
## Verify that `root` is neither from an accounts tree nor a strorage tree.
if not root.isValid:
return err(FetchRootVidMissing)
elif root == VertexID(1):
return err(FetchAccRootNotAccepted)
elif LEAST_FREE_VID <= root.distinctBase:
return err(FetchStoRootNotAccepted)
ok()
proc fetchPayloadImpl(
proc retrievePayload(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[PayloadRef,(VertexID,AristoError)] =
path.initNibbleRange.hikeUp(root, db).fetchPayloadImpl
): Result[PayloadRef,AristoError] =
if path.len == 0:
return err(FetchPathInvalid)
let hike = path.initNibbleRange.hikeUp(root, db).valueOr:
if error[1] in HikeAcceptableStopsNotFound:
return err(FetchPathNotFound)
return err(error[1])
ok hike.legs[^1].wp.vtx.lData
proc retrieveStoID(
db: AristoDbRef;
accPath: PathID;
): Result[VertexID,AristoError] =
let
accHike = ? db.retrieveStoAccHike accPath # checks for `AccountData`
stoID = accHike.legs[^1].wp.vtx.lData.account.storageID
if not stoID.isValid:
return err(FetchPathNotFound)
ok stoID
proc hasPayload(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[bool,AristoError] =
if path.len == 0:
return err(FetchPathInvalid)
let hike = path.initNibbleRange.hikeUp(VertexID(1), db).valueOr:
if error[1] in HikeAcceptableStopsNotFound:
return ok(false)
return err(error[1])
ok(true)
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc fetchPayload*(
db: AristoDbRef;
key: LeafTie;
): Result[PayloadRef,(VertexID,AristoError)] =
## Cascaded attempt to traverse the `Aristo Trie` and fetch the value of a
## leaf vertex. This function is complementary to `mergePayload()`.
##
key.hikeUp(db).fetchPayloadImpl
proc fetchPayload*(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[PayloadRef,(VertexID,AristoError)] =
## Variant of `fetchPayload()`
##
if path.len == 0:
return err((VertexID(0),LeafKeyInvalid))
db.fetchPayloadImpl(root, path)
proc hasPath*(
db: AristoDbRef; # Database
root: VertexID;
path: openArray[byte]; # Key of database record
): Result[bool,(VertexID,AristoError)] =
## Variant of `fetchPayload()`
##
if path.len == 0:
return err((VertexID(0),LeafKeyInvalid))
let rc = db.fetchPayloadImpl(root, path)
if rc.isOk:
return ok(true)
if rc.error[1] == FetchPathNotFound:
return ok(false)
err(rc.error)
proc fetchLastSavedState*(
db: AristoDbRef;
): Result[SavedState,AristoError] =
@ -86,6 +92,74 @@ proc fetchLastSavedState*(
## `uint64` identifier (may be interpreted as block number.)
db.getLstUbe()
proc fetchAccountPayload*(
db: AristoDbRef;
path: openArray[byte];
): Result[AristoAccount,AristoError] =
## Fetch an account record from the database indexed by `path`.
##
let pyl = ? db.retrievePayload(VertexID(1), path)
assert pyl.pType == AccountData # debugging only
ok pyl.account
proc hasPathAccount*(
db: AristoDbRef;
path: openArray[byte];
): Result[bool,AristoError] =
## For an account record indexed by `path` query whether this record exists
## on the database.
##
db.hasPayload(VertexID(1), path)
proc fetchGenericData*(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[Blob,AristoError] =
## For a generic sub-tree starting at `root`, fetch the data record
## indexed by `path`.
##
? root.mustBeGeneric()
let pyl = ? db.retrievePayload(root, path)
assert pyl.pType == RawData # debugging only
ok pyl.rawBlob
proc hasPathGeneric*(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[bool,AristoError] =
## For a generic sub-tree starting at `root` and indexed by `path`, query
## whether this record exists on the database.
##
? root.mustBeGeneric()
db.hasPayload(root, path)
proc fetchStorageData*(
db: AristoDbRef;
path: openArray[byte];
accPath: PathID;
): Result[Blob,AristoError] =
## For a storage tree related to account `accPath`, fetch the data record
## from the database indexed by `path`.
##
let pyl = ? db.retrievePayload(? db.retrieveStoID accPath, path)
assert pyl.pType == RawData # debugging only
ok pyl.rawBlob
proc hasPathStorage*(
db: AristoDbRef;
path: openArray[byte];
accPath: PathID;
): Result[bool,AristoError] =
## For a storage tree related to account `accPath`, query whether the data
## record indexed by `path` exists on the database.
##
db.hasPayload(? db.retrieveStoID accPath, path)
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------

View File

@ -97,7 +97,7 @@ func layersGetKey*(db: AristoDbRef; vid: VertexID): Opt[HashKey] =
Opt.none(HashKey)
func layersGetKeyOrVoid*(db: AristoDbRef; vid: VertexID): HashKey =
## Simplified version of `layersGetkey()`
## Simplified version of `layersGetKey()`
db.layersGetKey(vid).valueOr: VOID_HASH_KEY

View File

@ -120,7 +120,7 @@ proc mergeStorageData*(
## otherwise `VertexID(0)`.
##
let
accHike = ?db.retrieveStoAccHike accPath
accHike = ? db.retrieveStoAccHike accPath # checks for `AccountData`
wpAcc = accHike.legs[^1].wp
stoID = wpAcc.vtx.lData.account.storageID

View File

@ -40,7 +40,7 @@ proc toAccount*(
acc.storageRoot = (? db.getKeyRc payload.account.storageID).to(Hash256)
return ok(acc)
err PayloadTypeUnsupported
err UtilsPayloadTypeUnsupported
proc toAccount*(
vtx: VertexRef;
@ -49,7 +49,7 @@ proc toAccount*(
## Variant of `toAccount()` for a `Leaf` vertex.
if vtx.isValid and vtx.vType == Leaf:
return vtx.lData.toAccount db
err AccVtxUnsupported
err UtilsAccVtxUnsupported
proc toAccount*(
node: NodeRef;
@ -65,13 +65,13 @@ proc toAccount*(
storageRoot: EMPTY_ROOT_HASH)
if node.lData.account.storageID.isValid:
if not node.key[0].isValid:
return err(AccStorageKeyMissing)
return err(UtilsAccStorageKeyMissing)
acc.storageRoot = node.key[0].to(Hash256)
return ok(acc)
else:
return err(PayloadTypeUnsupported)
return err(UtilsPayloadTypeUnsupported)
err AccNodeUnsupported
err UtilsAccNodeUnsupported
# ---------------------

View File

@ -155,6 +155,7 @@ func toRc[T](
return ok(rc.value)
err rc.error.toError(base, info, error)
func toRc[T](
rc: Result[T,AristoError];
base: AristoBaseRef;
@ -206,12 +207,11 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
# The mpt might have become empty
let
key = cMpt.address.keccakHash.data
pyl = api.fetchPayload(mpt, AccountsVID, key).valueOr:
raiseAssert "mptColFn(): " & $error[1] & " at " & $error[0]
acc = api.fetchAccountPayload(mpt, key).valueOr:
raiseAssert "mptColFn(): " & $error
# Update by accounts data
doAssert pyl.pType == AccountData
cMpt.mptRoot = pyl.account.storageID
cMpt.mptRoot = acc.storageID
db.bless AristoColRef(
base: base,
@ -222,20 +222,24 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
proc mptFetch(key: openArray[byte]): CoreDbRc[Blob] =
const info = "fetchFn()"
# Some pathological behaviour observed with storage column due to lazy
# update. The `fetchPayload()` does not now about this and would complain
# an error different from `FetchPathNotFound`.
let rootVID = cMpt.mptRoot
if not rootVID.isValid:
return err((VoidVID,MptRootMissing).toError(base, info, MptNotFound))
let rc = block:
if cMpt.accPath.isValid:
api.fetchStorageData(mpt, key, cMpt.accPath)
elif cMpt.mptRoot.isValid:
api.fetchGenericData(mpt, cMpt.mptRoot, key)
else:
# Some pathological behaviour observed with storage column due to lazy
# update. The `fetchXxxPayload()` does not now about this and would
# complain an error different from `FetchPathNotFound`.
return err(MptRootMissing.toError(base, info, MptNotFound))
let rc = api.fetchPayload(mpt, rootVID, key)
# let rc = api.fetchPayload(mpt, rootVID, key)
if rc.isOk:
api.serialise(mpt, rc.value).toRc(base, info)
elif rc.error[1] != FetchPathNotFound:
ok rc.value
elif rc.error != FetchPathNotFound:
err(rc.error.toError(base, info))
else:
err rc.error.toError(base, info, MptNotFound)
err(rc.error.toError(base, info, MptNotFound))
proc mptMerge(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
const info = "mergeFn()"
@ -280,7 +284,13 @@ proc mptMethods(cMpt: AristoCoreDxMptRef): CoreDbMptFns =
proc mptHasPath(key: openArray[byte]): CoreDbRc[bool] =
const info = "hasPathFn()"
let rc = api.hasPath(mpt, cMpt.mptRoot, key)
let rc = block:
if cMpt.accPath.isValid:
api.hasPathStorage(mpt, key, cMpt.accPath)
else:
api.hasPathGeneric(mpt, cMpt.mptRoot, key)
#let rc = api.hasPath(mpt, cMpt.mptRoot, key)
if rc.isErr:
return err(rc.error.toError(base, info))
ok(rc.value)
@ -333,21 +343,14 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
proc accFetch(address: EthAddress): CoreDbRc[CoreDbAccount] =
const info = "acc/fetchFn()"
let pyl = block:
let
key = address.keccakHash.data
rc = api.fetchPayload(mpt, AccountsVID, 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))
let
key = address.keccakHash.data
acc = api.fetchAccountPayload(mpt, key).valueOr:
if error != FetchPathNotFound:
return err(error.toError(base, info))
return err(error.toError(base, info, AccNotFound))
if pyl.pType != AccountData:
let vidErrPair = (pyl.account.storageID, PayloadTypeUnsupported)
return err(vidErrPair.toError(base, info & "/" & $pyl.pType))
ok cAcc.toCoreDbAccount(pyl.account, address)
ok cAcc.toCoreDbAccount(acc, address)
proc accMerge(account: CoreDbAccount): CoreDbRc[void] =
const info = "acc/mergeFn()"
@ -385,10 +388,9 @@ proc accMethods(cAcc: AristoCoreDxAccRef): CoreDbAccFns =
let
key = address.keccakHash.data
rc = api.hasPath(mpt, AccountsVID, key)
if rc.isErr:
return err(rc.error.toError(base, info))
ok(rc.value)
yn = api.hasPathAccount(mpt, key).valueOr:
return err(error.toError(base, info))
ok(yn)
CoreDbAccFns(
@ -499,7 +501,6 @@ proc ctxMethods(cCtx: AristoCoreDbCtxRef): CoreDbCtxFns =
if reset:
let rc = api.deleteGenericTree(mpt, newMpt.mptRoot)
if rc.isErr:
raiseAssert "find me"
return err(rc.error.toError(base, info, AutoFlushFailed))
col.reset = false