Smaller leaf types

This commit is contained in:
Jacek Sieka 2024-12-03 11:10:48 +01:00
parent fa09c54a37
commit a984d54c2d
No known key found for this signature in database
GPG Key ID: A1B09461ABB656B8
13 changed files with 117 additions and 151 deletions

View File

@ -48,7 +48,8 @@ proc branchStillNeeded(vtx: VertexRef, removed: int8): Result[int8,void] =
proc deleteImpl(
db: AristoDbRef; # Database, top layer
hike: Hike; # Fully expanded path
): Result[VertexRef,AristoError] =
T: type
): Result[Opt[T],AristoError] =
## Removes the last node in the hike and returns the updated leaf in case
## a branch collapsed
@ -62,7 +63,7 @@ proc deleteImpl(
if hike.legs.len == 1:
# This was the last node in the trie, meaning we don't have any branches or
# leaves to update
return ok(default(VertexRef))
return ok(default(Opt[T]))
if hike.legs[^2].wp.vtx.vType != Branch:
return err(DelBranchExpexted)
@ -111,16 +112,16 @@ proc deleteImpl(
db.layersPutVtx((hike.root, br.vid), vtx)
if vtx.vType == Leaf:
ok(vtx)
ok(Opt.some(vtx.to(T)))
else:
ok(default(VertexRef))
ok(Opt.none(T))
else:
# Clear the removed leaf from the branch (that still contains other children)
var brDup = br.vtx.dup
discard brDup.setUsed(uint8 hike.legs[^2].nibble, false)
db.layersPutVtx((hike.root, br.vid), brDup)
ok(default(VertexRef))
ok(Opt.none(T))
# ------------------------------------------------------------------------------
# Public functions
@ -145,64 +146,17 @@ proc deleteAccountRecord*(
if stoID.isValid:
? db.delStoTreeImpl((stoID.vid, stoID.vid), accPath)
let otherLeaf = ?db.deleteImpl(accHike)
let otherLeaf = ?db.deleteImpl(accHike, AccountLeaf)
db.layersPutAccLeaf(accPath, default(VertexRef))
db.layersPutAccLeaf(accPath, default(Opt[AccountLeaf]))
if otherLeaf.isValid:
if otherLeaf.isSome:
db.layersPutAccLeaf(
Hash32(getBytes(NibblesBuf.fromBytes(accPath.data).replaceSuffix(otherLeaf.pfx))),
Hash32(getBytes(NibblesBuf.fromBytes(accPath.data).replaceSuffix(otherLeaf[].pfx))),
otherLeaf)
ok()
proc deleteGenericData*(
db: AristoDbRef;
root: VertexID;
path: openArray[byte];
): Result[bool,AristoError] =
## Delete the leaf data entry addressed by the argument `path`. The MPT
## sub-tree the leaf data entry is subsumed under is passed as argument
## `root` which must be greater than `VertexID(1)` and smaller than
## `LEAST_FREE_VID`.
##
## The return value is `true` if the argument `path` deleted was the last
## one and the tree does not exist anymore.
##
# Verify that `root` is neither an accounts tree nor a strorage tree.
if not root.isValid:
return err(DelRootVidMissing)
elif root == VertexID(1):
return err(DelAccRootNotAccepted)
elif LEAST_FREE_VID <= root.distinctBase:
return err(DelStoRootNotAccepted)
var hike: Hike
path.hikeUp(root, db, Opt.none(VertexRef), hike).isOkOr:
if error[1] in HikeAcceptableStopsNotFound:
return err(DelPathNotFound)
return err(error[1])
discard ?db.deleteImpl(hike)
ok(not db.getVtx((root, root)).isValid)
proc deleteGenericTree*(
db: AristoDbRef; # Database, top layer
root: VertexID; # Root vertex
): Result[void,AristoError] =
## Variant of `deleteGenericData()` for purging the whole MPT sub-tree.
##
# Verify that `root` is neither an accounts tree nor a strorage tree.
if not root.isValid:
return err(DelRootVidMissing)
elif root == VertexID(1):
return err(DelAccRootNotAccepted)
elif LEAST_FREE_VID <= root.distinctBase:
return err(DelStoRootNotAccepted)
db.delSubTreeImpl root
proc deleteStorageData*(
db: AristoDbRef;
accPath: Hash32; # Implies storage data tree
@ -220,7 +174,7 @@ proc deleteStorageData*(
mixPath = mixUp(accPath, stoPath)
stoLeaf = db.cachedStoLeaf(mixPath)
if stoLeaf == Opt.some(default(VertexRef)):
if stoLeaf == Opt.some(default(Opt[StoLeaf])):
return err(DelPathNotFound)
var accHike: Hike
@ -246,13 +200,13 @@ proc deleteStorageData*(
# Mark account path Merkle keys for update
db.layersResKeys accHike
let otherLeaf = ?db.deleteImpl(stoHike)
db.layersPutStoLeaf(mixPath, default(VertexRef))
let otherLeaf = ?db.deleteImpl(stoHike, StoLeaf)
db.layersPutStoLeaf(mixPath, default(Opt[StoLeaf]))
if otherLeaf.isValid:
if otherLeaf.isSome:
let leafMixPath = mixUp(
accPath,
Hash32(getBytes(stoNibbles.replaceSuffix(otherLeaf.pfx))))
Hash32(getBytes(stoNibbles.replaceSuffix(otherLeaf[].pfx))))
db.layersPutStoLeaf(leafMixPath, otherLeaf)
# If there was only one item (that got deleted), update the account as well
@ -262,7 +216,7 @@ proc deleteStorageData*(
# De-register the deleted storage tree from the account record
var leaf = wpAcc.vtx.dup # Dup on modify
leaf.lData.stoID.isValid = false
db.layersPutAccLeaf(accPath, leaf)
db.layersPutAccLeaf(accPath, Opt.some(leaf.to(AccountLeaf)))
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
ok(true)
@ -294,7 +248,7 @@ proc deleteStorageTree*(
# De-register the deleted storage tree from the accounts record
var leaf = wpAcc.vtx.dup # Dup on modify
leaf.lData.stoID.isValid = false
db.layersPutAccLeaf(accPath, leaf)
db.layersPutAccLeaf(accPath, Opt.some(leaf.to(AccountLeaf)))
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
ok()

View File

@ -61,7 +61,7 @@ proc delStoTreeNow(
of Leaf:
let stoPath = Hash32((stoPath & vtx.pfx).getBytes())
db.layersPutStoLeaf(mixUp(accPath, stoPath), default(VertexRef))
db.layersPutStoLeaf(mixUp(accPath, stoPath), default(Opt[StoLeaf]))
db.layersResVtx(rvid)

View File

@ -64,7 +64,7 @@ type
txUidGen*: uint ## Tx-relative unique number generator
dudes: DudesRef ## Related DB descriptors
accLeaves*: LruCache[Hash32, VertexRef]
accLeaves*: LruCache[Hash32, Opt[AccountLeaf]]
## Account path to payload cache - accounts are frequently accessed by
## account path when contracts interact with them - this cache ensures
## that we don't have to re-traverse the storage trie for every such
@ -72,7 +72,7 @@ type
## TODO a better solution would probably be to cache this in a type
## exposed to the high-level API
stoLeaves*: LruCache[Hash32, VertexRef]
stoLeaves*: LruCache[Hash32, Opt[StoLeaf]]
## Mixed account/storage path to payload cache - same as above but caches
## the full lookup of storage slots

View File

@ -79,6 +79,15 @@ type
startVid*: VertexID
used*: uint16
AccountLeaf* = object
pfx*: NibblesBuf
account*: AristoAccount
stoID*: StorageID
StoLeaf* = object
pfx*: NibblesBuf
stoData*: UInt256
NodeRef* = ref object of RootRef
## Combined record for a *traditional* ``Merkle Patricia Tree` node merged
## with a structural `VertexRef` type object.
@ -125,8 +134,8 @@ type
kMap*: Table[RootedVertexID,HashKey] ## Merkle hash key mapping
vTop*: VertexID ## Last used vertex ID
accLeaves*: Table[Hash32, VertexRef] ## Account path -> VertexRef
stoLeaves*: Table[Hash32, VertexRef] ## Storage path -> VertexRef
accLeaves*: Table[Hash32, Opt[AccountLeaf]] ## Account path -> VertexRef
stoLeaves*: Table[Hash32, Opt[StoLeaf]] ## Storage path -> VertexRef
txUid*: uint ## Transaction identifier if positive
@ -196,6 +205,18 @@ proc `==`*(a, b: VertexRef): bool =
return false
true
func to*(v: VertexRef, _: type AccountLeaf): AccountLeaf =
AccountLeaf(pfx: v.pfx, account: v.lData.account, stoID: v.lData.stoID)
func to*(v: VertexRef, _: type StoLeaf): StoLeaf =
StoLeaf(pfx: v.pfx, stoData: v.lData.stoData)
func to*(v: AccountLeaf, _: type VertexRef): VertexRef =
VertexRef(pfx: v.pfx, vType: Leaf, lData: LeafPayload(pType: AccountData, account: v.account, stoID: v.stoID))
func to*(v: StoLeaf, _: type VertexRef): VertexRef =
VertexRef(pfx: v.pfx, vType: Leaf, lData: LeafPayload(pType: StoData, stoData: v.stoData))
iterator pairs*(vtx: VertexRef): tuple[nibble: uint8, vid: VertexID] =
## Iterates over the sub-vids of a branch (does nothing for leaves)
case vtx.vType:

View File

@ -27,7 +27,8 @@ proc retrieveLeaf(
db: AristoDbRef;
root: VertexID;
path: Hash32;
): Result[VertexRef,AristoError] =
T: type
): Result[T,AristoError] =
for step in stepUp(NibblesBuf.fromBytes(path.data), root, db):
let vtx = step.valueOr:
if error in HikeAcceptableStopsNotFound:
@ -35,42 +36,42 @@ proc retrieveLeaf(
return err(error)
if vtx.vType == Leaf:
return ok vtx
return ok vtx.to(T)
return err(FetchPathNotFound)
proc cachedAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[VertexRef] =
proc cachedAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[Opt[AccountLeaf]] =
# Return vertex from layers or cache, `nil` if it's known to not exist and
# none otherwise
db.layersGetAccLeaf(accPath) or
db.accLeaves.get(accPath) or
Opt.none(VertexRef)
Opt.none(Opt[AccountLeaf])
proc cachedStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[VertexRef] =
proc cachedStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[Opt[StoLeaf]] =
# Return vertex from layers or cache, `nil` if it's known to not exist and
# none otherwise
db.layersGetStoLeaf(mixPath) or
db.stoLeaves.get(mixPath) or
Opt.none(VertexRef)
Opt.none(Opt[StoLeaf])
proc retrieveAccountLeaf(
db: AristoDbRef;
accPath: Hash32;
): Result[VertexRef,AristoError] =
): Result[AccountLeaf,AristoError] =
if (let leafVtx = db.cachedAccLeaf(accPath); leafVtx.isSome()):
if not leafVtx[].isValid():
if not leafVtx[].isSome():
return err(FetchPathNotFound)
return ok leafVtx[]
return ok leafVtx[][]
# Updated payloads are stored in the layers so if we didn't find them there,
# it must have been in the database
let
leafVtx = db.retrieveLeaf(VertexID(1), accPath).valueOr:
leafVtx = db.retrieveLeaf(VertexID(1), accPath, AccountLeaf).valueOr:
if error == FetchPathNotFound:
db.accLeaves.put(accPath, default(VertexRef))
db.accLeaves.put(accPath, default(Opt[AccountLeaf]))
return err(error)
db.accLeaves.put(accPath, leafVtx)
db.accLeaves.put(accPath, Opt.some(leafVtx))
ok leafVtx
@ -105,7 +106,7 @@ proc fetchStorageIdImpl(
## Helper function for retrieving a storage (vertex) ID for a given account.
let
leafVtx = ?db.retrieveAccountLeaf(accPath)
stoID = leafVtx.lData.stoID
stoID = leafVtx.stoID
if stoID.isValid:
ok stoID.vid
@ -126,11 +127,11 @@ proc fetchAccountHike*(
## Expand account path to account leaf or return failure
# Prefer the leaf cache so as not to burden the lower layers
let leaf = db.cachedAccLeaf(accPath)
if leaf == Opt.some(default(VertexRef)):
let accLeaf = db.cachedAccLeaf(accPath)
if accLeaf == Opt.some(Opt.none(AccountLeaf)):
return err(FetchAccInaccessible)
accPath.hikeUp(VertexID(1), db, leaf, accHike).isOkOr:
accPath.hikeUp(VertexID(1), db, accLeaf, accHike).isOkOr:
return err(FetchAccInaccessible)
# Extract the account payload from the leaf
@ -159,20 +160,20 @@ proc retrieveStoragePayload(
let mixPath = mixUp(accPath, stoPath)
if (let leafVtx = db.cachedStoLeaf(mixPath); leafVtx.isSome()):
if not leafVtx[].isValid():
if not leafVtx[].isSome():
return err(FetchPathNotFound)
return ok leafVtx[].lData.stoData
return ok leafVtx[][].stoData
# Updated payloads are stored in the layers so if we didn't find them there,
# it must have been in the database
let leafVtx = db.retrieveLeaf(? db.fetchStorageIdImpl(accPath), stoPath).valueOr:
let leafVtx = db.retrieveLeaf(? db.fetchStorageIdImpl(accPath), stoPath, StoLeaf).valueOr:
if error == FetchPathNotFound:
db.stoLeaves.put(mixPath, default(VertexRef))
db.stoLeaves.put(mixPath, default(Opt[StoLeaf]))
return err(error)
db.stoLeaves.put(mixPath, leafVtx)
db.stoLeaves.put(mixPath, Opt.some(leafVtx))
ok leafVtx.lData.stoData
ok leafVtx.stoData
proc hasStoragePayload(
db: AristoDbRef;
@ -205,9 +206,8 @@ proc fetchAccountRecord*(
## Fetch an account record from the database indexed by `accPath`.
##
let leafVtx = ? db.retrieveAccountLeaf(accPath)
assert leafVtx.lData.pType == AccountData # debugging only
ok leafVtx.lData.account
ok leafVtx.account
proc fetchStateRoot*(
db: AristoDbRef;

View File

@ -124,11 +124,11 @@ iterator stepUp*(
if path.len == 0:
break
proc hikeUp*(
proc hikeUp*[T](
path: NibblesBuf; # Partial path
root: VertexID; # Start vertex
db: AristoDbRef; # Database
leaf: Opt[VertexRef];
leaf: Opt[T];
hike: var Hike;
): Result[void,(VertexID,AristoError)] =
## For the argument `path`, find and return the logest possible path in the
@ -147,10 +147,11 @@ proc hikeUp*(
var vid = root
while true:
if leaf.isSome() and leaf[].isValid and path == leaf[].pfx:
hike.legs.add Leg(wp: VidVtxPair(vid: vid, vtx: leaf[]), nibble: -1)
reset(hike.tail)
break
when T is Opt[AccountLeaf] or T is Opt[StoLeaf]:
if leaf.isSome() and leaf[].isSome and path == leaf[][].pfx:
hike.legs.add Leg(wp: VidVtxPair(vid: vid, vtx: leaf[][].to(VertexRef)), nibble: -1)
reset(hike.tail)
break
let (vtx, path, next) = step(hike.tail, (root, vid), db).valueOr:
return err((vid,error))
@ -173,30 +174,30 @@ proc hikeUp*(
ok()
proc hikeUp*(
proc hikeUp*[T](
lty: LeafTie;
db: AristoDbRef;
leaf: Opt[VertexRef];
leaf: Opt[T];
hike: var Hike
): Result[void,(VertexID,AristoError)] =
## Variant of `hike()`
lty.path.to(NibblesBuf).hikeUp(lty.root, db, leaf, hike)
proc hikeUp*(
proc hikeUp*[T](
path: openArray[byte];
root: VertexID;
db: AristoDbRef;
leaf: Opt[VertexRef];
leaf: Opt[T];
hike: var Hike
): Result[void,(VertexID,AristoError)] =
## Variant of `hike()`
NibblesBuf.fromBytes(path).hikeUp(root, db, leaf, hike)
proc hikeUp*(
proc hikeUp*[T](
path: Hash32;
root: VertexID;
db: AristoDbRef;
leaf: Opt[VertexRef];
leaf: Opt[T];
hike: var Hike
): Result[void,(VertexID,AristoError)] =
## Variant of `hike()`

View File

@ -54,8 +54,8 @@ proc newAristoRdbDbRef(
ok((AristoDbRef(
top: LayerRef(vTop: vTop),
backend: be,
accLeaves: LruCache[Hash32, VertexRef].init(ACC_LRU_SIZE),
stoLeaves: LruCache[Hash32, VertexRef].init(ACC_LRU_SIZE),
accLeaves: LruCache[Hash32, Opt[AccountLeaf]].init(ACC_LRU_SIZE),
stoLeaves: LruCache[Hash32, Opt[StoLeaf]].init(ACC_LRU_SIZE),
), oCfs))
# ------------------------------------------------------------------------------

View File

@ -91,7 +91,7 @@ func layersGetKeyOrVoid*(db: AristoDbRef; rvid: RootedVertexID): HashKey =
## Simplified version of `layersGetKey()`
(db.layersGetKey(rvid).valueOr (VOID_HASH_KEY, 0))[0]
func layersGetAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[VertexRef] =
func layersGetAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[Opt[AccountLeaf]] =
db.top.accLeaves.withValue(accPath, item):
return Opt.some(item[])
@ -99,9 +99,9 @@ func layersGetAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[VertexRef] =
w.accLeaves.withValue(accPath, item):
return Opt.some(item[])
Opt.none(VertexRef)
Opt.none(Opt[AccountLeaf])
func layersGetStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[VertexRef] =
func layersGetStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[Opt[StoLeaf]] =
db.top.stoLeaves.withValue(mixPath, item):
return Opt.some(item[])
@ -109,7 +109,7 @@ func layersGetStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[VertexRef] =
w.stoLeaves.withValue(mixPath, item):
return Opt.some(item[])
Opt.none(VertexRef)
Opt.none(Opt[StoLeaf])
# ------------------------------------------------------------------------------
# Public functions: setter variants
@ -153,10 +153,10 @@ func layersResKeys*(db: AristoDbRef; hike: Hike) =
for i in 1..hike.legs.len:
db.layersResKey((hike.root, hike.legs[^i].wp.vid), hike.legs[^i].wp.vtx)
func layersPutAccLeaf*(db: AristoDbRef; accPath: Hash32; leafVtx: VertexRef) =
func layersPutAccLeaf*(db: AristoDbRef; accPath: Hash32; leafVtx: Opt[AccountLeaf]) =
db.top.accLeaves[accPath] = leafVtx
func layersPutStoLeaf*(db: AristoDbRef; mixPath: Hash32; leafVtx: VertexRef) =
func layersPutStoLeaf*(db: AristoDbRef; mixPath: Hash32; leafVtx: Opt[StoLeaf]) =
db.top.stoLeaves[mixPath] = leafVtx
# ------------------------------------------------------------------------------

View File

@ -38,13 +38,13 @@ proc layersPutLeaf(
db.layersPutVtx(rvid, vtx)
vtx
proc mergePayloadImpl(
proc mergePayloadImpl[T](
db: AristoDbRef, # Database, top layer
root: VertexID, # MPT state root
path: Hash32, # Leaf item to add to the database
leaf: Opt[VertexRef],
leaf: Opt[Opt[T]],
payload: LeafPayload, # Payload value
): Result[(VertexRef, VertexRef, VertexRef), AristoError] =
): Result[(T, Opt[NibblesBuf], Opt[T]), AristoError] =
## Merge the argument `(root,path)` key-value-pair into the top level vertex
## table of the database `db`. The `path` argument is used to address the
## leaf vertex with the payload. It is stored or updated on the database
@ -59,7 +59,7 @@ proc mergePayloadImpl(
# We're at the root vertex and there is no data - this must be a fresh
# VertexID!
return ok (db.layersPutLeaf((root, cur), path, payload), default(VertexRef), default(VertexRef))
return ok (db.layersPutLeaf((root, cur), path, payload).to(T), Opt.none(NibblesBuf), Opt.none(T))
vids: ArrayBuf[NibblesBuf.high + 1, VertexID]
vtxs: ArrayBuf[NibblesBuf.high + 1, VertexRef]
@ -93,7 +93,7 @@ proc mergePayloadImpl(
db.layersPutLeaf((root, cur), path, payload)
else:
db.layersPutLeaf((root, cur), path, payload)
(leafVtx, default(VertexRef), default(VertexRef))
(leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T))
else:
# Turn leaf into a branch (or extension) then insert the two leaves
# into the branch
@ -111,7 +111,7 @@ proc mergePayloadImpl(
# We need to return vtx here because its pfx member hasn't yet been
# sliced off and is therefore shared with the hike
(leafVtx, vtx, other)
(leafVtx.to(T), Opt.some(vtx.pfx), Opt.some(other.to(T)))
resetKeys()
return ok(res)
@ -126,8 +126,8 @@ proc mergePayloadImpl(
cur = next
path = path.slice(n + 1)
vtx =
if leaf.isSome and leaf[].isValid and leaf[].pfx == path:
leaf[]
if leaf.isSome and leaf[].isSome and leaf[][].pfx == path:
leaf[][].to(VertexRef)
else:
(?db.getVtxRc((root, next)))[0]
@ -143,7 +143,7 @@ proc mergePayloadImpl(
leafVtx = db.layersPutLeaf((root, local), path.slice(n + 1), payload)
resetKeys()
return ok((leafVtx, default(VertexRef), default(VertexRef)))
return ok((leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T)))
else:
# Partial path match - we need to split the existing branch at
# the point of divergence, inserting a new branch
@ -163,7 +163,7 @@ proc mergePayloadImpl(
db.layersPutVtx((root, cur), branch)
resetKeys()
return ok((leafVtx, default(VertexRef), default(VertexRef)))
return ok((leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T)))
err(MergeHikeFailed)
@ -193,10 +193,10 @@ proc mergeAccountRecord*(
# Update leaf cache both of the merged value and potentially the displaced
# leaf resulting from splitting a leaf into a branch with two leaves
db.layersPutAccLeaf(accPath, updated[0])
if updated[1].isValid:
db.layersPutAccLeaf(accPath, Opt.some(updated[0]))
if updated[1].isSome:
let otherPath = Hash32(getBytes(
NibblesBuf.fromBytes(accPath.data).replaceSuffix(updated[1].pfx)))
NibblesBuf.fromBytes(accPath.data).replaceSuffix(updated[1][])))
db.layersPutAccLeaf(otherPath, updated[2])
ok true
@ -239,18 +239,18 @@ proc mergeStorageData*(
# Update leaf cache both of the merged value and potentially the displaced
# leaf resulting from splitting a leaf into a branch with two leaves
db.layersPutStoLeaf(mixPath, updated[0])
db.layersPutStoLeaf(mixPath, Opt.some(updated[0]))
if updated[1].isValid:
if updated[1].isSome:
let otherPath = Hash32(getBytes(
NibblesBuf.fromBytes(stoPath.data).replaceSuffix(updated[1].pfx)))
NibblesBuf.fromBytes(stoPath.data).replaceSuffix(updated[1][])))
db.layersPutStoLeaf(mixUp(accPath, otherPath), updated[2])
if not stoID.isValid:
# Make sure that there is an account that refers to that storage trie
var leaf = accHike.legs[^1].wp.vtx.dup # Dup on modify
leaf.lData.stoID = useID
db.layersPutAccLeaf(accPath, leaf)
db.layersPutAccLeaf(accPath, Opt.some(leaf.to(AccountLeaf)))
db.layersPutVtx((VertexID(1), accHike.legs[^1].wp.vid), leaf)
ok()

View File

@ -145,9 +145,9 @@ proc zeroAdjust(
proc toHike(pfx: NibblesBuf, root: VertexID, db: AristoDbRef): Hike =
when doLeast:
discard pfx.pathPfxPad(0).hikeUp(root, db, Opt.none(VertexRef), result)
discard pfx.pathPfxPad(0).hikeUp(root, db, Opt.none(void), result)
else:
discard pfx.pathPfxPad(255).hikeUp(root, db, Opt.none(VertexRef), result)
discard pfx.pathPfxPad(255).hikeUp(root, db, Opt.none(void), result)
if 0 < hike.legs.len:
return ok(hike)
@ -354,7 +354,7 @@ proc nearbyNextLeafTie(
): Result[PathID,(VertexID,AristoError)] =
## Variant of `nearbyNext()`, convenience wrapper
var hike: Hike
discard lty.hikeUp(db, Opt.none(VertexRef), hike)
discard lty.hikeUp(db, Opt.none(void), hike)
hike = ?hike.nearbyNext(db, hikeLenMax, moveRight)
if 0 < hike.legs.len:
@ -403,7 +403,7 @@ iterator rightPairs*(
## Traverse the sub-trie implied by the argument `start` with increasing
## order.
var hike: Hike
discard start.hikeUp(db, Opt.none(VertexRef), hike)
discard start.hikeUp(db, Opt.none(void), hike)
var rc = hike.right db
while rc.isOk:
hike = rc.value
@ -431,7 +431,7 @@ iterator rightPairs*(
hike.legs.setLen(hike.legs.len - 1)
break reuseHike
# Fall back to default method
discard key.next.hikeUp(db, Opt.none(VertexRef), hike)
discard key.next.hikeUp(db, Opt.none(void), hike)
rc = hike.right db
# End while
@ -488,7 +488,7 @@ iterator leftPairs*(
## the `path` field decremented by `1`.
var
hike: Hike
discard start.hikeUp(db, Opt.none(VertexRef), hike)
discard start.hikeUp(db, Opt.none(void), hike)
var rc = hike.left db
while rc.isOk:
@ -517,7 +517,7 @@ iterator leftPairs*(
hike.legs.setLen(hike.legs.len - 1)
break reuseHike
# Fall back to default method
discard key.prev.hikeUp(db, Opt.none(VertexRef), hike)
discard key.prev.hikeUp(db, Opt.none(void), hike)
rc = hike.left db
# End while

View File

@ -125,27 +125,17 @@ proc ctxAcceptChange(psc: PartStateCtx): Result[bool,AristoError] =
proc ctxMergeBegin*(
ps: PartStateRef;
root: VertexID;
path: openArray[byte];
accPath: Hash32;
): Result[PartStateCtx,AristoError] =
## This function clears the way for mering some payload at the argument
## path `(root,path)`.
## Variant of `partMergeBegin()` for different path representation
var hike: Hike
path.hikeUp(root,ps.db, Opt.none(VertexRef), hike).isOkOr:
accPath.hikeUp(VertexID(1),ps.db, Opt.none(Opt[AccountLeaf]), hike).isOkOr:
if error[1] != HikeDanglingEdge:
return err error[1] # Cannot help here
return ps.newCtx hike
ok PartStateCtx(nil) # Nothing to do
proc ctxMergeBegin*(
ps: PartStateRef;
accPath: Hash32;
): Result[PartStateCtx,AristoError] =
## Variant of `partMergeBegin()` for different path representation
ps.ctxMergeBegin(VertexID(1), accPath.data)
proc ctxMergeCommit*(psc: PartStateCtx): Result[bool,AristoError] =
##
if psc.isNil:

View File

@ -153,7 +153,7 @@ proc testCreatePortalProof(node: JsonNode, testStatusIMPL: var TestStatus) {.dep
let
path = a.data.keccak256
var hike: Hike
let rc = path.hikeUp(VertexID(1), ps.db, Opt.none(VertexRef), hike)
let rc = path.hikeUp(VertexID(1), ps.db, Opt.none(void), hike)
sample[path] = ProofData(
error: (if rc.isErr: rc.error[1] else: AristoError(0)),
hike: hike) # keep `hike` for potential debugging

View File

@ -95,7 +95,7 @@ proc randomisedLeafs(
var lvp: seq[(LeafTie,RootedVertexID)]
for lty in ltys:
var hike: Hike
?lty.hikeUp(db, Opt.none(VertexRef), hike)
?lty.hikeUp(db, Opt.none(void), hike)
lvp.add (lty,(hike.root, hike.legs[^1].wp.vid))
var lvp2 = lvp.sorted(