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:
parent
035ef696a6
commit
e7be0d185c
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
# ---------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue