mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-11 03:27:00 +00:00
Smaller leaf types
This commit is contained in:
parent
fa09c54a37
commit
a984d54c2d
@ -48,7 +48,8 @@ proc branchStillNeeded(vtx: VertexRef, removed: int8): Result[int8,void] =
|
|||||||
proc deleteImpl(
|
proc deleteImpl(
|
||||||
db: AristoDbRef; # Database, top layer
|
db: AristoDbRef; # Database, top layer
|
||||||
hike: Hike; # Fully expanded path
|
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
|
## Removes the last node in the hike and returns the updated leaf in case
|
||||||
## a branch collapsed
|
## a branch collapsed
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ proc deleteImpl(
|
|||||||
if hike.legs.len == 1:
|
if hike.legs.len == 1:
|
||||||
# This was the last node in the trie, meaning we don't have any branches or
|
# This was the last node in the trie, meaning we don't have any branches or
|
||||||
# leaves to update
|
# leaves to update
|
||||||
return ok(default(VertexRef))
|
return ok(default(Opt[T]))
|
||||||
|
|
||||||
if hike.legs[^2].wp.vtx.vType != Branch:
|
if hike.legs[^2].wp.vtx.vType != Branch:
|
||||||
return err(DelBranchExpexted)
|
return err(DelBranchExpexted)
|
||||||
@ -111,16 +112,16 @@ proc deleteImpl(
|
|||||||
db.layersPutVtx((hike.root, br.vid), vtx)
|
db.layersPutVtx((hike.root, br.vid), vtx)
|
||||||
|
|
||||||
if vtx.vType == Leaf:
|
if vtx.vType == Leaf:
|
||||||
ok(vtx)
|
ok(Opt.some(vtx.to(T)))
|
||||||
else:
|
else:
|
||||||
ok(default(VertexRef))
|
ok(Opt.none(T))
|
||||||
else:
|
else:
|
||||||
# Clear the removed leaf from the branch (that still contains other children)
|
# Clear the removed leaf from the branch (that still contains other children)
|
||||||
var brDup = br.vtx.dup
|
var brDup = br.vtx.dup
|
||||||
discard brDup.setUsed(uint8 hike.legs[^2].nibble, false)
|
discard brDup.setUsed(uint8 hike.legs[^2].nibble, false)
|
||||||
db.layersPutVtx((hike.root, br.vid), brDup)
|
db.layersPutVtx((hike.root, br.vid), brDup)
|
||||||
|
|
||||||
ok(default(VertexRef))
|
ok(Opt.none(T))
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public functions
|
# Public functions
|
||||||
@ -145,64 +146,17 @@ proc deleteAccountRecord*(
|
|||||||
if stoID.isValid:
|
if stoID.isValid:
|
||||||
? db.delStoTreeImpl((stoID.vid, stoID.vid), accPath)
|
? 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(
|
db.layersPutAccLeaf(
|
||||||
Hash32(getBytes(NibblesBuf.fromBytes(accPath.data).replaceSuffix(otherLeaf.pfx))),
|
Hash32(getBytes(NibblesBuf.fromBytes(accPath.data).replaceSuffix(otherLeaf[].pfx))),
|
||||||
otherLeaf)
|
otherLeaf)
|
||||||
|
|
||||||
ok()
|
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*(
|
proc deleteStorageData*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
accPath: Hash32; # Implies storage data tree
|
accPath: Hash32; # Implies storage data tree
|
||||||
@ -220,7 +174,7 @@ proc deleteStorageData*(
|
|||||||
mixPath = mixUp(accPath, stoPath)
|
mixPath = mixUp(accPath, stoPath)
|
||||||
stoLeaf = db.cachedStoLeaf(mixPath)
|
stoLeaf = db.cachedStoLeaf(mixPath)
|
||||||
|
|
||||||
if stoLeaf == Opt.some(default(VertexRef)):
|
if stoLeaf == Opt.some(default(Opt[StoLeaf])):
|
||||||
return err(DelPathNotFound)
|
return err(DelPathNotFound)
|
||||||
|
|
||||||
var accHike: Hike
|
var accHike: Hike
|
||||||
@ -246,13 +200,13 @@ proc deleteStorageData*(
|
|||||||
# Mark account path Merkle keys for update
|
# Mark account path Merkle keys for update
|
||||||
db.layersResKeys accHike
|
db.layersResKeys accHike
|
||||||
|
|
||||||
let otherLeaf = ?db.deleteImpl(stoHike)
|
let otherLeaf = ?db.deleteImpl(stoHike, StoLeaf)
|
||||||
db.layersPutStoLeaf(mixPath, default(VertexRef))
|
db.layersPutStoLeaf(mixPath, default(Opt[StoLeaf]))
|
||||||
|
|
||||||
if otherLeaf.isValid:
|
if otherLeaf.isSome:
|
||||||
let leafMixPath = mixUp(
|
let leafMixPath = mixUp(
|
||||||
accPath,
|
accPath,
|
||||||
Hash32(getBytes(stoNibbles.replaceSuffix(otherLeaf.pfx))))
|
Hash32(getBytes(stoNibbles.replaceSuffix(otherLeaf[].pfx))))
|
||||||
db.layersPutStoLeaf(leafMixPath, otherLeaf)
|
db.layersPutStoLeaf(leafMixPath, otherLeaf)
|
||||||
|
|
||||||
# If there was only one item (that got deleted), update the account as well
|
# 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
|
# De-register the deleted storage tree from the account record
|
||||||
var leaf = wpAcc.vtx.dup # Dup on modify
|
var leaf = wpAcc.vtx.dup # Dup on modify
|
||||||
leaf.lData.stoID.isValid = false
|
leaf.lData.stoID.isValid = false
|
||||||
db.layersPutAccLeaf(accPath, leaf)
|
db.layersPutAccLeaf(accPath, Opt.some(leaf.to(AccountLeaf)))
|
||||||
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
|
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
|
||||||
ok(true)
|
ok(true)
|
||||||
|
|
||||||
@ -294,7 +248,7 @@ proc deleteStorageTree*(
|
|||||||
# De-register the deleted storage tree from the accounts record
|
# De-register the deleted storage tree from the accounts record
|
||||||
var leaf = wpAcc.vtx.dup # Dup on modify
|
var leaf = wpAcc.vtx.dup # Dup on modify
|
||||||
leaf.lData.stoID.isValid = false
|
leaf.lData.stoID.isValid = false
|
||||||
db.layersPutAccLeaf(accPath, leaf)
|
db.layersPutAccLeaf(accPath, Opt.some(leaf.to(AccountLeaf)))
|
||||||
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
|
db.layersPutVtx((accHike.root, wpAcc.vid), leaf)
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ proc delStoTreeNow(
|
|||||||
|
|
||||||
of Leaf:
|
of Leaf:
|
||||||
let stoPath = Hash32((stoPath & vtx.pfx).getBytes())
|
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)
|
db.layersResVtx(rvid)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ type
|
|||||||
txUidGen*: uint ## Tx-relative unique number generator
|
txUidGen*: uint ## Tx-relative unique number generator
|
||||||
dudes: DudesRef ## Related DB descriptors
|
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 to payload cache - accounts are frequently accessed by
|
||||||
## account path when contracts interact with them - this cache ensures
|
## account path when contracts interact with them - this cache ensures
|
||||||
## that we don't have to re-traverse the storage trie for every such
|
## 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
|
## TODO a better solution would probably be to cache this in a type
|
||||||
## exposed to the high-level API
|
## 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
|
## Mixed account/storage path to payload cache - same as above but caches
|
||||||
## the full lookup of storage slots
|
## the full lookup of storage slots
|
||||||
|
|
||||||
|
@ -79,6 +79,15 @@ type
|
|||||||
startVid*: VertexID
|
startVid*: VertexID
|
||||||
used*: uint16
|
used*: uint16
|
||||||
|
|
||||||
|
AccountLeaf* = object
|
||||||
|
pfx*: NibblesBuf
|
||||||
|
account*: AristoAccount
|
||||||
|
stoID*: StorageID
|
||||||
|
|
||||||
|
StoLeaf* = object
|
||||||
|
pfx*: NibblesBuf
|
||||||
|
stoData*: UInt256
|
||||||
|
|
||||||
NodeRef* = ref object of RootRef
|
NodeRef* = ref object of RootRef
|
||||||
## Combined record for a *traditional* ``Merkle Patricia Tree` node merged
|
## Combined record for a *traditional* ``Merkle Patricia Tree` node merged
|
||||||
## with a structural `VertexRef` type object.
|
## with a structural `VertexRef` type object.
|
||||||
@ -125,8 +134,8 @@ type
|
|||||||
kMap*: Table[RootedVertexID,HashKey] ## Merkle hash key mapping
|
kMap*: Table[RootedVertexID,HashKey] ## Merkle hash key mapping
|
||||||
vTop*: VertexID ## Last used vertex ID
|
vTop*: VertexID ## Last used vertex ID
|
||||||
|
|
||||||
accLeaves*: Table[Hash32, VertexRef] ## Account path -> VertexRef
|
accLeaves*: Table[Hash32, Opt[AccountLeaf]] ## Account path -> VertexRef
|
||||||
stoLeaves*: Table[Hash32, VertexRef] ## Storage path -> VertexRef
|
stoLeaves*: Table[Hash32, Opt[StoLeaf]] ## Storage path -> VertexRef
|
||||||
|
|
||||||
txUid*: uint ## Transaction identifier if positive
|
txUid*: uint ## Transaction identifier if positive
|
||||||
|
|
||||||
@ -196,6 +205,18 @@ proc `==`*(a, b: VertexRef): bool =
|
|||||||
return false
|
return false
|
||||||
true
|
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] =
|
iterator pairs*(vtx: VertexRef): tuple[nibble: uint8, vid: VertexID] =
|
||||||
## Iterates over the sub-vids of a branch (does nothing for leaves)
|
## Iterates over the sub-vids of a branch (does nothing for leaves)
|
||||||
case vtx.vType:
|
case vtx.vType:
|
||||||
|
@ -27,7 +27,8 @@ proc retrieveLeaf(
|
|||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
root: VertexID;
|
root: VertexID;
|
||||||
path: Hash32;
|
path: Hash32;
|
||||||
): Result[VertexRef,AristoError] =
|
T: type
|
||||||
|
): Result[T,AristoError] =
|
||||||
for step in stepUp(NibblesBuf.fromBytes(path.data), root, db):
|
for step in stepUp(NibblesBuf.fromBytes(path.data), root, db):
|
||||||
let vtx = step.valueOr:
|
let vtx = step.valueOr:
|
||||||
if error in HikeAcceptableStopsNotFound:
|
if error in HikeAcceptableStopsNotFound:
|
||||||
@ -35,42 +36,42 @@ proc retrieveLeaf(
|
|||||||
return err(error)
|
return err(error)
|
||||||
|
|
||||||
if vtx.vType == Leaf:
|
if vtx.vType == Leaf:
|
||||||
return ok vtx
|
return ok vtx.to(T)
|
||||||
|
|
||||||
return err(FetchPathNotFound)
|
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
|
# Return vertex from layers or cache, `nil` if it's known to not exist and
|
||||||
# none otherwise
|
# none otherwise
|
||||||
db.layersGetAccLeaf(accPath) or
|
db.layersGetAccLeaf(accPath) or
|
||||||
db.accLeaves.get(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
|
# Return vertex from layers or cache, `nil` if it's known to not exist and
|
||||||
# none otherwise
|
# none otherwise
|
||||||
db.layersGetStoLeaf(mixPath) or
|
db.layersGetStoLeaf(mixPath) or
|
||||||
db.stoLeaves.get(mixPath) or
|
db.stoLeaves.get(mixPath) or
|
||||||
Opt.none(VertexRef)
|
Opt.none(Opt[StoLeaf])
|
||||||
|
|
||||||
proc retrieveAccountLeaf(
|
proc retrieveAccountLeaf(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
accPath: Hash32;
|
accPath: Hash32;
|
||||||
): Result[VertexRef,AristoError] =
|
): Result[AccountLeaf,AristoError] =
|
||||||
if (let leafVtx = db.cachedAccLeaf(accPath); leafVtx.isSome()):
|
if (let leafVtx = db.cachedAccLeaf(accPath); leafVtx.isSome()):
|
||||||
if not leafVtx[].isValid():
|
if not leafVtx[].isSome():
|
||||||
return err(FetchPathNotFound)
|
return err(FetchPathNotFound)
|
||||||
return ok leafVtx[]
|
return ok leafVtx[][]
|
||||||
|
|
||||||
# Updated payloads are stored in the layers so if we didn't find them there,
|
# Updated payloads are stored in the layers so if we didn't find them there,
|
||||||
# it must have been in the database
|
# it must have been in the database
|
||||||
let
|
let
|
||||||
leafVtx = db.retrieveLeaf(VertexID(1), accPath).valueOr:
|
leafVtx = db.retrieveLeaf(VertexID(1), accPath, AccountLeaf).valueOr:
|
||||||
if error == FetchPathNotFound:
|
if error == FetchPathNotFound:
|
||||||
db.accLeaves.put(accPath, default(VertexRef))
|
db.accLeaves.put(accPath, default(Opt[AccountLeaf]))
|
||||||
return err(error)
|
return err(error)
|
||||||
|
|
||||||
db.accLeaves.put(accPath, leafVtx)
|
db.accLeaves.put(accPath, Opt.some(leafVtx))
|
||||||
|
|
||||||
ok leafVtx
|
ok leafVtx
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ proc fetchStorageIdImpl(
|
|||||||
## Helper function for retrieving a storage (vertex) ID for a given account.
|
## Helper function for retrieving a storage (vertex) ID for a given account.
|
||||||
let
|
let
|
||||||
leafVtx = ?db.retrieveAccountLeaf(accPath)
|
leafVtx = ?db.retrieveAccountLeaf(accPath)
|
||||||
stoID = leafVtx.lData.stoID
|
stoID = leafVtx.stoID
|
||||||
|
|
||||||
if stoID.isValid:
|
if stoID.isValid:
|
||||||
ok stoID.vid
|
ok stoID.vid
|
||||||
@ -126,11 +127,11 @@ proc fetchAccountHike*(
|
|||||||
## Expand account path to account leaf or return failure
|
## Expand account path to account leaf or return failure
|
||||||
|
|
||||||
# Prefer the leaf cache so as not to burden the lower layers
|
# Prefer the leaf cache so as not to burden the lower layers
|
||||||
let leaf = db.cachedAccLeaf(accPath)
|
let accLeaf = db.cachedAccLeaf(accPath)
|
||||||
if leaf == Opt.some(default(VertexRef)):
|
if accLeaf == Opt.some(Opt.none(AccountLeaf)):
|
||||||
return err(FetchAccInaccessible)
|
return err(FetchAccInaccessible)
|
||||||
|
|
||||||
accPath.hikeUp(VertexID(1), db, leaf, accHike).isOkOr:
|
accPath.hikeUp(VertexID(1), db, accLeaf, accHike).isOkOr:
|
||||||
return err(FetchAccInaccessible)
|
return err(FetchAccInaccessible)
|
||||||
|
|
||||||
# Extract the account payload from the leaf
|
# Extract the account payload from the leaf
|
||||||
@ -159,20 +160,20 @@ proc retrieveStoragePayload(
|
|||||||
let mixPath = mixUp(accPath, stoPath)
|
let mixPath = mixUp(accPath, stoPath)
|
||||||
|
|
||||||
if (let leafVtx = db.cachedStoLeaf(mixPath); leafVtx.isSome()):
|
if (let leafVtx = db.cachedStoLeaf(mixPath); leafVtx.isSome()):
|
||||||
if not leafVtx[].isValid():
|
if not leafVtx[].isSome():
|
||||||
return err(FetchPathNotFound)
|
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,
|
# Updated payloads are stored in the layers so if we didn't find them there,
|
||||||
# it must have been in the database
|
# 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:
|
if error == FetchPathNotFound:
|
||||||
db.stoLeaves.put(mixPath, default(VertexRef))
|
db.stoLeaves.put(mixPath, default(Opt[StoLeaf]))
|
||||||
return err(error)
|
return err(error)
|
||||||
|
|
||||||
db.stoLeaves.put(mixPath, leafVtx)
|
db.stoLeaves.put(mixPath, Opt.some(leafVtx))
|
||||||
|
|
||||||
ok leafVtx.lData.stoData
|
ok leafVtx.stoData
|
||||||
|
|
||||||
proc hasStoragePayload(
|
proc hasStoragePayload(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
@ -205,9 +206,8 @@ proc fetchAccountRecord*(
|
|||||||
## Fetch an account record from the database indexed by `accPath`.
|
## Fetch an account record from the database indexed by `accPath`.
|
||||||
##
|
##
|
||||||
let leafVtx = ? db.retrieveAccountLeaf(accPath)
|
let leafVtx = ? db.retrieveAccountLeaf(accPath)
|
||||||
assert leafVtx.lData.pType == AccountData # debugging only
|
|
||||||
|
|
||||||
ok leafVtx.lData.account
|
ok leafVtx.account
|
||||||
|
|
||||||
proc fetchStateRoot*(
|
proc fetchStateRoot*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
|
@ -124,11 +124,11 @@ iterator stepUp*(
|
|||||||
if path.len == 0:
|
if path.len == 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
proc hikeUp*(
|
proc hikeUp*[T](
|
||||||
path: NibblesBuf; # Partial path
|
path: NibblesBuf; # Partial path
|
||||||
root: VertexID; # Start vertex
|
root: VertexID; # Start vertex
|
||||||
db: AristoDbRef; # Database
|
db: AristoDbRef; # Database
|
||||||
leaf: Opt[VertexRef];
|
leaf: Opt[T];
|
||||||
hike: var Hike;
|
hike: var Hike;
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
## For the argument `path`, find and return the logest possible path in the
|
## For the argument `path`, find and return the logest possible path in the
|
||||||
@ -147,8 +147,9 @@ proc hikeUp*(
|
|||||||
|
|
||||||
var vid = root
|
var vid = root
|
||||||
while true:
|
while true:
|
||||||
if leaf.isSome() and leaf[].isValid and path == leaf[].pfx:
|
when T is Opt[AccountLeaf] or T is Opt[StoLeaf]:
|
||||||
hike.legs.add Leg(wp: VidVtxPair(vid: vid, vtx: leaf[]), nibble: -1)
|
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)
|
reset(hike.tail)
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -173,30 +174,30 @@ proc hikeUp*(
|
|||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc hikeUp*(
|
proc hikeUp*[T](
|
||||||
lty: LeafTie;
|
lty: LeafTie;
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
leaf: Opt[VertexRef];
|
leaf: Opt[T];
|
||||||
hike: var Hike
|
hike: var Hike
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
## Variant of `hike()`
|
## Variant of `hike()`
|
||||||
lty.path.to(NibblesBuf).hikeUp(lty.root, db, leaf, hike)
|
lty.path.to(NibblesBuf).hikeUp(lty.root, db, leaf, hike)
|
||||||
|
|
||||||
proc hikeUp*(
|
proc hikeUp*[T](
|
||||||
path: openArray[byte];
|
path: openArray[byte];
|
||||||
root: VertexID;
|
root: VertexID;
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
leaf: Opt[VertexRef];
|
leaf: Opt[T];
|
||||||
hike: var Hike
|
hike: var Hike
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
## Variant of `hike()`
|
## Variant of `hike()`
|
||||||
NibblesBuf.fromBytes(path).hikeUp(root, db, leaf, hike)
|
NibblesBuf.fromBytes(path).hikeUp(root, db, leaf, hike)
|
||||||
|
|
||||||
proc hikeUp*(
|
proc hikeUp*[T](
|
||||||
path: Hash32;
|
path: Hash32;
|
||||||
root: VertexID;
|
root: VertexID;
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
leaf: Opt[VertexRef];
|
leaf: Opt[T];
|
||||||
hike: var Hike
|
hike: var Hike
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
## Variant of `hike()`
|
## Variant of `hike()`
|
||||||
|
@ -54,8 +54,8 @@ proc newAristoRdbDbRef(
|
|||||||
ok((AristoDbRef(
|
ok((AristoDbRef(
|
||||||
top: LayerRef(vTop: vTop),
|
top: LayerRef(vTop: vTop),
|
||||||
backend: be,
|
backend: be,
|
||||||
accLeaves: LruCache[Hash32, VertexRef].init(ACC_LRU_SIZE),
|
accLeaves: LruCache[Hash32, Opt[AccountLeaf]].init(ACC_LRU_SIZE),
|
||||||
stoLeaves: LruCache[Hash32, VertexRef].init(ACC_LRU_SIZE),
|
stoLeaves: LruCache[Hash32, Opt[StoLeaf]].init(ACC_LRU_SIZE),
|
||||||
), oCfs))
|
), oCfs))
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -91,7 +91,7 @@ func layersGetKeyOrVoid*(db: AristoDbRef; rvid: RootedVertexID): HashKey =
|
|||||||
## Simplified version of `layersGetKey()`
|
## Simplified version of `layersGetKey()`
|
||||||
(db.layersGetKey(rvid).valueOr (VOID_HASH_KEY, 0))[0]
|
(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):
|
db.top.accLeaves.withValue(accPath, item):
|
||||||
return Opt.some(item[])
|
return Opt.some(item[])
|
||||||
|
|
||||||
@ -99,9 +99,9 @@ func layersGetAccLeaf*(db: AristoDbRef; accPath: Hash32): Opt[VertexRef] =
|
|||||||
w.accLeaves.withValue(accPath, item):
|
w.accLeaves.withValue(accPath, item):
|
||||||
return Opt.some(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):
|
db.top.stoLeaves.withValue(mixPath, item):
|
||||||
return Opt.some(item[])
|
return Opt.some(item[])
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ func layersGetStoLeaf*(db: AristoDbRef; mixPath: Hash32): Opt[VertexRef] =
|
|||||||
w.stoLeaves.withValue(mixPath, item):
|
w.stoLeaves.withValue(mixPath, item):
|
||||||
return Opt.some(item[])
|
return Opt.some(item[])
|
||||||
|
|
||||||
Opt.none(VertexRef)
|
Opt.none(Opt[StoLeaf])
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public functions: setter variants
|
# Public functions: setter variants
|
||||||
@ -153,10 +153,10 @@ func layersResKeys*(db: AristoDbRef; hike: Hike) =
|
|||||||
for i in 1..hike.legs.len:
|
for i in 1..hike.legs.len:
|
||||||
db.layersResKey((hike.root, hike.legs[^i].wp.vid), hike.legs[^i].wp.vtx)
|
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
|
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
|
db.top.stoLeaves[mixPath] = leafVtx
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -38,13 +38,13 @@ proc layersPutLeaf(
|
|||||||
db.layersPutVtx(rvid, vtx)
|
db.layersPutVtx(rvid, vtx)
|
||||||
vtx
|
vtx
|
||||||
|
|
||||||
proc mergePayloadImpl(
|
proc mergePayloadImpl[T](
|
||||||
db: AristoDbRef, # Database, top layer
|
db: AristoDbRef, # Database, top layer
|
||||||
root: VertexID, # MPT state root
|
root: VertexID, # MPT state root
|
||||||
path: Hash32, # Leaf item to add to the database
|
path: Hash32, # Leaf item to add to the database
|
||||||
leaf: Opt[VertexRef],
|
leaf: Opt[Opt[T]],
|
||||||
payload: LeafPayload, # Payload value
|
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
|
## 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
|
## 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
|
## 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
|
# We're at the root vertex and there is no data - this must be a fresh
|
||||||
# VertexID!
|
# 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]
|
vids: ArrayBuf[NibblesBuf.high + 1, VertexID]
|
||||||
vtxs: ArrayBuf[NibblesBuf.high + 1, VertexRef]
|
vtxs: ArrayBuf[NibblesBuf.high + 1, VertexRef]
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ proc mergePayloadImpl(
|
|||||||
db.layersPutLeaf((root, cur), path, payload)
|
db.layersPutLeaf((root, cur), path, payload)
|
||||||
else:
|
else:
|
||||||
db.layersPutLeaf((root, cur), path, payload)
|
db.layersPutLeaf((root, cur), path, payload)
|
||||||
(leafVtx, default(VertexRef), default(VertexRef))
|
(leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T))
|
||||||
else:
|
else:
|
||||||
# Turn leaf into a branch (or extension) then insert the two leaves
|
# Turn leaf into a branch (or extension) then insert the two leaves
|
||||||
# into the branch
|
# into the branch
|
||||||
@ -111,7 +111,7 @@ proc mergePayloadImpl(
|
|||||||
|
|
||||||
# We need to return vtx here because its pfx member hasn't yet been
|
# We need to return vtx here because its pfx member hasn't yet been
|
||||||
# sliced off and is therefore shared with the hike
|
# 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()
|
resetKeys()
|
||||||
return ok(res)
|
return ok(res)
|
||||||
@ -126,8 +126,8 @@ proc mergePayloadImpl(
|
|||||||
cur = next
|
cur = next
|
||||||
path = path.slice(n + 1)
|
path = path.slice(n + 1)
|
||||||
vtx =
|
vtx =
|
||||||
if leaf.isSome and leaf[].isValid and leaf[].pfx == path:
|
if leaf.isSome and leaf[].isSome and leaf[][].pfx == path:
|
||||||
leaf[]
|
leaf[][].to(VertexRef)
|
||||||
else:
|
else:
|
||||||
(?db.getVtxRc((root, next)))[0]
|
(?db.getVtxRc((root, next)))[0]
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ proc mergePayloadImpl(
|
|||||||
leafVtx = db.layersPutLeaf((root, local), path.slice(n + 1), payload)
|
leafVtx = db.layersPutLeaf((root, local), path.slice(n + 1), payload)
|
||||||
|
|
||||||
resetKeys()
|
resetKeys()
|
||||||
return ok((leafVtx, default(VertexRef), default(VertexRef)))
|
return ok((leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T)))
|
||||||
else:
|
else:
|
||||||
# Partial path match - we need to split the existing branch at
|
# Partial path match - we need to split the existing branch at
|
||||||
# the point of divergence, inserting a new branch
|
# the point of divergence, inserting a new branch
|
||||||
@ -163,7 +163,7 @@ proc mergePayloadImpl(
|
|||||||
db.layersPutVtx((root, cur), branch)
|
db.layersPutVtx((root, cur), branch)
|
||||||
|
|
||||||
resetKeys()
|
resetKeys()
|
||||||
return ok((leafVtx, default(VertexRef), default(VertexRef)))
|
return ok((leafVtx.to(T), Opt.none(NibblesBuf), Opt.none(T)))
|
||||||
|
|
||||||
err(MergeHikeFailed)
|
err(MergeHikeFailed)
|
||||||
|
|
||||||
@ -193,10 +193,10 @@ proc mergeAccountRecord*(
|
|||||||
|
|
||||||
# Update leaf cache both of the merged value and potentially the displaced
|
# Update leaf cache both of the merged value and potentially the displaced
|
||||||
# leaf resulting from splitting a leaf into a branch with two leaves
|
# leaf resulting from splitting a leaf into a branch with two leaves
|
||||||
db.layersPutAccLeaf(accPath, updated[0])
|
db.layersPutAccLeaf(accPath, Opt.some(updated[0]))
|
||||||
if updated[1].isValid:
|
if updated[1].isSome:
|
||||||
let otherPath = Hash32(getBytes(
|
let otherPath = Hash32(getBytes(
|
||||||
NibblesBuf.fromBytes(accPath.data).replaceSuffix(updated[1].pfx)))
|
NibblesBuf.fromBytes(accPath.data).replaceSuffix(updated[1][])))
|
||||||
db.layersPutAccLeaf(otherPath, updated[2])
|
db.layersPutAccLeaf(otherPath, updated[2])
|
||||||
|
|
||||||
ok true
|
ok true
|
||||||
@ -239,18 +239,18 @@ proc mergeStorageData*(
|
|||||||
|
|
||||||
# Update leaf cache both of the merged value and potentially the displaced
|
# Update leaf cache both of the merged value and potentially the displaced
|
||||||
# leaf resulting from splitting a leaf into a branch with two leaves
|
# 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(
|
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])
|
db.layersPutStoLeaf(mixUp(accPath, otherPath), updated[2])
|
||||||
|
|
||||||
if not stoID.isValid:
|
if not stoID.isValid:
|
||||||
# Make sure that there is an account that refers to that storage trie
|
# Make sure that there is an account that refers to that storage trie
|
||||||
var leaf = accHike.legs[^1].wp.vtx.dup # Dup on modify
|
var leaf = accHike.legs[^1].wp.vtx.dup # Dup on modify
|
||||||
leaf.lData.stoID = useID
|
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)
|
db.layersPutVtx((VertexID(1), accHike.legs[^1].wp.vid), leaf)
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
@ -145,9 +145,9 @@ proc zeroAdjust(
|
|||||||
|
|
||||||
proc toHike(pfx: NibblesBuf, root: VertexID, db: AristoDbRef): Hike =
|
proc toHike(pfx: NibblesBuf, root: VertexID, db: AristoDbRef): Hike =
|
||||||
when doLeast:
|
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:
|
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:
|
if 0 < hike.legs.len:
|
||||||
return ok(hike)
|
return ok(hike)
|
||||||
@ -354,7 +354,7 @@ proc nearbyNextLeafTie(
|
|||||||
): Result[PathID,(VertexID,AristoError)] =
|
): Result[PathID,(VertexID,AristoError)] =
|
||||||
## Variant of `nearbyNext()`, convenience wrapper
|
## Variant of `nearbyNext()`, convenience wrapper
|
||||||
var hike: Hike
|
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)
|
hike = ?hike.nearbyNext(db, hikeLenMax, moveRight)
|
||||||
|
|
||||||
if 0 < hike.legs.len:
|
if 0 < hike.legs.len:
|
||||||
@ -403,7 +403,7 @@ iterator rightPairs*(
|
|||||||
## Traverse the sub-trie implied by the argument `start` with increasing
|
## Traverse the sub-trie implied by the argument `start` with increasing
|
||||||
## order.
|
## order.
|
||||||
var hike: Hike
|
var hike: Hike
|
||||||
discard start.hikeUp(db, Opt.none(VertexRef), hike)
|
discard start.hikeUp(db, Opt.none(void), hike)
|
||||||
var rc = hike.right db
|
var rc = hike.right db
|
||||||
while rc.isOk:
|
while rc.isOk:
|
||||||
hike = rc.value
|
hike = rc.value
|
||||||
@ -431,7 +431,7 @@ iterator rightPairs*(
|
|||||||
hike.legs.setLen(hike.legs.len - 1)
|
hike.legs.setLen(hike.legs.len - 1)
|
||||||
break reuseHike
|
break reuseHike
|
||||||
# Fall back to default method
|
# 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
|
rc = hike.right db
|
||||||
# End while
|
# End while
|
||||||
@ -488,7 +488,7 @@ iterator leftPairs*(
|
|||||||
## the `path` field decremented by `1`.
|
## the `path` field decremented by `1`.
|
||||||
var
|
var
|
||||||
hike: Hike
|
hike: Hike
|
||||||
discard start.hikeUp(db, Opt.none(VertexRef), hike)
|
discard start.hikeUp(db, Opt.none(void), hike)
|
||||||
|
|
||||||
var rc = hike.left db
|
var rc = hike.left db
|
||||||
while rc.isOk:
|
while rc.isOk:
|
||||||
@ -517,7 +517,7 @@ iterator leftPairs*(
|
|||||||
hike.legs.setLen(hike.legs.len - 1)
|
hike.legs.setLen(hike.legs.len - 1)
|
||||||
break reuseHike
|
break reuseHike
|
||||||
# Fall back to default method
|
# 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
|
rc = hike.left db
|
||||||
# End while
|
# End while
|
||||||
|
@ -125,27 +125,17 @@ proc ctxAcceptChange(psc: PartStateCtx): Result[bool,AristoError] =
|
|||||||
|
|
||||||
proc ctxMergeBegin*(
|
proc ctxMergeBegin*(
|
||||||
ps: PartStateRef;
|
ps: PartStateRef;
|
||||||
root: VertexID;
|
accPath: Hash32;
|
||||||
path: openArray[byte];
|
|
||||||
): Result[PartStateCtx,AristoError] =
|
): Result[PartStateCtx,AristoError] =
|
||||||
## This function clears the way for mering some payload at the argument
|
## Variant of `partMergeBegin()` for different path representation
|
||||||
## path `(root,path)`.
|
|
||||||
var hike: Hike
|
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:
|
if error[1] != HikeDanglingEdge:
|
||||||
return err error[1] # Cannot help here
|
return err error[1] # Cannot help here
|
||||||
return ps.newCtx hike
|
return ps.newCtx hike
|
||||||
|
|
||||||
ok PartStateCtx(nil) # Nothing to do
|
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] =
|
proc ctxMergeCommit*(psc: PartStateCtx): Result[bool,AristoError] =
|
||||||
##
|
##
|
||||||
if psc.isNil:
|
if psc.isNil:
|
||||||
|
@ -153,7 +153,7 @@ proc testCreatePortalProof(node: JsonNode, testStatusIMPL: var TestStatus) {.dep
|
|||||||
let
|
let
|
||||||
path = a.data.keccak256
|
path = a.data.keccak256
|
||||||
var hike: Hike
|
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(
|
sample[path] = ProofData(
|
||||||
error: (if rc.isErr: rc.error[1] else: AristoError(0)),
|
error: (if rc.isErr: rc.error[1] else: AristoError(0)),
|
||||||
hike: hike) # keep `hike` for potential debugging
|
hike: hike) # keep `hike` for potential debugging
|
||||||
|
@ -95,7 +95,7 @@ proc randomisedLeafs(
|
|||||||
var lvp: seq[(LeafTie,RootedVertexID)]
|
var lvp: seq[(LeafTie,RootedVertexID)]
|
||||||
for lty in ltys:
|
for lty in ltys:
|
||||||
var hike: Hike
|
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))
|
lvp.add (lty,(hike.root, hike.legs[^1].wp.vid))
|
||||||
|
|
||||||
var lvp2 = lvp.sorted(
|
var lvp2 = lvp.sorted(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user