From d7f40516a7aa7d98acb1f24733b4c0c052bc18d3 Mon Sep 17 00:00:00 2001 From: Jordan Hrycaj Date: Mon, 12 Jun 2023 19:16:03 +0100 Subject: [PATCH] Detach from snap/sync declarations & definitions (#1601) why: Tests and some basic components were originally borrowed from the snap/sync implementation. These have fully been re-implemented. --- nimbus/db/aristo/aristo_constants.nim | 11 +- nimbus/db/aristo/aristo_debug.nim | 27 ++-- nimbus/db/aristo/aristo_delete.nim | 2 +- nimbus/db/aristo/aristo_desc.nim | 18 +-- nimbus/db/aristo/aristo_desc/aristo_error.nim | 6 +- .../aristo_desc/aristo_types_backend.nim | 5 +- .../aristo_desc/aristo_types_identifiers.nim | 142 +++++++++++++++++- .../aristo_desc/aristo_types_private.nim | 15 ++ .../aristo_desc/aristo_types_structural.nim | 3 +- nimbus/db/aristo/aristo_get.nim | 10 +- nimbus/db/aristo/aristo_hashify.nim | 26 ++-- nimbus/db/aristo/aristo_hike.nim | 4 +- nimbus/db/aristo/aristo_init.nim | 19 ++- .../db/aristo/aristo_init/aristo_memory.nim | 10 +- nimbus/db/aristo/aristo_merge.nim | 52 +++---- nimbus/db/aristo/aristo_nearby.nim | 41 +++-- nimbus/db/aristo/aristo_path.nim | 26 ++-- nimbus/db/aristo/aristo_transcode.nim | 38 ++--- nimbus/db/aristo/aristo_vid.nim | 2 +- tests/test_aristo/test_aristo_cache.nim | 14 +- tests/test_aristo/test_delete.nim | 5 +- tests/test_aristo/test_helpers.nim | 24 ++- tests/test_aristo/test_merge.nim | 4 +- tests/test_aristo/test_nearby.nim | 21 ++- 24 files changed, 330 insertions(+), 195 deletions(-) create mode 100644 nimbus/db/aristo/aristo_desc/aristo_types_private.nim diff --git a/nimbus/db/aristo/aristo_constants.nim b/nimbus/db/aristo/aristo_constants.nim index fe7f0de1f..834735aa6 100644 --- a/nimbus/db/aristo/aristo_constants.nim +++ b/nimbus/db/aristo/aristo_constants.nim @@ -12,7 +12,6 @@ import eth/[common, trie/nibbles], - ../../sync/snap/range_desc, ./aristo_desc/aristo_types_identifiers const @@ -22,12 +21,12 @@ const EmptyNibbleSeq* = EmptyBlob.initNibbleRange ## Useful shortcut (borrowed from `sync/snap/constants.nim`) - VOID_NODE_KEY* = EMPTY_ROOT_HASH.to(NodeKey) - ## Equivalent of `nil` for Merkle hash ket - - VOID_CODE_KEY* = EMPTY_CODE_HASH.to(NodeKey) + VOID_CODE_KEY* = EMPTY_CODE_HASH.to(HashKey) ## Equivalent of `nil` for `Account` object code hash - VOID_HASH_LABEL* = HashLabel(root: VertexID(0), key: VOID_NODE_KEY) + VOID_HASH_KEY* = EMPTY_ROOT_HASH.to(HashKey) + ## Equivalent of `nil` for Merkle hash ket + + VOID_HASH_LABEL* = HashLabel(root: VertexID(0), key: VOID_HASH_KEY) # End diff --git a/nimbus/db/aristo/aristo_debug.nim b/nimbus/db/aristo/aristo_debug.nim index 9ad5ee780..24f65f105 100644 --- a/nimbus/db/aristo/aristo_debug.nim +++ b/nimbus/db/aristo/aristo_debug.nim @@ -14,7 +14,8 @@ import std/[algorithm, sequtils, sets, strutils, tables], eth/[common, trie/nibbles], stew/byteutils, - "."/[aristo_constants, aristo_desc, aristo_hike, aristo_vid] + "."/[aristo_constants, aristo_desc, aristo_hike, aristo_vid], + ./aristo_desc/aristo_types_private # ------------------------------------------------------------------------------ # Ptivate functions @@ -83,10 +84,10 @@ proc vidCode(lbl: HashLabel, db: AristoDb): uint64 = if vid.isValid: return vid.uint64 -proc ppKey(key: NodeKey): string = - if key == NodeKey.default: +proc ppKey(key: HashKey): string = + if key == HashKey.default: return "£ø" - if key == VOID_NODE_KEY: + if key == VOID_HASH_KEY: return "£r" if key == VOID_CODE_KEY: return "£c" @@ -96,9 +97,9 @@ proc ppKey(key: NodeKey): string = .squeeze(hex=true,ignLen=true) proc ppLabel(lbl: HashLabel; db: AristoDb): string = - if lbl.key == NodeKey.default: + if lbl.key == HashKey.default: return "£ø" - if lbl.key == VOID_NODE_KEY: + if lbl.key == VOID_HASH_KEY: return "£r" if lbl.key == VOID_CODE_KEY: return "£c" @@ -118,11 +119,11 @@ proc ppLabel(lbl: HashLabel; db: AristoDb): string = .mapIt(it.toHex(2)).join.tolowerAscii .squeeze(hex=true,ignLen=true) -proc ppRootKey(a: NodeKey): string = +proc ppRootKey(a: HashKey): string = if a.isValid: return a.ppKey -proc ppCodeKey(a: NodeKey): string = +proc ppCodeKey(a: HashKey): string = if a != VOID_CODE_KEY: return a.ppKey @@ -133,7 +134,7 @@ proc ppLeafTie(lty: LeafTie, db: AristoDb): string = return "@" & vid.ppVid "@" & ($lty.root.uint64.toHex).stripZeros & ":" & - lty.path.to(NodeKey).ByteArray32 + lty.path.to(HashKey).ByteArray32 .mapIt(it.toHex(2)).join.squeeze(hex=true,ignLen=true) proc ppPathPfx(pfx: NibblesSeq): string = @@ -154,8 +155,8 @@ proc ppPayload(p: PayloadRef, db: AristoDb): string = result = "(" result &= $p.account.nonce & "," result &= $p.account.balance & "," - result &= p.account.storageRoot.to(NodeKey).ppRootKey() & "," - result &= p.account.codeHash.to(NodeKey).ppCodeKey() & ")" + result &= p.account.storageRoot.to(HashKey).ppRootKey() & "," + result &= p.account.codeHash.to(HashKey).ppCodeKey() & ")" proc ppVtx(nd: VertexRef, db: AristoDb, vid: VertexID): string = if not nd.isValid: @@ -261,9 +262,9 @@ proc lblToVtxID*(db: var AristoDb, lbl: HashLabel): VertexID = db.xMap[lbl] = result proc hashToVtxID*(db: var AristoDb, root: VertexID; hash: Hash256): VertexID = - db.lblToVtxID HashLabel(root: root, key: hash.to(NodeKey)) + db.lblToVtxID HashLabel(root: root, key: hash.to(HashKey)) -proc pp*(key: NodeKey): string = +proc pp*(key: HashKey): string = key.ppKey proc pp*(lbl: HashLabel, db = AristoDb()): string = diff --git a/nimbus/db/aristo/aristo_delete.nim b/nimbus/db/aristo/aristo_delete.nim index 109f1f25d..e00a40a6a 100644 --- a/nimbus/db/aristo/aristo_delete.nim +++ b/nimbus/db/aristo/aristo_delete.nim @@ -78,7 +78,7 @@ proc deleteImpl( inx.dec while 0 <= inx: - # Unlink child node + # Unlink child vertex let br = hike.legs[inx].wp if br.vtx.vType != Branch: return err((br.vid,DelBranchExpexted)) diff --git a/nimbus/db/aristo/aristo_desc.nim b/nimbus/db/aristo/aristo_desc.nim index 8eef8bc04..c64ad6f80 100644 --- a/nimbus/db/aristo/aristo_desc.nim +++ b/nimbus/db/aristo/aristo_desc.nim @@ -16,16 +16,14 @@ ## ## Some semantic explanations; ## -## * NodeKey, NodeRef etc. refer to the standard/legacy `Merkel Patricia Tree` +## * HashKey, NodeRef etc. refer to the standard/legacy `Merkle Patricia Tree` ## * VertexID, VertexRef, etc. refer to the `Aristo Trie` ## {.push raises: [].} import std/[sets, tables], - eth/[common, trie/nibbles], - stew/results, - ../../sync/snap/range_desc, + eth/common, ./aristo_constants, ./aristo_desc/[ aristo_error, aristo_types_backend, @@ -36,9 +34,6 @@ export aristo_constants, aristo_error, aristo_types_identifiers, aristo_types_structural -export # This one should go away one time - ByteArray32, NodeKey, NodeTag, digestTo, hash, to, `==`, `$` - type AristoLayerRef* = ref object ## Hexary trie database layer structures. Any layer holds the full @@ -60,10 +55,6 @@ type # Debugging data below, might go away in future xMap*: Table[HashLabel,VertexID] ## For pretty printing, extends `pAmk` -static: - # Not that there is no doubt about this ... - doAssert NodeKey.default.ByteArray32.initNibbleRange.len == 64 - # ------------------------------------------------------------------------------ # Public helpers # ------------------------------------------------------------------------------ @@ -77,6 +68,7 @@ proc getOrVoid*[W](tab: Table[W,HashLabel]; w: W): HashLabel = proc getOrVoid*[W](tab: Table[W,VertexID]; w: W): VertexID = tab.getOrDefault(w, VertexID(0)) +# -------- proc isValid*(vtx: VertexRef): bool = vtx != VertexRef(nil) @@ -84,8 +76,8 @@ proc isValid*(vtx: VertexRef): bool = proc isValid*(nd: NodeRef): bool = nd != NodeRef(nil) -proc isValid*(key: NodeKey): bool = - key != VOID_NODE_KEY +proc isValid*(key: HashKey): bool = + key != VOID_HASH_KEY proc isValid*(lbl: HashLabel): bool = lbl != VOID_HASH_LABEL diff --git a/nimbus/db/aristo/aristo_desc/aristo_error.nim b/nimbus/db/aristo/aristo_desc/aristo_error.nim index e67688d0e..4f637d0ac 100644 --- a/nimbus/db/aristo/aristo_desc/aristo_error.nim +++ b/nimbus/db/aristo/aristo_desc/aristo_error.nim @@ -82,9 +82,9 @@ type MergeNonBranchProofModeLock MergeRootBranchLinkBusy - MergeNodeKeyEmpty - MergeNodeKeyCachedAlready - MergeNodeKeyDiffersFromCached + MergeHashKeyEmpty + MergeHashKeyCachedAlready + MergeHashKeyDiffersFromCached MergeRootKeyEmpty MergeRootKeyDiffersForVid diff --git a/nimbus/db/aristo/aristo_desc/aristo_types_backend.nim b/nimbus/db/aristo/aristo_desc/aristo_types_backend.nim index 409dd5740..b931c5fca 100644 --- a/nimbus/db/aristo/aristo_desc/aristo_types_backend.nim +++ b/nimbus/db/aristo/aristo_desc/aristo_types_backend.nim @@ -16,7 +16,6 @@ import stew/results, - ../../../sync/snap/range_desc, "."/[aristo_error, aristo_types_identifiers, aristo_types_structural] type @@ -26,7 +25,7 @@ type ## `Aristo DB` data record. GetKeyFn* = - proc(vid: VertexID): Result[NodeKey,AristoError] {.gcsafe, raises: [].} + proc(vid: VertexID): Result[HashKey,AristoError] {.gcsafe, raises: [].} ## Generic backend database retrieval function for a single ## `Aristo DB` hash lookup value. @@ -53,7 +52,7 @@ type ## Generic backend database bulk storage function. PutKeyFn* = - proc(hdl: PutHdlRef; vkps: openArray[(VertexID,NodeKey)]) + proc(hdl: PutHdlRef; vkps: openArray[(VertexID,HashKey)]) {.gcsafe, raises: [].} ## Generic backend database bulk storage function. diff --git a/nimbus/db/aristo/aristo_desc/aristo_types_identifiers.nim b/nimbus/db/aristo/aristo_desc/aristo_types_identifiers.nim index cbdb01e75..75304e070 100644 --- a/nimbus/db/aristo/aristo_desc/aristo_types_identifiers.nim +++ b/nimbus/db/aristo/aristo_desc/aristo_types_identifiers.nim @@ -15,9 +15,10 @@ {.push raises: [].} import - std/strutils, - eth/common, - ../../../sync/snap/range_desc + std/[strutils, hashes], + eth/[common, trie/nibbles], + stint, + ./aristo_types_private type VertexID* = distinct uint64 @@ -25,7 +26,20 @@ type ## prefix tree (aka `Patricia Trie`) component. When augmented by hash ## keys, the vertex component will be called a node. On the persistent ## backend of the database, there is no other reference to the node than - ## the very same `VertexID` + ## the very same `VertexID`. + + HashID* = distinct UInt256 + ## Variant of a `Hash256` object that can be used in a order relation + ## (i.e. it can be sorted.) Among temporary conversions for sorting, the + ## `HashID` type is consistently used for addressing leaf vertices (see + ## below `LeafTie`.) + + HashKey* = distinct ByteArray32 + ## Dedicated `Hash256` object variant that is used for labelling the + ## vertices of the `Patricia Trie` in order to make it a + ## `Merkle Patricia Tree`. + + # ---------- LeafTie* = object ## Unique access key for a leaf vertex. It identifies a root vertex @@ -37,7 +51,7 @@ type ## Note that `LeafTie` objects have no representation in the `Aristo Trie`. ## They are used temporarily and in caches or backlog tables. root*: VertexID ## Root ID for the sub-trie - path*: NodeTag ## Path into the `Patricia Trie` + path*: HashID ## Path into the `Patricia Trie` HashLabel* = object ## Merkle hash key uniquely associated with a vertex ID. As hashes in a @@ -47,8 +61,12 @@ type ## ## Note that `LeafTie` objects have no representation in the `Aristo Trie`. ## They are used temporarily and in caches or backlog tables. - root*: VertexID ## Root ID for the sub-trie - key*: NodeKey ## Path into the `Patricia Trie` + root*: VertexID ## Root ID for the sub-trie. + key*: HashKey ## Merkle hash tacked to a vertex. + +static: + # Not that there is no doubt about this ... + doAssert HashKey.default.ByteArray32.initNibbleRange.len == 64 # ------------------------------------------------------------------------------ # Public helpers: `VertexID` scalar data model @@ -62,6 +80,93 @@ proc `$`*(a: VertexID): string = $a.uint64 proc `==`*(a: VertexID; b: static[uint]): bool = a == VertexID(b) +# ------------------------------------------------------------------------------ +# Public helpers: `HashID` scalar data model +# ------------------------------------------------------------------------------ + +proc u256*(lp: HashID): UInt256 = lp.UInt256 +proc low*(T: type HashID): T = low(UInt256).T +proc high*(T: type HashID): T = high(UInt256).T + +proc `+`*(a: HashID; b: UInt256): HashID = (a.u256+b).HashID +proc `-`*(a: HashID; b: UInt256): HashID = (a.u256-b).HashID +proc `-`*(a, b: HashID): UInt256 = (a.u256 - b.u256) + +proc `==`*(a, b: HashID): bool = a.u256 == b.u256 +proc `<=`*(a, b: HashID): bool = a.u256 <= b.u256 +proc `<`*(a, b: HashID): bool = a.u256 < b.u256 + +proc cmp*(x, y: HashID): int = cmp(x.UInt256, y.UInt256) + +# ------------------------------------------------------------------------------ +# Public helpers: Conversions between `HashID`, `HashKey`, `Hash256` +# ------------------------------------------------------------------------------ + +proc to*(hid: HashID; T: type Hash256): T = + result.data = hid.UInt256.toBytesBE + +proc to*(hid: HashID; T: type HashKey): T = + hid.UInt256.toBytesBE.T + +proc to*(key: HashKey; T: type HashID): T = + UInt256.fromBytesBE(key.ByteArray32).T + +proc to*(key: HashKey; T: type Hash256): T = + T(data: ByteArray32(key)) + +proc to*(hash: Hash256; T: type HashKey): T = + hash.data.T + +proc to*(key: Hash256; T: type HashID): T = + key.data.HashKey.to(T) + +# ------------------------------------------------------------------------------ +# Public helpers: Miscellaneous mappings +# ------------------------------------------------------------------------------ + +proc to*(key: HashKey; T: type Blob): T = + ## Representation of a `HashKey` as `Blob` (preserving full information) + key.ByteArray32.toSeq + +proc to*(key: HashKey; T: type NibblesSeq): T = + ## Representation of a `HashKey` as `NibbleSeq` (preserving full information) + key.ByteArray32.initNibbleRange() + +proc to*(hid: HashID; T: type NibblesSeq): T = + ## Representation of a `HashKey` as `NibbleSeq` (preserving full information) + ByteArray32(hid.to(HashKey)).initNibbleRange() + +proc to*(n: SomeUnsignedInt|UInt256; T: type HashID): T = + ## Representation of a scalar as `HashID` (preserving full information) + n.u256.T + +proc digestTo*(data: Blob; T: type HashKey): T = + ## Keccak hash of a `Blob`, represented as a `HashKey` + keccakHash(data).data.T + +# ------------------------------------------------------------------------------ +# Public helpers: `Tables` and `Rlp` support +# ------------------------------------------------------------------------------ + +proc hash*(a: HashID): Hash = + ## Table/KeyedQueue mixin + a.to(HashKey).ByteArray32.hash + +proc hash*(a: HashKey): Hash = + ## Table/KeyedQueue mixin + a.ByteArray32.hash + +proc `==`*(a, b: HashKey): bool = + ## Table/KeyedQueue mixin + a.ByteArray32 == b.ByteArray32 + +proc read*[T: HashID|HashKey](rlp: var Rlp, W: type T): T + {.gcsafe, raises: [RlpError].} = + rlp.read(Hash256).to(T) + +proc append*(writer: var RlpWriter, val: HashID|HashKey) = + writer.append(val.to(Hash256)) + # ------------------------------------------------------------------------------ # Public helpers: `LeafTie` scalar data model # ------------------------------------------------------------------------------ @@ -79,6 +184,29 @@ proc `$`*(a: LeafTie): string = let w = $a.root.uint64.toHex & ":" & $a.path.Uint256.toHex w.strip(leading=true, trailing=false, chars={'0'}).toLowerAscii +# ------------------------------------------------------------------------------ +# Miscellaneous helpers +# ------------------------------------------------------------------------------ + +proc `$`*(hid: HashID): string = + if hid == high(HashID): + "2^256-1" + elif hid == 0.u256.HashID: + "0" + elif hid == 2.u256.pow(255).HashID: + "2^255" # 800... + elif hid == 2.u256.pow(254).HashID: + "2^254" # 400.. + elif hid == 2.u256.pow(253).HashID: + "2^253" # 200... + elif hid == 2.u256.pow(251).HashID: + "2^252" # 100... + else: + hid.UInt256.toHex + +proc `$`*(key: HashKey): string = + $key.to(HashID) + # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/nimbus/db/aristo/aristo_desc/aristo_types_private.nim b/nimbus/db/aristo/aristo_desc/aristo_types_private.nim new file mode 100644 index 000000000..0d7ca8bf3 --- /dev/null +++ b/nimbus/db/aristo/aristo_desc/aristo_types_private.nim @@ -0,0 +1,15 @@ +# nimbus-eth1 +# Copyright (c) 2021 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or +# http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or +# http://opensource.org/licenses/MIT) +# at your option. This file may not be copied, modified, or distributed +# except according to those terms. + +type + ByteArray32* = array[32,byte] + ## Used for 32 byte hash components repurposed as Merkle hash labels. + +# End diff --git a/nimbus/db/aristo/aristo_desc/aristo_types_structural.nim b/nimbus/db/aristo/aristo_desc/aristo_types_structural.nim index b63ed8621..1bee68f16 100644 --- a/nimbus/db/aristo/aristo_desc/aristo_types_structural.nim +++ b/nimbus/db/aristo/aristo_desc/aristo_types_structural.nim @@ -16,7 +16,6 @@ import eth/[common, trie/nibbles], - ../../../sync/snap/range_desc, "."/[aristo_error, aristo_types_identifiers] type @@ -55,7 +54,7 @@ type ## Combined record for a *traditional* ``Merkle Patricia Tree` node merged ## with a structural `VertexRef` type object. error*: AristoError ## Can be used for error signalling - key*: array[16,NodeKey] ## Merkle hash/es for Branch & Extension + key*: array[16,HashKey] ## Merkle hash/es for Branch & Extension # ------------------------------------------------------------------------------ # Public helpers: `NodeRef` and `PayloadRef` diff --git a/nimbus/db/aristo/aristo_get.nim b/nimbus/db/aristo/aristo_get.nim index 186168bb4..c8195cf8f 100644 --- a/nimbus/db/aristo/aristo_get.nim +++ b/nimbus/db/aristo/aristo_get.nim @@ -41,7 +41,7 @@ proc getVtxBackend*( proc getKeyBackend*( db: AristoDb; vid: VertexID; - ): Result[NodeKey,AristoError] = + ): Result[HashKey,AristoError] = ## Get the merkle hash/key from the backend # key must not have been locally deleted (but not saved, yet) if vid notin db.top.dKey: @@ -66,7 +66,7 @@ proc getVtxCascaded*( proc getKeyCascaded*( db: AristoDb; vid: VertexID; - ): Result[NodeKey,AristoError] = + ): Result[HashKey,AristoError] = ## Get the Merkle hash/key from the top layer or the `backened` layer if ## available. let lbl = db.top.kMap.getOrVoid vid @@ -103,10 +103,10 @@ proc getVtx*(db: AristoDb; lty: LeafTie): VertexRef = if rc.isOk: return rc.value.vtx -proc getKey*(db: AristoDb; vid: VertexID): NodeKey = - ## Variant of `getKeyCascaded()` returning `VOID_NODE_KEY` on error (while +proc getKey*(db: AristoDb; vid: VertexID): HashKey = + ## Variant of `getKeyCascaded()` returning `VOID_HASH_KEY` on error (while ## ignoring the detailed error type information.) - db.getKeyCascaded(vid).get(otherwise = VOID_NODE_KEY) + db.getKeyCascaded(vid).get(otherwise = VOID_HASH_KEY) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/aristo/aristo_hashify.nim b/nimbus/db/aristo/aristo_hashify.nim index 686b9e1e5..2a8c7a27b 100644 --- a/nimbus/db/aristo/aristo_hashify.nim +++ b/nimbus/db/aristo/aristo_hashify.nim @@ -35,8 +35,8 @@ ## vertex as long as possible. ## + Stash the rest of the partial chain to be completed later ## -## * While there is a partial chain left, use the ends towards the leaf nodes -## and calculate the remaining keys (which results in a width-first +## * While there is a partial chain left, use the ends towards the leaf +## vertices and calculate the remaining keys (which results in a width-first ## traversal, again.) {.push raises: [].} @@ -70,7 +70,7 @@ proc toNode(vtx: VertexRef; db: AristoDb): Result[NodeRef,void] = continue return err() else: - node.key[n] = VOID_NODE_KEY + node.key[n] = VOID_HASH_KEY return ok node of Extension: if vtx.eVid.isValid: @@ -98,7 +98,7 @@ proc leafToRootHasher( # Check against existing key, or store new key let - key = rc.value.encode.digestTo(NodeKey) + key = rc.value.encode.digestTo(HashKey) vfy = db.getKey wp.vid if not vfy.isValid: db.vidAttach(HashLabel(root: hike.root, key: key), wp.vid) @@ -188,22 +188,22 @@ proc hashify*( # Also `db.getVtx(fromVid)` => not nil as it was fetched earlier, already let rc = db.getVtx(fromVid).toNode(db) if rc.isErr: - # Cannot complete with this node, so do it later + # Cannot complete with this vertex, so do it later redo[fromVid] = rootAndVid else: # Register Hashes let - nodeKey = rc.value.encode.digestTo(NodeKey) + hashKey = rc.value.encode.digestTo(HashKey) toVid = rootAndVid[1] - # Update Merkle hash (aka `nodeKey`) + # Update Merkle hash (aka `HashKey`) let fromLbl = db.top.kMap.getOrVoid fromVid if fromLbl.isValid: - db.vidAttach(HashLabel(root: rootAndVid[0], key: nodeKey), fromVid) - elif nodeKey != fromLbl.key: + db.vidAttach(HashLabel(root: rootAndVid[0], key: hashKey), fromVid) + elif hashKey != fromLbl.key: let error = HashifyExistingHashMismatch - debug "hashify failed", vid=fromVid, key=nodeKey, + debug "hashify failed", vid=fromVid, key=hashKey, expected=fromLbl.key.pp, error return err((fromVid,error)) @@ -245,7 +245,7 @@ proc hashifyCheck*( let lbl = db.top.kMap.getOrVoid vid if not lbl.isValid: return err((vid,HashifyCheckVtxHashMissing)) - if lbl.key != rc.value.encode.digestTo(NodeKey): + if lbl.key != rc.value.encode.digestTo(HashKey): return err((vid,HashifyCheckVtxHashMismatch)) let revVid = db.top.pAmk.getOrVoid lbl @@ -267,7 +267,7 @@ proc hashifyCheck*( let lbl = db.top.kMap.getOrVoid vid if not lbl.isValid: return err((vid,HashifyCheckVtxHashMissing)) - if lbl.key != rc.value.encode.digestTo(NodeKey): + if lbl.key != rc.value.encode.digestTo(HashKey): return err((vid,HashifyCheckVtxHashMismatch)) let revVid = db.top.pAmk.getOrVoid lbl @@ -282,7 +282,7 @@ proc hashifyCheck*( if vtx.isValid: let rc = vtx.toNode(db) if rc.isOk: - if lbl.key != rc.value.encode.digestTo(NodeKey): + if lbl.key != rc.value.encode.digestTo(HashKey): return err((vid,HashifyCheckVtxHashMismatch)) let revVid = db.top.pAmk.getOrVoid lbl diff --git a/nimbus/db/aristo/aristo_hike.nim b/nimbus/db/aristo/aristo_hike.nim index eef020764..6e12bb25f 100644 --- a/nimbus/db/aristo/aristo_hike.nim +++ b/nimbus/db/aristo/aristo_hike.nim @@ -12,7 +12,7 @@ import eth/[common, trie/nibbles], - "."/[aristo_desc, aristo_get, aristo_path] + "."/[aristo_desc, aristo_get] type Leg* = object @@ -126,7 +126,7 @@ proc hikeUp*( proc hikeUp*(lty: LeafTie; db: AristoDb): Hike = ## Variant of `hike()` - lty.path.pathAsNibbles.hikeUp(lty.root, db) + lty.path.to(NibblesSeq).hikeUp(lty.root, db) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/db/aristo/aristo_init.nim b/nimbus/db/aristo/aristo_init.nim index 80ca44193..d854dcb38 100644 --- a/nimbus/db/aristo/aristo_init.nim +++ b/nimbus/db/aristo/aristo_init.nim @@ -8,21 +8,32 @@ # at your option. This file may not be copied, modified, or distributed # except according to those terms. -## Backend or cascaded constructors for Aristo DB -## ============================================== +## Constructors for Aristo DB +## ========================== ## -## For a backend-less constructor use `AristoDbRef.new()` +## For a backend-less constructor use `AristoDb(top: AristoLayerRef())`. {.push raises: [].} import ./aristo_init/[aristo_memory], - ./aristo_desc + ./aristo_desc, + ./aristo_desc/aristo_types_private # ------------------------------------------------------------------------------ # Public functions # ------------------------------------------------------------------------------ +proc init*(key: var HashKey; data: openArray[byte]): bool = + ## Import argument `data` into `key` which must have length either `32`, or + ## `0`. The latter case is equivalent to an all zero byte array of size `32`. + if data.len == 32: + (addr key.ByteArray32[0]).copyMem(unsafeAddr data[0], data.len) + return true + if data.len == 0: + key = VOID_HASH_KEY + return true + proc init*(T: type AristoDb): T = ## Constructor with memory backend. T(top: AristoLayerRef(), diff --git a/nimbus/db/aristo/aristo_init/aristo_memory.nim b/nimbus/db/aristo/aristo_init/aristo_memory.nim index 4fffe09b9..c30b19050 100644 --- a/nimbus/db/aristo/aristo_init/aristo_memory.nim +++ b/nimbus/db/aristo/aristo_init/aristo_memory.nim @@ -22,7 +22,7 @@ import type MemBackendRef = ref object sTab: Table[VertexID,VertexRef] ## Structural vertex table making up a trie - kMap: Table[VertexID,NodeKey] ## Merkle hash key mapping + kMap: Table[VertexID,HashKey] ## Merkle hash key mapping vGen: seq[VertexID] txGen: uint ## Transaction ID generator (for debugging) txId: uint ## Active transaction ID (for debugging) @@ -47,9 +47,9 @@ proc getVtxFn(db: MemBackendRef): GetVtxFn = proc getKeyFn(db: MemBackendRef): GetKeyFn = result = - proc(vid: VertexID): Result[NodeKey,AristoError] = - let key = db.kMap.getOrDefault(vid, EMPTY_ROOT_KEY) - if key != EMPTY_ROOT_KEY: + proc(vid: VertexID): Result[HashKey,AristoError] = + let key = db.kMap.getOrDefault(vid, VOID_HASH_KEY) + if key != VOID_HASH_KEY: return ok key err(MemBeKeyNotFound) @@ -79,7 +79,7 @@ proc putVtxFn(db: MemBackendRef): PutVtxFn = proc putKeyFn(db: MemBackendRef): PutKeyFn = result = - proc(hdl: PutHdlRef; vkps: openArray[(VertexID,NodeKey)]) = + proc(hdl: PutHdlRef; vkps: openArray[(VertexID,HashKey)]) = when VerifyIxId: doAssert db.txId == hdl.MemPutHdlRef.txId for (vid,key) in vkps: diff --git a/nimbus/db/aristo/aristo_merge.nim b/nimbus/db/aristo/aristo_merge.nim index c3e022ed4..a4c081eb6 100644 --- a/nimbus/db/aristo/aristo_merge.nim +++ b/nimbus/db/aristo/aristo_merge.nim @@ -11,7 +11,7 @@ ## Aristo DB -- Patricia Trie builder, raw node insertion ## ====================================================== ## -## This module merges `NodeTag` values as hexary lookup paths into the +## This module merges `HashID` values as hexary lookup paths into the ## `Patricia Trie`. When changing vertices (aka nodes without Merkle hashes), ## associated (but separated) Merkle hashes will be deleted unless locked. ## Instead of deleting locked hashes error handling is applied. @@ -133,7 +133,7 @@ proc insertBranch( # Install `forkVtx` block: - # Clear Merkle hashes (aka node keys) unless proof mode. + # Clear Merkle hashes (aka hash keys) unless proof mode. if db.top.pPrf.len == 0: db.clearMerkleKeys(hike, linkID) elif linkID in db.top.pPrf: @@ -228,17 +228,17 @@ proc concatBranchAndLeaf( if brVtx.bVid[nibble].isValid: return Hike(error: MergeRootBranchLinkBusy) - # Clear Merkle hashes (aka node keys) unless proof mode. + # Clear Merkle hashes (aka hash keys) unless proof mode. if db.top.pPrf.len == 0: db.clearMerkleKeys(hike, brVid) elif brVid in db.top.pPrf: return Hike(error: MergeBranchProofModeLock) # Ooops - # Append branch node + # Append branch vertex result = Hike(root: hike.root, legs: hike.legs) result.legs.add Leg(wp: VidVtxPair(vtx: brVtx, vid: brVid), nibble: nibble) - # Append leaf node + # Append leaf vertex let vid = db.vidFetch vtx = VertexRef( @@ -324,7 +324,7 @@ proc topIsExtAddLeaf( result = Hike(root: hike.root, legs: hike.legs) if not brVtx.isValid: - # Blind vertex, promote to leaf node. + # Blind vertex, promote to leaf vertex. # # --(extVid)--> --(brVid)--> nil # @@ -354,7 +354,7 @@ proc topIsExtAddLeaf( if linkID.isValid: return Hike(error: MergeRootBranchLinkBusy) - # Clear Merkle hashes (aka node keys) unless proof mode + # Clear Merkle hashes (aka hash keys) unless proof mode if db.top.pPrf.len == 0: db.clearMerkleKeys(hike, brVid) elif brVid in db.top.pPrf: @@ -386,7 +386,7 @@ proc topIsEmptyAddLeaf( if rootVtx.bVid[nibble].isValid: return Hike(error: MergeRootBranchLinkBusy) - # Clear Merkle hashes (aka node keys) unless proof mode + # Clear Merkle hashes (aka hash keys) unless proof mode if db.top.pPrf.len == 0: db.clearMerkleKeys(hike, hike.root) elif hike.root in db.top.pPrf: @@ -413,14 +413,14 @@ proc topIsEmptyAddLeaf( proc mergeNodeImpl( db: AristoDb; # Database, top layer - nodeKey: NodeKey; # Merkel hash of node + hashKey: HashKey; # Merkel hash of node node: NodeRef; # Node derived from RLP representation rootVid: VertexID; # Current sub-trie ): Result[VertexID,AristoError] = - ## The function merges a node key `nodeKey` expanded from its RLP - ## representation into the `Aristo Trie` database. The vertex is split off - ## from the node and stored separately. So are the Merkle hashes. The - ## vertex is labelled `locked`. + ## The function merges the argument hash key `hashKey` as expanded from the + ## node RLP representation into the `Aristo Trie` database. The vertex is + ## split off from the node and stored separately. So are the Merkle hashes. + ## The vertex is labelled `locked`. ## ## The `node` argument is *not* checked, whether the vertex IDs have been ## allocated, already. If the node comes straight from the `decode()` RLP @@ -431,26 +431,26 @@ proc mergeNodeImpl( if not rootVid.isValid: return err(MergeRootKeyEmpty) - # Verify `nodeKey` - if not nodeKey.isValid: - return err(MergeNodeKeyEmpty) + # Verify `hashKey` + if not hashKey.isValid: + return err(MergeHashKeyEmpty) # Check whether the node exists, already. If not then create a new vertex ID var - nodeLbl = HashLabel(root: rootVid, key: nodeKey) - vid = db.top.pAmk.getOrVoid nodeLbl + hashLbl = HashLabel(root: rootVid, key: hashKey) + vid = db.top.pAmk.getOrVoid hashLbl if not vid.isValid: - vid = db.vidAttach nodeLbl + vid = db.vidAttach hashLbl else: let lbl = db.top.kMap.getOrVoid vid - if lbl == nodeLbl: + if lbl == hashLbl: if db.top.sTab.hasKey vid: # This is tyically considered OK - return err(MergeNodeKeyCachedAlready) + return err(MergeHashKeyCachedAlready) # Otherwise proceed elif lbl.isValid: # Different key assigned => error - return err(MergeNodeKeyDiffersFromCached) + return err(MergeHashKeyDiffersFromCached) let vtx = node.to(VertexRef) # the vertex IDs need to be set up now (if any) @@ -523,7 +523,7 @@ proc merge*( vid: hike.root, vtx: VertexRef( vType: Leaf, - lPfx: leaf.leafTie.path.pathAsNibbles, + lPfx: leaf.leafTie.path.to(NibblesSeq), lData: leaf.payload)) db.top.sTab[wp.vid] = wp.vtx result = Hike(root: wp.vid, legs: @[Leg(wp: wp, nibble: -1)]) @@ -565,12 +565,12 @@ proc merge*( var (merged, dups) = (0, 0) for n,w in proof: let - key = w.Blob.digestTo(NodeKey) + key = w.Blob.digestTo(HashKey) node = w.Blob.decode(NodeRef) rc = db.mergeNodeImpl(key, node, rootVid) if rc.isOK: merged.inc - elif rc.error == MergeNodeKeyCachedAlready: + elif rc.error == MergeHashKeyCachedAlready: dups.inc else: return (n, dups, rc.error) @@ -579,7 +579,7 @@ proc merge*( proc merge*( db: AristoDb; # Database, top layer - rootKey: NodeKey; # Merkle hash for root + rootKey: HashKey; # Merkle hash for root rootVid = VertexID(0) # Optionally, force root vertex ID ): Result[VertexID,AristoError] = ## Set up a `rootKey` associated with a vertex ID. diff --git a/nimbus/db/aristo/aristo_nearby.nim b/nimbus/db/aristo/aristo_nearby.nim index d8dde0873..f279576b1 100644 --- a/nimbus/db/aristo/aristo_nearby.nim +++ b/nimbus/db/aristo/aristo_nearby.nim @@ -127,7 +127,7 @@ proc zeroAdjust( db: AristoDb; # Database layer doLeast: static[bool]; # Direction: *least* or *most* ): Hike = - ## Adjust empty argument path to the first node entry to the right. Ths + ## Adjust empty argument path to the first vertex entry to the right. Ths ## applies is the argument `hike` is before the first entry in the database. ## The result is a hike which is aligned with the first entry. proc accept(p: Hike; pfx: NibblesSeq): bool = @@ -171,7 +171,7 @@ proc zeroAdjust( of Extension: let ePfx = root.ePfx - # Must be followed by a branch node + # Must be followed by a branch vertex if hike.tail.len < 2 or not hike.accept(ePfx): break fail let vtx = db.getVtx root.eVid @@ -229,9 +229,9 @@ proc finalise( if 0 < hike.tail.len: # nothing to compare against, otherwise let top = hike.legs[^1] - # Note that only a `Branch` nodes has a non-zero nibble + # Note that only a `Branch` vertices has a non-zero nibble if 0 <= top.nibble and top.nibble == top.wp.vtx.branchBorderNibble: - # Check the following up node + # Check the following up vertex let vtx = db.getVtx top.wp.vtx.bVid[top.nibble] if not vtx.isValid: return Hike(error: NearbyDanglingLink) @@ -252,7 +252,7 @@ proc finalise( # * finalise left: n00000.. for 0 < n if hike.legs[0].wp.vtx.vType == Branch or (1 < hike.legs.len and hike.legs[1].wp.vtx.vType == Branch): - return Hike(error: NearbyFailed) # no more nodes + return Hike(error: NearbyFailed) # no more vertices Hike(error: NearbyUnexpectedVtx) # error @@ -314,7 +314,7 @@ proc nearbyNext( uHikeLen = uHike.legs.len # in case of backtracking uHikeTail = uHike.tail # in case of backtracking - # Look ahead checking next node + # Look ahead checking next vertex if start: let vid = top.wp.vtx.bVid[top.nibble] if not vid.isValid: @@ -334,7 +334,7 @@ proc nearbyNext( of Branch: let nibble = uHike.tail[0].int8 if start and accept nibble: - # Step down and complete with a branch link on the child node + # Step down and complete with a branch link on the child vertex step = Leg(wp: VidVtxPair(vid: vid, vtx: vtx), nibble: nibble) uHike.legs.add step @@ -354,7 +354,7 @@ proc nearbyNext( uHike.legs.setLen(uHikeLen) uHike.tail = uHikeTail else: - # Pop current `Branch` node on top and append nibble to `tail` + # Pop current `Branch` vertex on top and append nibble to `tail` uHike.tail = @[top.nibble.byte].initNibbleRange.slice(1) & uHike.tail uHike.legs.setLen(uHike.legs.len - 1) # End while @@ -368,7 +368,7 @@ proc nearbyNext( db: AristoDb; # Database layer hikeLenMax: static[int]; # Beware of loops (if any) moveRight:static[bool]; # Direction of next vertex - ): Result[NodeTag,AristoError] = + ): Result[HashID,AristoError] = ## Variant of `nearbyNext()`, convenience wrapper let hike = lty.hikeUp(db).nearbyNext(db, hikeLenMax, moveRight) if hike.error != AristoError(0): @@ -377,7 +377,7 @@ proc nearbyNext( if 0 < hike.legs.len and hike.legs[^1].wp.vtx.vType == Leaf: let rc = hike.legsTo(NibblesSeq).pathToKey if rc.isOk: - return ok rc.value.to(NodeTag) + return ok rc.value.to(HashID) return err(rc.error) err(NearbyLeafExpected) @@ -390,22 +390,22 @@ proc nearbyRight*( hike: Hike; # Partially expanded chain of vertices db: AristoDb; # Database layer ): Hike = - ## Extends the maximally extended argument nodes `hike` to the right (i.e. + ## Extends the maximally extended argument vertices `hike` to the right (i.e. ## with non-decreasing path value). This function does not backtrack if ## there are dangling links in between. It will return an error in that case. ## - ## If there is no more leaf node to the right of the argument `hike`, the + ## If there is no more leaf vertices to the right of the argument `hike`, the ## particular error code `NearbyBeyondRange` is returned. ## ## This code is intended to be used for verifying a left-bound proof to - ## verify that there is no leaf node *right* of a boundary path value. + ## verify that there is no leaf vertex *right* of a boundary path value. hike.nearbyNext(db, 64, moveRight=true) proc nearbyRight*( lty: LeafTie; # Some `Patricia Trie` path db: AristoDb; # Database layer ): Result[LeafTie,AristoError] = - ## Variant of `nearbyRight()` working with a `NodeTag` argument instead + ## Variant of `nearbyRight()` working with a `HashID` argument instead ## of a `Hike`. let rc = lty.nearbyNext(db, 64, moveRight=true) if rc.isErr: @@ -419,15 +419,14 @@ proc nearbyLeft*( ## Similar to `nearbyRight()`. ## ## This code is intended to be used for verifying a right-bound proof to - ## verify that there is no leaf node *left* to a boundary path value. + ## verify that there is no leaf vertex *left* to a boundary path value. hike.nearbyNext(db, 64, moveRight=false) proc nearbyLeft*( lty: LeafTie; # Some `Patricia Trie` path db: AristoDb; # Database layer ): Result[LeafTie,AristoError] = - ## Similar to `nearbyRight()` for `NodeTag` argument instead - ## of a `Hike`. + ## Similar to `nearbyRight()` for `HashID` argument instead of a `Hike`. let rc = lty.nearbyNext(db, 64, moveRight=false) if rc.isErr: return err(rc.error) @@ -441,10 +440,10 @@ proc nearbyRightMissing*( hike: Hike; # Partially expanded chain of vertices db: AristoDb; # Database layer ): Result[bool,AristoError] = - ## Returns `true` if the maximally extended argument nodes `hike` is the - ## rightmost on the hexary trie database. It verifies that there is no more + ## Returns `true` if the maximally extended argument vertex `hike` is the + ## right most on the hexary trie database. It verifies that there is no more ## leaf entry to the right of the argument `hike`. This function is an - ## an alternative to + ## alternative to ## :: ## let rc = path.nearbyRight(db) ## if rc.isOk: @@ -454,7 +453,7 @@ proc nearbyRightMissing*( ## # problem with database => error ## ... ## else: - ## # no nore nodes => true + ## # no nore vertices => true ## ... ## and is intended mainly for debugging. if hike.legs.len == 0: diff --git a/nimbus/db/aristo/aristo_path.nim b/nimbus/db/aristo/aristo_path.nim index 053ff8d1e..77cc6d861 100644 --- a/nimbus/db/aristo/aristo_path.nim +++ b/nimbus/db/aristo/aristo_path.nim @@ -14,7 +14,8 @@ import std/sequtils, eth/[common, trie/nibbles], stew/results, - ./aristo_desc + ./aristo_desc, + ./aristo_desc/aristo_types_private # Info snippet (just a reminder to keep somewhere) # @@ -34,35 +35,28 @@ import # Public functions # ------------------------------------------------------------------------------ -proc pathAsNibbles*(key: NodeKey): NibblesSeq = - key.ByteArray32.initNibbleRange() - -proc pathAsNibbles*(tag: NodeTag): NibblesSeq = - tag.to(NodeKey).pathAsNibbles() - -proc pathAsBlob*(keyOrTag: NodeKey|NodeTag): Blob = +proc pathAsBlob*(keyOrTag: HashKey|HashID): Blob = keyOrTag.pathAsNibbles.hexPrefixEncode(isLeaf=true) - -proc pathToKey*(partPath: NibblesSeq): Result[NodeKey,AristoError] = +proc pathToKey*(partPath: NibblesSeq): Result[HashKey,AristoError] = var key: ByteArray32 if partPath.len == 64: # Trailing dummy nibbles (aka no nibbles) force a nibble seq reorg let path = (partPath & EmptyNibbleSeq).getBytes() (addr key[0]).copyMem(unsafeAddr path[0], 32) - return ok(key.NodeKey) + return ok(key.HashKey) err(PathExpected64Nibbles) -proc pathToKey*(partPath: Blob): Result[NodeKey,AristoError] = +proc pathToKey*(partPath: Blob): Result[HashKey,AristoError] = let (isLeaf,pathSegment) = partPath.hexPrefixDecode if isleaf: return pathSegment.pathToKey() err(PathExpectedLeaf) -proc pathToTag*(partPath: NibblesSeq|Blob): Result[NodeTag,AristoError] = +proc pathToTag*(partPath: NibblesSeq|Blob): Result[HashID,AristoError] = let rc = partPath.pathToKey() if rc.isOk: - return ok(rc.value.to(NodeTag)) + return ok(rc.value.to(HashID)) err(rc.error) # -------------------- @@ -86,11 +80,11 @@ proc pathPfxPad*(pfx: NibblesSeq; dblNibble: static[byte]): NibblesSeq = let nope = seq[byte].default.initNibbleRange result = pfx.slice(0,64) & nope # nope forces re-alignment -proc pathPfxPadKey*(pfx: NibblesSeq; dblNibble: static[byte]): NodeKey = +proc pathPfxPadKey*(pfx: NibblesSeq; dblNibble: static[byte]): HashKey = ## Variant of `pathPfxPad()`. ## ## Extend (or cut) the argument nibbles sequence `pfx` for generating a - ## `NodeKey`. + ## `HashKey`. let bytes = pfx.pathPfxPad(dblNibble).getBytes (addr result.ByteArray32[0]).copyMem(unsafeAddr bytes[0], bytes.len) diff --git a/nimbus/db/aristo/aristo_transcode.nim b/nimbus/db/aristo/aristo_transcode.nim index 5d4fc0aa2..cb7a08c04 100644 --- a/nimbus/db/aristo/aristo_transcode.nim +++ b/nimbus/db/aristo/aristo_transcode.nim @@ -14,7 +14,7 @@ import std/[bitops, sequtils], eth/[common, trie/nibbles], stew/results, - "."/[aristo_constants, aristo_desc] + "."/[aristo_constants, aristo_desc, aristo_init] # ------------------------------------------------------------------------------ # Private functions @@ -24,16 +24,6 @@ proc aristoError(error: AristoError): NodeRef = ## Allows returning de NodeRef(vType: Leaf, error: error) -proc aInit(key: var NodeKey; data: openArray[byte]): bool = - ## Import argument `data` into `key` which must have length either `32`, or - ## `0`. The latter case is equivalent to an all zero byte array of size `32`. - if data.len == 32: - (addr key.ByteArray32[0]).copyMem(unsafeAddr data[0], data.len) - return true - elif data.len == 0: - key = VOID_NODE_KEY - return true - # ------------------------------------------------------------------------------ # Public RLP transcoder mixins # ------------------------------------------------------------------------------ @@ -51,7 +41,7 @@ proc read*( var blobs = newSeq[Blob](2) # temporary, cache - links: array[16,NodeKey] # reconstruct branch node + links: array[16,HashKey] # reconstruct branch node top = 0 # count entries and positions # Collect lists of either 2 or 17 blob entries. @@ -62,7 +52,7 @@ proc read*( return aristoError(RlpBlobExpected) blobs[top] = rlp.read(Blob) of 2 .. 15: - if not links[top].aInit(rlp.read(Blob)): + if not links[top].init(rlp.read(Blob)): return aristoError(RlpBranchLinkExpected) of 16: if not w.isBlob: @@ -90,12 +80,12 @@ proc read*( var node = NodeRef( vType: Extension, ePfx: pathSegment) - if not node.key[0].aInit(blobs[1]): + if not node.key[0].init(blobs[1]): return aristoError(RlpExtPathEncoding) return node of 17: for n in [0,1]: - if not links[n].aInit(blobs[n]): + if not links[n].init(blobs[n]): return aristoError(RlpBranchLinkExpected) return NodeRef( vType: Branch, @@ -109,7 +99,7 @@ proc read*( proc append*(writer: var RlpWriter; node: NodeRef) = ## Mixin for RLP writer. Note that a `Dummy` node is encoded as an empty ## list. - proc addNodeKey(writer: var RlpWriter; key: NodeKey) = + proc addHashKey(writer: var RlpWriter; key: HashKey) = if not key.isValid: writer.append EmptyBlob else: @@ -122,12 +112,12 @@ proc append*(writer: var RlpWriter; node: NodeRef) = of Branch: writer.startList(17) for n in 0..15: - writer.addNodeKey node.key[n] + writer.addHashKey node.key[n] writer.append EmptyBlob of Extension: writer.startList(2) writer.append node.ePfx.hexPrefixEncode(isleaf = false) - writer.addNodeKey node.key[0] + writer.addHashKey node.key[0] of Leaf: writer.startList(2) writer.append node.lPfx.hexPrefixEncode(isleaf = true) @@ -143,12 +133,12 @@ proc blobify*(node: VertexRef; data: var Blob): AristoError = ## boundaries. ## :: ## Branch: - ## uint64, ... -- list of up to 16 child nodes lookup keys + ## uint64, ... -- list of up to 16 child vertices lookup keys ## uint16 -- index bitmap ## 0x00 -- marker(2) + unused(2) ## ## Extension: - ## uint64 -- child node lookup key + ## uint64 -- child vertex lookup key ## Blob -- hex encoded partial path (at least one byte) ## 0x80 -- marker(2) + unused(2) ## @@ -158,7 +148,7 @@ proc blobify*(node: VertexRef; data: var Blob): AristoError = ## 0xc0 -- marker(2) + partialPathLen(6) ## ## For a branch record, the bytes of the `access` array indicate the position - ## of the Patricia Trie node reference. So the `vertexID` with index `n` has + ## of the Patricia Trie vertex reference. So the `vertexID` with index `n` has ## :: ## 8 * n * ((access shr (n * 4)) and 15) ## @@ -229,7 +219,7 @@ proc deblobify*(record: Blob; vtx: var VertexRef): AristoError = return DbrTooShort case record[^1] shr 6: - of 0: # `Branch` node + of 0: # `Branch` vertex if record.len < 19: # at least two edges return DbrBranchTooShort if (record.len mod 8) != 3: @@ -254,7 +244,7 @@ proc deblobify*(record: Blob; vtx: var VertexRef): AristoError = vType: Branch, bVid: vtxList) - of 2: # `Extension` node + of 2: # `Extension` vertex let sLen = record[^1].int and 0x3f # length of path segment rlen = record.len - 1 # `vertexID` + path segm @@ -270,7 +260,7 @@ proc deblobify*(record: Blob; vtx: var VertexRef): AristoError = eVid: (uint64.fromBytesBE record[0 ..< 8]).VertexID, ePfx: pathSegment) - of 3: # `Leaf` node + of 3: # `Leaf` vertex let sLen = record[^1].int and 0x3f # length of path segment rlen = record.len - 1 # payload + path segment diff --git a/nimbus/db/aristo/aristo_vid.nim b/nimbus/db/aristo/aristo_vid.nim index 72c0e4969..62a144b18 100644 --- a/nimbus/db/aristo/aristo_vid.nim +++ b/nimbus/db/aristo/aristo_vid.nim @@ -101,7 +101,7 @@ proc vidAttach*(db: AristoDb; lbl: HashLabel): VertexID {.discardable.} = result = db.vidFetch db.vidAttach(lbl, result) -proc vidRoot*(db: AristoDb; key: NodeKey): VertexID {.discardable.} = +proc vidRoot*(db: AristoDb; key: HashKey): VertexID {.discardable.} = ## Variant of `vidAttach()` for generating a sub-trie root result = db.vidFetch db.vidAttach(HashLabel(root: result, key: key), result) diff --git a/tests/test_aristo/test_aristo_cache.nim b/tests/test_aristo/test_aristo_cache.nim index f68bd314d..744cb7c2c 100644 --- a/tests/test_aristo/test_aristo_cache.nim +++ b/tests/test_aristo/test_aristo_cache.nim @@ -100,12 +100,12 @@ proc cachedVID(db: AristoDb; lbl: HashLabel): VertexID = result = db.vidAttach lbl # ------------------------------------------------------------------------------ -# Public functions for `VertexID` => `NodeKey` mapping +# Public functions for `VertexID` => `HashKey` mapping # ------------------------------------------------------------------------------ -proc pal*(db: AristoDb; rootID: VertexID; vid: VertexID): NodeKey = - ## Retrieve the cached `Merkel` hash (aka `NodeKey` object) associated with - ## the argument `VertexID` type argument `vid`. Return a zero `NodeKey` if +proc pal*(db: AristoDb; rootID: VertexID; vid: VertexID): HashKey = + ## Retrieve the cached `Merkel` hash (aka `HashKey` object) associated with + ## the argument `VertexID` type argument `vid`. Return a zero `HashKey` if ## there is none. ## ## If the vertex ID `vid` is not found in the cache, then the structural @@ -122,7 +122,7 @@ proc pal*(db: AristoDb; rootID: VertexID; vid: VertexID): NodeKey = if db.convertPartiallyOk(vtx,node): var w = initRlpWriter() w.append node - result = w.finish.keccakHash.data.NodeKey + result = w.finish.keccakHash.data.HashKey db.top.kMap[vid] = HashLabel(root: rootID, key: result) # ------------------------------------------------------------------------------ @@ -135,7 +135,7 @@ proc updated*(nd: NodeRef; root: VertexID; db: AristoDb): NodeRef = ## For a `Leaf` node, the payload data `PayloadRef` type reference is *not* ## duplicated and returned as-is. ## - ## This function will not complain if all `Merkel` hashes (aka `NodeKey` + ## This function will not complain if all `Merkel` hashes (aka `HashKey` ## objects) are zero for either `Extension` or `Leaf` nodes. if nd.isValid: case nd.vType: @@ -161,7 +161,7 @@ proc updated*(nd: NodeRef; root: VertexID; db: AristoDb): NodeRef = proc asNode*(vtx: VertexRef; db: AristoDb): NodeRef = ## Return a `NodeRef` object by augmenting missing `Merkel` hashes (aka - ## `NodeKey` objects) from the cache or from calculated cached vertex + ## `HashKey` objects) from the cache or from calculated cached vertex ## entries, if available. ## ## If not all `Merkel` hashes are available in a single lookup, then the diff --git a/tests/test_aristo/test_delete.nim b/tests/test_aristo/test_delete.nim index cd258a471..6cd1c1ed8 100644 --- a/tests/test_aristo/test_delete.nim +++ b/tests/test_aristo/test_delete.nim @@ -18,7 +18,6 @@ import unittest2, ../../nimbus/db/aristo/[ aristo_desc, aristo_delete, aristo_hashify, aristo_nearby, aristo_merge], - ../../nimbus/sync/snap/range_desc, ./test_helpers type @@ -93,8 +92,8 @@ proc fwdWalkVerify( error = rc.error check rc.error == AristoError(0) break - if rc.value.path < high(NodeTag): - lty.path = NodeTag(rc.value.path.u256 + 1) + if rc.value.path < high(HashID): + lty.path = HashID(rc.value.path.u256 + 1) n.inc if error != AristoError(0): diff --git a/tests/test_aristo/test_helpers.nim b/tests/test_aristo/test_helpers.nim index 7568178a9..2c0a69c73 100644 --- a/tests/test_aristo/test_helpers.nim +++ b/tests/test_aristo/test_helpers.nim @@ -20,9 +20,12 @@ import ../test_sync_snap/test_types, ../replay/[pp, undump_accounts, undump_storages] +from ../../nimbus/sync/snap/range_desc + import NodeKey + type ProofTrieData* = object - root*: NodeKey + root*: HashKey id*: int proof*: seq[SnapProof] kvpLst*: seq[LeafTiePayload] @@ -34,6 +37,9 @@ type proc toPfx(indent: int): string = "\n" & " ".repeat(indent) +proc to(a: NodeKey; T: type HashKey): T = + a.T + # ------------------------------------------------------------------------------ # Public pretty printing # ------------------------------------------------------------------------------ @@ -118,9 +124,9 @@ proc to*(sample: AccountsSample; T: type seq[UndumpStorages]): T = result.add w proc to*(ua: seq[UndumpAccounts]; T: type seq[ProofTrieData]): T = - var (rootKey, rootVid) = (VOID_NODE_KEY, VertexID(0)) + var (rootKey, rootVid) = (VOID_HASH_KEY, VertexID(0)) for w in ua: - let thisRoot = w.root.to(NodeKey) + let thisRoot = w.root.to(HashKey) if rootKey != thisRoot: (rootKey, rootVid) = (thisRoot, VertexID(rootVid.uint64 + 1)) if 0 < w.data.accounts.len: @@ -128,14 +134,16 @@ proc to*(ua: seq[UndumpAccounts]; T: type seq[ProofTrieData]): T = root: rootKey, proof: w.data.proof, kvpLst: w.data.accounts.mapIt(LeafTiePayload( - leafTie: LeafTie(root: rootVid, path: it.accKey.to(NodeTag)), + leafTie: LeafTie( + root: rootVid, + path: it.accKey.to(HashKey).to(HashID)), payload: PayloadRef(pType: BlobData, blob: it.accBlob)))) proc to*(us: seq[UndumpStorages]; T: type seq[ProofTrieData]): T = - var (rootKey, rootVid) = (VOID_NODE_KEY, VertexID(0)) + var (rootKey, rootVid) = (VOID_HASH_KEY, VertexID(0)) for n,s in us: for w in s.data.storages: - let thisRoot = w.account.storageRoot.to(NodeKey) + let thisRoot = w.account.storageRoot.to(HashKey) if rootKey != thisRoot: (rootKey, rootVid) = (thisRoot, VertexID(rootVid.uint64 + 1)) if 0 < w.data.len: @@ -143,7 +151,9 @@ proc to*(us: seq[UndumpStorages]; T: type seq[ProofTrieData]): T = root: thisRoot, id: n + 1, kvpLst: w.data.mapIt(LeafTiePayload( - leafTie: LeafTie(root: rootVid, path: it.slotHash.to(NodeTag)), + leafTie: LeafTie( + root: rootVid, + path: it.slotHash.to(HashKey).to(HashID)), payload: PayloadRef(pType: BlobData, blob: it.slotData)))) if 0 < result.len: result[^1].proof = s.data.proof diff --git a/tests/test_aristo/test_merge.nim b/tests/test_aristo/test_merge.nim index b106ab521..76c701937 100644 --- a/tests/test_aristo/test_merge.nim +++ b/tests/test_aristo/test_merge.nim @@ -194,7 +194,7 @@ proc test_mergeProofAndKvpList*( oopsTab = oops.toTable var db: AristoDb - rootKey = NodeKey.default + rootKey = HashKey.default count = 0 for n,w in list: if resetDb or w.root != rootKey or w.proof.len == 0: @@ -222,7 +222,7 @@ proc test_mergeProofAndKvpList*( check rc.error == AristoError(0) return proved = db.merge(w.proof, rc.value) - check proved.error in {AristoError(0),MergeNodeKeyCachedAlready} + check proved.error in {AristoError(0),MergeHashKeyCachedAlready} check w.proof.len == proved.merged + proved.dups check db.top.lTab.len == lTabLen check db.top.sTab.len == proved.merged + sTabLen diff --git a/tests/test_aristo/test_nearby.nim b/tests/test_aristo/test_nearby.nim index 12e441f7b..39026ff1b 100644 --- a/tests/test_aristo/test_nearby.nim +++ b/tests/test_aristo/test_nearby.nim @@ -18,7 +18,6 @@ import unittest2, ../../nimbus/db/aristo/[ aristo_desc, aristo_debug, aristo_merge, aristo_nearby], - ../../nimbus/sync/snap/range_desc, ./test_helpers # ------------------------------------------------------------------------------ @@ -28,14 +27,14 @@ import proc fwdWalkLeafsCompleteDB( db: AristoDb; root: VertexID; - tags: openArray[NodeTag]; + tags: openArray[HashID]; noisy: bool; ): tuple[visited: int, error: AristoError] = let tLen = tags.len var error = AristoError(0) - lty = LeafTie(root: root, path: NodeTag(tags[0].u256 div 2)) + lty = LeafTie(root: root, path: HashID(tags[0].u256 div 2)) n = 0 while true: let rc = lty.nearbyRight(db) @@ -63,8 +62,8 @@ proc fwdWalkLeafsCompleteDB( error = AristoError(1) check rc.value.path == tags[n] break - if rc.value.path < high(NodeTag): - lty.path = NodeTag(rc.value.path.u256 + 1) + if rc.value.path < high(HashID): + lty.path = HashID(rc.value.path.u256 + 1) n.inc (n,error) @@ -73,7 +72,7 @@ proc fwdWalkLeafsCompleteDB( proc revWalkLeafsCompleteDB( db: AristoDb; root: VertexID; - tags: openArray[NodeTag]; + tags: openArray[HashID]; noisy: bool; ): tuple[visited: int, error: AristoError] = let @@ -81,7 +80,7 @@ proc revWalkLeafsCompleteDB( var error = AristoError(0) delta = ((high(UInt256) - tags[^1].u256) div 2) - lty = LeafTie(root: root, path: NodeTag(tags[^1].u256 + delta)) + lty = LeafTie(root: root, path: HashID(tags[^1].u256 + delta)) n = tLen-1 while true: # and false: let rc = lty.nearbyLeft(db) @@ -107,8 +106,8 @@ proc revWalkLeafsCompleteDB( error = AristoError(1) check rc.value.path == tags[n] break - if low(NodeTag) < rc.value.path: - lty.path = NodeTag(rc.value.path.u256 - 1) + if low(HashID) < rc.value.path: + lty.path = HashID(rc.value.path.u256 - 1) n.dec (tLen-1 - n, error) @@ -124,8 +123,8 @@ proc test_nearbyKvpList*( ): bool = var db: AristoDb - rootKey = NodeKey.default - tagSet: HashSet[NodeTag] + rootKey = HashKey.default + tagSet: HashSet[HashID] count = 0 for n,w in list: if resetDb or w.root != rootKey: