simplify VertexRef (#2626)

* move pfx out of variant which avoids pointless field type panic checks
and copies on access
* make `VertexRef` a non-inheritable object which reduces its memory
footprint and simplifies its use - it's also unclear from a semantic
point of view why inheritance makes sense for storing keys
This commit is contained in:
Jacek Sieka 2024-09-13 18:55:17 +02:00 committed by GitHub
parent 0be6291fba
commit adb8d64377
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 133 additions and 143 deletions

View File

@ -200,8 +200,8 @@ proc blobifyTo*(vtx: VertexRef; data: var Blob): Result[void,AristoError] =
let
pSegm =
if vtx.ePfx.len > 0:
vtx.ePfx.toHexPrefix(isleaf = false)
if vtx.pfx.len > 0:
vtx.pfx.toHexPrefix(isleaf = false)
else:
default(HexPrefixBuf)
psLen = pSegm.len.byte
@ -214,7 +214,7 @@ proc blobifyTo*(vtx: VertexRef; data: var Blob): Result[void,AristoError] =
of Leaf:
let
pSegm = vtx.lPfx.toHexPrefix(isleaf = true)
pSegm = vtx.pfx.toHexPrefix(isleaf = true)
psLen = pSegm.len.byte
if psLen == 0 or 33 < psLen:
return err(BlobifyLeafPathOverflow)
@ -325,7 +325,7 @@ proc deblobify*(
# End `while`
VertexRef(
vType: Branch,
ePfx: pathSegment,
pfx: pathSegment,
bVid: vtxList)
of 3: # `Leaf` vertex
@ -341,7 +341,7 @@ proc deblobify*(
return err(DeblobLeafGotExtPrefix)
let vtx = VertexRef(
vType: Leaf,
lPfx: pathSegment)
pfx: pathSegment)
? record.toOpenArray(0, pLen - 1).deblobify(vtx.lData)
vtx

View File

@ -68,7 +68,7 @@ proc computeKeyImpl(
case vtx.vType:
of Leaf:
writer.startList(2)
writer.append(vtx.lPfx.toHexPrefix(isLeaf = true).data())
writer.append(vtx.pfx.toHexPrefix(isLeaf = true).data())
case vtx.lData.pType
of AccountData:
@ -106,12 +106,12 @@ proc computeKeyImpl(
else:
w.append(VOID_HASH_KEY)
w.append EmptyBlob
if vtx.ePfx.len > 0: # Extension node
if vtx.pfx.len > 0: # Extension node
var bwriter = initRlpWriter()
writeBranch(bwriter)
writer.startList(2)
writer.append(vtx.ePfx.toHexPrefix(isleaf = false).data())
writer.append(vtx.pfx.toHexPrefix(isleaf = false).data())
writer.append(bwriter.finish().digestTo(HashKey))
else:
writeBranch(writer)

View File

@ -209,9 +209,9 @@ proc ppVtx(nd: VertexRef, db: AristoDbRef, rvid: RootedVertexID): string =
result = ["ł(", "þ("][nd.vType.ord]
case nd.vType:
of Leaf:
result &= nd.lPfx.ppPathPfx & "," & nd.lData.ppPayload(db)
result &= nd.pfx.ppPathPfx & "," & nd.lData.ppPayload(db)
of Branch:
result &= nd.ePfx.ppPathPfx & ":"
result &= nd.pfx.ppPathPfx & ":"
for n in 0..15:
if nd.bVid[n].isValid:
result &= nd.bVid[n].ppVid
@ -229,33 +229,33 @@ proc ppNode(
result = "ø"
else:
if not rvid.isValid:
result = ["L(", "B("][nd.vType.ord]
result = ["L(", "B("][nd.vtx.vType.ord]
elif db.layersGetKey(rvid).isOk:
result = ["l(", "b("][nd.vType.ord]
result = ["l(", "b("][nd.vtx.vType.ord]
else:
result = ["ł(", "þ("][nd.vType.ord]
case nd.vType:
result = ["ł(", "þ("][nd.vtx.vType.ord]
case nd.vtx.vType:
of Leaf:
result &= nd.lPfx.ppPathPfx & ","
if nd.lData.pType == AccountData:
result &= "(" & nd.lData.account.ppAriAccount() & ","
if nd.lData.stoID.isValid:
let tag = db.ppKeyOk(nd.key[0],(rvid.root,nd.lData.stoID.vid))
result &= nd.lData.stoID.ppVid & tag
result &= nd.vtx.pfx.ppPathPfx & ","
if nd.vtx.lData.pType == AccountData:
result &= "(" & nd.vtx.lData.account.ppAriAccount() & ","
if nd.vtx.lData.stoID.isValid:
let tag = db.ppKeyOk(nd.key[0],(rvid.root,nd.vtx.lData.stoID.vid))
result &= nd.vtx.lData.stoID.ppVid & tag
else:
result &= nd.lData.stoID.ppVid
result &= nd.vtx.lData.stoID.ppVid
if nd.key[0].isValid:
result &= nd.key[0].ppKey(db)
result &= ")"
else:
result &= nd.lData.ppPayload(db)
result &= nd.vtx.lData.ppPayload(db)
of Branch:
let keyOnly = nd.bVid.toSeq.filterIt(it.isValid).len == 0
result &= nd.ePfx.ppPathPfx & ":"
let keyOnly = nd.vtx.bVid.toSeq.filterIt(it.isValid).len == 0
result &= nd.vtx.pfx.ppPathPfx & ":"
for n in 0..15:
if nd.bVid[n].isValid:
let tag = db.ppKeyOk(nd.key[n],(rvid.root,nd.bVid[n]))
result &= nd.bVid[n].ppVid & tag
if nd.vtx.bVid[n].isValid:
let tag = db.ppKeyOk(nd.key[n],(rvid.root,nd.vtx.bVid[n]))
result &= nd.vtx.bVid[n].ppVid & tag
elif keyOnly and nd.key[n].isValid:
result &= nd.key[n].ppKey(db)
if n < 15:

View File

@ -97,12 +97,12 @@ proc deleteImpl(
of Leaf:
VertexRef(
vType: Leaf,
lPfx: br.vtx.ePfx & NibblesBuf.nibble(nbl.byte) & nxt.lPfx,
pfx: br.vtx.pfx & NibblesBuf.nibble(nbl.byte) & nxt.pfx,
lData: nxt.lData)
of Branch:
VertexRef(
vType: Branch,
ePfx: br.vtx.ePfx & NibblesBuf.nibble(nbl.byte) & nxt.ePfx,
pfx: br.vtx.pfx & NibblesBuf.nibble(nbl.byte) & nxt.pfx,
bVid: nxt.bVid)
# Put the new vertex at the id of the obsolete branch

View File

@ -58,10 +58,10 @@ proc delStoTreeNow(
if vtx.bVid[i].isValid:
? db.delStoTreeNow(
(rvid.root, vtx.bVid[i]), accPath,
stoPath & vtx.ePfx & NibblesBuf.nibble(byte i))
stoPath & vtx.pfx & NibblesBuf.nibble(byte i))
of Leaf:
let stoPath = Hash256(data: (stoPath & vtx.lPfx).getBytes())
let stoPath = Hash256(data: (stoPath & vtx.pfx).getBytes())
db.layersPutStoLeaf(mixUp(accPath, stoPath), nil)
db.disposeOfVtx(rvid)

View File

@ -68,20 +68,21 @@ type
of StoData:
stoData*: UInt256
VertexRef* = ref object of RootRef
VertexRef* = ref object
## Vertex for building a hexary Patricia or Merkle Patricia Trie
pfx*: NibblesBuf
## Portion of path segment - extension nodes are branch nodes with
## non-empty prefix
case vType*: VertexType
of Leaf:
lPfx*: NibblesBuf ## Portion of path segment
lData*: LeafPayload ## Reference to data payload
of Branch:
ePfx*: NibblesBuf ## Portion of path segment - if non-empty,
## it's an extension node!
bVid*: array[16,VertexID] ## Edge list with vertex IDs
NodeRef* = ref object of VertexRef
NodeRef* = ref object of RootRef
## Combined record for a *traditional* ``Merkle Patricia Tree` node merged
## with a structural `VertexRef` type object.
vtx*: VertexRef
key*: array[16,HashKey] ## Merkle hash/es for vertices
# ----------------------
@ -174,21 +175,21 @@ proc `==`*(a, b: VertexRef): bool =
return false
case a.vType:
of Leaf:
if a.lPfx != b.lPfx or a.lData != b.lData:
if a.pfx != b.pfx or a.lData != b.lData:
return false
of Branch:
if a.ePfx != b.ePfx or a.bVid != b.bVid:
if a.pfx != b.pfx or a.bVid != b.bVid:
return false
true
proc `==`*(a, b: NodeRef): bool =
## Beware, potential deep comparison
if a.VertexRef != b.VertexRef:
if a.vtx != b.vtx:
return false
case a.vType:
case a.vtx.vType:
of Branch:
for n in 0..15:
if a.bVid[n] != 0.VertexID or b.bVid[n] != 0.VertexID:
if a.vtx.bVid[n] != 0.VertexID or b.vtx.bVid[n] != 0.VertexID:
if a.key[n] != b.key[n]:
return false
else:
@ -227,12 +228,12 @@ func dup*(vtx: VertexRef): VertexRef =
of Leaf:
VertexRef(
vType: Leaf,
lPfx: vtx.lPfx,
pfx: vtx.pfx,
lData: vtx.lData.dup)
of Branch:
VertexRef(
vType: Branch,
ePfx: vtx.ePfx,
pfx: vtx.pfx,
bVid: vtx.bVid)
func dup*(node: NodeRef): NodeRef =
@ -241,19 +242,9 @@ func dup*(node: NodeRef): NodeRef =
if node.isNil:
NodeRef(nil)
else:
case node.vType:
of Leaf:
NodeRef(
vType: Leaf,
lPfx: node.lPfx,
lData: node.lData.dup,
key: node.key)
of Branch:
NodeRef(
vType: Branch,
ePfx: node.ePfx,
bVid: node.bVid,
key: node.key)
NodeRef(
vtx: node.vtx.dup(),
key: node.key)
func dup*(wp: VidVtxPair): VidVtxPair =
## Safe copy of `wp` argument

View File

@ -47,9 +47,9 @@ func getNibblesImpl(hike: Hike; start = 0; maxLen = high(int)): NibblesBuf =
let leg = hike.legs[n]
case leg.wp.vtx.vType:
of Branch:
result = result & leg.wp.vtx.ePfx & NibblesBuf.nibble(leg.nibble.byte)
result = result & leg.wp.vtx.pfx & NibblesBuf.nibble(leg.nibble.byte)
of Leaf:
result = result & leg.wp.vtx.lPfx
result = result & leg.wp.vtx.pfx
# ------------------------------------------------------------------------------
# Public functions
@ -89,24 +89,24 @@ proc step*(
case vtx.vType:
of Leaf:
# This must be the last vertex, so there cannot be any `tail` left.
if path.len != path.sharedPrefixLen(vtx.lPfx):
if path.len != path.sharedPrefixLen(vtx.pfx):
return err(HikeLeafUnexpected)
ok (vtx, NibblesBuf(), VertexID(0))
of Branch:
# There must be some more data (aka `tail`) after a `Branch` vertex.
if path.len <= vtx.ePfx.len:
if path.len <= vtx.pfx.len:
return err(HikeBranchTailEmpty)
let
nibble = path[vtx.ePfx.len].int8
nibble = path[vtx.pfx.len].int8
nextVid = vtx.bVid[nibble]
if not nextVid.isValid:
return err(HikeBranchMissingEdge)
ok (vtx, path.slice(vtx.ePfx.len + 1), nextVid)
ok (vtx, path.slice(vtx.pfx.len + 1), nextVid)
iterator stepUp*(
@ -162,7 +162,7 @@ proc hikeUp*(
break
of Branch:
hike.legs.add Leg(wp: wp, nibble: int8 hike.tail[vtx.ePfx.len])
hike.legs.add Leg(wp: wp, nibble: int8 hike.tail[vtx.pfx.len])
hike.tail = path
vid = next

View File

@ -16,17 +16,12 @@ import eth/common, results, ".."/[aristo_desc, aristo_get, aristo_layers, aristo
# Private getters & setters
# ------------------------------------------------------------------------------
proc xPfx(vtx: VertexRef): NibblesBuf =
case vtx.vType
of Leaf: vtx.lPfx
of Branch: vtx.ePfx
# -----------
proc layersPutLeaf(
db: AristoDbRef, rvid: RootedVertexID, path: NibblesBuf, payload: LeafPayload
): VertexRef =
let vtx = VertexRef(vType: Leaf, lPfx: path, lData: payload)
let vtx = VertexRef(vType: Leaf, pfx: path, lData: payload)
db.layersPutVtx(rvid, vtx)
vtx
@ -68,11 +63,11 @@ proc mergePayloadImpl*(
touched[pos] = cur
pos += 1
let n = path.sharedPrefixLen(vtx.xPfx)
let n = path.sharedPrefixLen(vtx.pfx)
case vtx.vType
of Leaf:
let leafVtx =
if n == vtx.lPfx.len:
if n == vtx.pfx.len:
# Same path - replace the current vertex with a new payload
if vtx.lData == payload:
@ -92,11 +87,11 @@ proc mergePayloadImpl*(
else:
# Turn leaf into a branch (or extension) then insert the two leaves
# into the branch
let branch = VertexRef(vType: Branch, ePfx: path.slice(0, n))
let branch = VertexRef(vType: Branch, pfx: path.slice(0, n))
block: # Copy of existing leaf node, now one level deeper
let local = db.vidFetch()
branch.bVid[vtx.lPfx[n]] = local
discard db.layersPutLeaf((root, local), vtx.lPfx.slice(n + 1), vtx.lData)
branch.bVid[vtx.pfx[n]] = local
discard db.layersPutLeaf((root, local), vtx.pfx.slice(n + 1), vtx.lData)
let leafVtx = block: # Newly inserted leaf node
let local = db.vidFetch()
@ -111,10 +106,10 @@ proc mergePayloadImpl*(
resetKeys()
return ok(leafVtx)
of Branch:
if vtx.ePfx.len == n:
if vtx.pfx.len == n:
# The existing branch is a prefix of the new entry
let
nibble = path[vtx.ePfx.len]
nibble = path[vtx.pfx.len]
next = vtx.bVid[nibble]
if next.isValid:
@ -137,14 +132,14 @@ proc mergePayloadImpl*(
else:
# Partial path match - we need to split the existing branch at
# the point of divergence, inserting a new branch
let branch = VertexRef(vType: Branch, ePfx: path.slice(0, n))
let branch = VertexRef(vType: Branch, pfx: path.slice(0, n))
block: # Copy the existing vertex and add it to the new branch
let local = db.vidFetch()
branch.bVid[vtx.ePfx[n]] = local
branch.bVid[vtx.pfx[n]] = local
db.layersPutVtx(
(root, local),
VertexRef(vType: Branch, ePfx: vtx.ePfx.slice(n + 1), bVid: vtx.bVid),
VertexRef(vType: Branch, pfx: vtx.pfx.slice(n + 1), bVid: vtx.bVid),
)
let leafVtx = block: # add the new entry

View File

@ -170,10 +170,10 @@ proc zeroAdjust(
if n < 0:
# Before or after the database range
return err((hike.root,NearbyBeyondRange))
pfx = rootVtx.ePfx & NibblesBuf.nibble(n.byte)
pfx = rootVtx.pfx & NibblesBuf.nibble(n.byte)
of Leaf:
pfx = rootVtx.lPfx
pfx = rootVtx.pfx
if not hike.accept pfx:
# Before or after the database range
return err((hike.root,NearbyBeyondRange))
@ -230,12 +230,12 @@ proc finalise(
if not vtx.isValid:
return err((vid,NearbyDanglingLink))
var pfx: NibblesBuf
case vtx.vType:
of Leaf:
pfx = vtx.lPfx
of Branch:
pfx = vtx.ePfx & NibblesBuf.nibble(vtx.branchBorderNibble.byte)
let pfx =
case vtx.vType:
of Leaf:
vtx.pfx
of Branch:
vtx.pfx & NibblesBuf.nibble(vtx.branchBorderNibble.byte)
if hike.beyond pfx:
return err((vid,NearbyBeyondRange))
@ -308,7 +308,7 @@ proc nearbyNext(
case vtx.vType
of Leaf:
if uHike.accept vtx.lPfx:
if uHike.accept vtx.pfx:
return uHike.complete(vid, db, hikeLenMax, doLeast=moveRight)
of Branch:
let nibble = uHike.tail[0].int8
@ -408,7 +408,7 @@ iterator rightPairs*(
# Increment `key` by one and update `hike`. In many cases, the current
# `hike` can be modified and re-used which saves some database lookups.
block reuseHike:
let tail = hike.legs[^1].wp.vtx.lPfx
let tail = hike.legs[^1].wp.vtx.pfx
if 0 < tail.len:
let topNibble = tail[tail.len - 1]
if topNibble < 15:
@ -503,7 +503,7 @@ iterator leftPairs*(
# Decrement `key` by one and update `hike`. In many cases, the current
# `hike` can be modified and re-used which saves some database lookups.
block reuseHike:
let tail = hike.legs[^1].wp.vtx.lPfx
let tail = hike.legs[^1].wp.vtx.pfx
if 0 < tail.len:
let topNibble = tail[tail.len - 1]
if 0 < topNibble:
@ -567,7 +567,7 @@ proc rightMissing*(
case vtx.vType
of Leaf:
return ok(vtx.lPfx < hike.tail)
return ok(vtx.pfx < hike.tail)
of Branch:
return ok(vtx.branchNibbleMin(hike.tail[0].int8) < 0)

View File

@ -238,11 +238,11 @@ proc partPut*(
# Register core node. Even though these nodes are only local to this
# loop local, they need to be updated because another `chain` might
# merge into this one at exactly this node.
case node.vType:
case node.vtx.vType:
of Leaf:
node.lData = vtx.lData
node.vtx.lData = vtx.lData
of Branch:
node.bVid = vtx.bVid
node.vtx.bVid = vtx.bVid
ps.addCore(root, key) # register core node
ps.pureExt.del key # core node can't be an extension
continue
@ -251,27 +251,27 @@ proc partPut*(
# stored separately off the database and will only be temporarily
# inserted into the database on demand.
if node.prfType == isExtension:
ps.pureExt[key] = PrfExtension(xPfx: node.ePfx, xLink: node.key[0])
ps.pureExt[key] = PrfExtension(xPfx: node.vtx.pfx, xLink: node.key[0])
continue
# Otherwise assign new VIDs to a core node. Even though these nodes are
# only local to this loop local, they need to be updated because another
# `chain` might merge into this one at exactly this node.
case node.vType:
case node.vtx.vType:
of Leaf:
let lKey = node.key[0]
if node.lData.pType == AccountData and lKey.isValid:
node.lData.stoID = (true, (? ps.getRvid(root, lKey))[0].vid)
if node.vtx.lData.pType == AccountData and lKey.isValid:
node.vtx.lData.stoID = (true, (? ps.getRvid(root, lKey))[0].vid)
of Branch:
for n in 0 .. 15:
let bKey = node.key[n]
if bKey.isValid:
node.bVid[n] = (? ps.getRvid(root, bKey))[0].vid
node.vtx.bVid[n] = (? ps.getRvid(root, bKey))[0].vid
ps.addCore(root, key) # register core node
ps.pureExt.del key # core node can't be an extension
# Store vertex on database
ps.db.layersPutVtx(rvid, VertexRef(node))
ps.db.layersPutVtx(rvid, node.vtx)
seen.incl key # node was processed here
if stopHere: # follow up tail of earlier chain
#discard ps.pp()
@ -456,7 +456,7 @@ proc partWithExtBegin*(ps: PartStateRef): Result[void,AristoError] =
if ps.db.getKey(rvid).isValid:
restore()
return err(PartExtVtxExistsAlready)
ps.db.layersPutVtx(rvid, VertexRef(vType: Branch, ePfx: ext.xPfx))
ps.db.layersPutVtx(rvid, VertexRef(vType: Branch, pfx: ext.xPfx))
rollback.add rvid
ok()
@ -464,7 +464,7 @@ proc partWithExtEnd*(ps: PartStateRef): Result[void,AristoError] =
var rollback: seq[(RootedVertexID,PrfExtension)]
proc restore() =
for (rvid,ext) in rollback:
ps.db.layersPutVtx(rvid, VertexRef(vType: Branch, ePfx: ext.xPfx))
ps.db.layersPutVtx(rvid, VertexRef(vType: Branch, pfx: ext.xPfx))
for (key,ext) in ps.pureExt.pairs:
let rvid = ps[key]
@ -474,7 +474,7 @@ proc partWithExtEnd*(ps: PartStateRef): Result[void,AristoError] =
restore()
return err(PartExtVtxHasVanished)
if vtx.vType != Branch or
vtx.ePfx != ext.xPfx or
vtx.pfx != ext.xPfx or
vtx.bVid != array[16,VertexID].default:
restore()
return err(PartExtVtxWasModified)

View File

@ -48,14 +48,14 @@ proc chainRlpNodes*(
# Follow up child node
case vtx.vType:
of Leaf:
if path != vtx.lPfx:
if path != vtx.pfx:
err(PartChnLeafPathMismatch)
else:
ok()
of Branch:
let nChewOff = sharedPrefixLen(vtx.ePfx, path)
if nChewOff != vtx.ePfx.len:
let nChewOff = sharedPrefixLen(vtx.pfx, path)
if nChewOff != vtx.pfx.len:
err(PartChnExtPfxMismatch)
elif path.len == nChewOff:
err(PartChnBranchPathExhausted)

View File

@ -41,7 +41,7 @@ proc pp*(n: PrfNode; ps: PartStateRef): string =
elif n.prfType == isError:
"(" & $n.error & ")"
elif n.prfType == isExtension:
"X(" & n.ePfx.pp & "," & n.key[0].pp(ps.db) & ")"
"X(" & n.vtx.pfx.pp & "," & n.key[0].pp(ps.db) & ")"
else:
"(" & NodeRef(n).pp(ps.db) & ")"

View File

@ -27,7 +27,7 @@ proc read(rlp: var Rlp; T: type PrfNode): T {.gcsafe, raises: [RlpError].} =
##
func readError(error: AristoError): PrfNode =
## Prettify return code expression
PrfNode(vType: Leaf, prfType: isError, error: error)
PrfNode(vtx: VertexRef(vType: Leaf), prfType: isError, error: error)
if not rlp.isList:
# Otherwise `rlp.items` would raise a `Defect`
@ -64,17 +64,20 @@ proc read(rlp: var Rlp; T: type PrfNode): T {.gcsafe, raises: [RlpError].} =
let (isLeaf, pathSegment) = NibblesBuf.fromHexPrefix blobs[0]
if isLeaf:
return PrfNode(
vType: Leaf,
prfType: ignore,
lPfx: pathSegment,
lData: LeafPayload(
pType: RawData,
rawBlob: blobs[1]))
vtx: VertexRef(
vType: Leaf,
pfx: pathSegment,
lData: LeafPayload(
pType: RawData,
rawBlob: blobs[1])))
else:
var node = PrfNode(
vType: Branch,
prfType: isExtension,
ePfx: pathSegment)
vtx: VertexRef(
vType: Branch,
pfx: pathSegment))
node.key[0] = HashKey.fromBytes(blobs[1]).valueOr:
return readError(PartRlpExtHashKeyExpected)
return node
@ -83,7 +86,8 @@ proc read(rlp: var Rlp; T: type PrfNode): T {.gcsafe, raises: [RlpError].} =
links[n] = HashKey.fromBytes(blobs[n]).valueOr:
return readError(PartRlpBranchHashKeyExpected)
return PrfNode(
vType: Branch,
vtx: VertexRef(
vType: Branch),
prfType: ignore,
key: links)
else:
@ -137,11 +141,11 @@ func toNodesTab*(
nodes[w.digestTo HashKey] = nd
# Special decoding for account `Leaf` nodes
if nd.vType == Leaf and mode != ForceGenericPayload:
if nd.vtx.vType == Leaf and mode != ForceGenericPayload:
# Decode payload to deficated format for storage or accounts
var pyl: PrfPayload
try:
pyl = rlp.decode(nd.lData.rawBlob, PrfPayload)
pyl = rlp.decode(nd.vtx.lData.rawBlob, PrfPayload)
except RlpError:
pyl = PrfPayload(prfType: isError, error: PartRlpPayloadException)
@ -150,10 +154,10 @@ func toNodesTab*(
# Single value encoding might not be unique so it cannot be
# automatically detected
if mode != AutomaticPayload:
nd.lData = LeafPayload(pType: StoData, stoData: pyl.num)
nd.vtx.lData = LeafPayload(pType: StoData, stoData: pyl.num)
of isAccount:
nd.key[0] = pyl.acc.storageRoot.to(HashKey)
nd.lData = LeafPayload(
nd.vtx.lData = LeafPayload(
pType: AccountData,
account: AristoAccount(
nonce: pyl.acc.nonce,
@ -174,11 +178,11 @@ func toNodesTab*(
# Need to store raw extension
nodes[xKey] = xNode
continue
if nd.ePfx.len != 0:
if nd.vtx.pfx.len != 0:
return err(PartGarbledExtsInProofs)
# Move extended `nd` branch node
nd.prfType = ignore
nd.ePfx = xNode.ePfx
nd.vtx.pfx = xNode.vtx.pfx
nodes.del xNode.key[0]
nodes[xKey] = nd
@ -196,8 +200,8 @@ proc backLinks*(nTab: TableRef[HashKey,PrfNode]): PrfBackLinks =
# Collect predecessor list
for (key,nd) in nTab.pairs:
if nd.vType == Leaf:
if nd.lData.pType == AccountData and nd.key[0].isValid:
if nd.vtx.vType == Leaf:
if nd.vtx.lData.pType == AccountData and nd.key[0].isValid:
result.links[nd.key[0]] = key
elif nd.prfType == isExtension:
result.links[nd.key[0]] = key
@ -280,7 +284,7 @@ proc updateAccountsTree*(
for chain in bl.chains:
for key in chain:
nodes[].withValue(key,node):
if node.vType == Leaf and node.lData.pType == AccountData:
if node.vtx.vType == Leaf and node.vtx.lData.pType == AccountData:
# Ok, got an accounts leaf node
if not accRootKey.isValid:

View File

@ -70,7 +70,7 @@ proc to*(node: NodeRef; T: type seq[Blob]): T =
## `<rlp-encoded-node>` type entries. Only in case of a combined extension
## and branch vertex argument, there will be a double item list result.
##
case node.vType:
case node.vtx.vType:
of Branch:
# Do branch node
var wr = initRlpWriter()
@ -80,13 +80,13 @@ proc to*(node: NodeRef; T: type seq[Blob]): T =
wr.append EmptyBlob
let brData = wr.finish()
if 0 < node.ePfx.len:
if 0 < node.vtx.pfx.len:
# Prefix branch by embedded extension node
let brHash = brData.digestTo(HashKey)
var wrx = initRlpWriter()
wrx.startList(2)
wrx.append node.ePfx.toHexPrefix(isleaf = false).data()
wrx.append node.vtx.pfx.toHexPrefix(isleaf = false).data()
wrx.append brHash
result.add wrx.finish()
@ -104,8 +104,8 @@ proc to*(node: NodeRef; T: type seq[Blob]): T =
var wr = initRlpWriter()
wr.startList(2)
wr.append node.lPfx.toHexPrefix(isleaf = true).data()
wr.append node.lData.serialise(getKey0).value
wr.append node.vtx.pfx.toHexPrefix(isleaf = true).data()
wr.append node.vtx.lData.serialise(getKey0).value
result.add (wr.finish())
@ -114,7 +114,7 @@ proc digestTo*(node: NodeRef; T: type HashKey): T =
## that a `Dummy` node is encoded as as a `Leaf`.
##
var wr = initRlpWriter()
case node.vType:
case node.vtx.vType:
of Branch:
# Do branch node
wr.startList(17)
@ -123,11 +123,11 @@ proc digestTo*(node: NodeRef; T: type HashKey): T =
wr.append EmptyBlob
# Do for embedded extension node
if 0 < node.ePfx.len:
if 0 < node.vtx.pfx.len:
let brHash = wr.finish().digestTo(HashKey)
wr = initRlpWriter()
wr.startList(2)
wr.append node.ePfx.toHexPrefix(isleaf = false).data()
wr.append node.vtx.pfx.toHexPrefix(isleaf = false).data()
wr.append brHash
of Leaf:
@ -138,8 +138,8 @@ proc digestTo*(node: NodeRef; T: type HashKey): T =
ok(node.key[0]) # always succeeds
wr.startList(2)
wr.append node.lPfx.toHexPrefix(isleaf = true).data()
wr.append node.lData.serialise(getKey0).value
wr.append node.vtx.pfx.toHexPrefix(isleaf = true).data()
wr.append node.vtx.lData.serialise(getKey0).value
wr.finish().digestTo(HashKey)

View File

@ -56,7 +56,7 @@ proc toNode*(
case vtx.vType:
of Leaf:
let node = NodeRef(vType: Leaf, lPfx: vtx.lPfx, lData: vtx.lData)
let node = NodeRef(vtx: vtx.dup())
# Need to resolve storage root for account leaf
if vtx.lData.pType == AccountData:
let stoID = vtx.lData.stoID
@ -68,7 +68,7 @@ proc toNode*(
return ok node
of Branch:
let node = NodeRef(vType: Branch, bVid: vtx.bVid, ePfx: vtx.ePfx)
let node = NodeRef(vtx: vtx.dup())
var missing: seq[VertexID]
for n in 0 .. 15:
let vid = vtx.bVid[n]
@ -100,15 +100,15 @@ iterator subVids*(vtx: VertexRef): VertexID =
iterator subVidKeys*(node: NodeRef): (VertexID,HashKey) =
## Simolar to `subVids()` but for nodes
case node.vType:
case node.vtx.vType:
of Leaf:
if node.lData.pType == AccountData:
let stoID = node.lData.stoID
if node.vtx.lData.pType == AccountData:
let stoID = node.vtx.lData.stoID
if stoID.isValid:
yield (stoID.vid, node.key[0])
of Branch:
for n in 0 .. 15:
let vid = node.bVid[n]
let vid = node.vtx.bVid[n]
if vid.isValid:
yield (vid,node.key[n])

View File

@ -43,7 +43,7 @@ suite "Aristo blobify":
extension = VertexRef(
vType: Branch,
ePfx: NibblesBuf.nibble(2),
pfx: NibblesBuf.nibble(2),
bVid: [
VertexID(0),
VertexID(0),