Skip to content

Commit

Permalink
Aristo db fixes after storage slots dump tests added (status-im#1595)
Browse files Browse the repository at this point in the history
* Fix missing Merkle key removal in `merge()`

* Accept optional root hash argument in `hashify()`

why:
  For importing a full database, there will be no proof data except the
  root key. So this can be used to check and set the root key in the
  database descriptor.

also:
  Associate vertex ID to `hashify()` error return code

* Added Aristo Trie traversal function

why:
 * step along leaf vertices in sorted order
 * tree/trie consistency checks when debugging

* Enabled storage slots test data for Aristo DB
  • Loading branch information
mjfh authored Jun 2, 2023
1 parent cbd593f commit 099444a
Show file tree
Hide file tree
Showing 9 changed files with 964 additions and 113 deletions.
15 changes: 15 additions & 0 deletions nimbus/db/aristo/aristo_error.nim
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type
HashifyExistingHashMismatch
HashifyLeafToRootAllFailed
HashifyRootHashMismatch
HashifyRootVidMismatch

HashifyCheckRevCountMismatch
HashifyCheckRevHashMismatch
Expand All @@ -103,4 +104,18 @@ type
HashifyCheckVtxIncomplete
HashifyCheckVtxLockWithoutKey

# Neighbour vertex, tree traversal `nearbyRight()` and `nearbyLeft()`
NearbyBeyondRange
NearbyBranchError
NearbyDanglingLink
NearbyEmptyHike
NearbyExtensionError
NearbyFailed
NearbyBranchExpected
NearbyLeafExpected
NearbyNestingTooDeep
NearbyPathTailUnexpected
NearbyPathTailInxOverflow
NearbyUnexpectedVtx

# End
37 changes: 23 additions & 14 deletions nimbus/db/aristo/aristo_hashify.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ proc toNode(vtx: VertexRef; db: AristoDbRef): Result[NodeRef,void] =
proc leafToRootHasher(
db: AristoDbRef; # Database, top layer
hike: Hike; # Hike for labelling leaf..root
): Result[int,AristoError] =
): Result[int,(VertexID,AristoError)] =
## Returns the index of the first node that could not be hashed
for n in (hike.legs.len-1).countDown(0):
let
Expand All @@ -120,7 +120,7 @@ proc leafToRootHasher(
elif key != vfyKey:
let error = HashifyExistingHashMismatch
debug "hashify failed", vid=wp.vid, key, expected=vfyKey, error
return err(error)
return err((wp.vid,error))

ok -1 # all could be hashed

Expand All @@ -141,13 +141,13 @@ proc hashifyClear*(

proc hashify*(
db: AristoDbRef; # Database, top layer
): Result[NodeKey,AristoError] =
rootKey = EMPTY_ROOT_KEY; # Optional root key
): Result[NodeKey,(VertexID,AristoError)] =
## Add keys to the `Patricia Trie` so that it becomes a `Merkle Patricia
## Tree`. If successful, the function returns the key (aka Merkle hash) of
## the root vertex.
var
fullPath = false
rootKey: NodeKey
thisRootKey = EMPTY_ROOT_KEY

# Width-first leaf-to-root traversal structure
backLink: Table[VertexID,VertexID]
Expand All @@ -156,7 +156,7 @@ proc hashify*(
for (pathTag,vid) in db.lTab.pairs:
let hike = pathTag.hikeUp(db.lRoot,db)
if hike.error != AristoError(0):
return err(hike.error)
return err((VertexID(0),hike.error))

# Hash as much of the `hike` as possible
let n = block:
Expand All @@ -178,13 +178,22 @@ proc hashify*(
for u in (n-1).countDown(1):
backLink[hike.legs[u].wp.vid] = hike.legs[u-1].wp.vid

elif not fullPath:
rootKey = db.kMap.getOrDefault(hike.legs[0].wp.vid, EMPTY_ROOT_KEY)
fullPath = (rootKey != EMPTY_ROOT_KEY)
elif thisRootKey == EMPTY_ROOT_KEY:
let rootVid = hike.legs[0].wp.vid
thisRootKey = db.kMap.getOrDefault(rootVid, EMPTY_ROOT_KEY)

if thisRootKey != EMPTY_ROOT_KEY:
if rootKey != EMPTY_ROOT_KEY and rootKey != thisRootKey:
return err((rootVid, HashifyRootHashMismatch))

if db.lRoot == VertexID(0):
db.lRoot = rootVid
elif db.lRoot != rootVid:
return err((rootVid,HashifyRootVidMismatch))

# At least one full path leaf..root should have succeeded with labelling
if not fullPath:
return err(HashifyLeafToRootAllFailed)
if thisRootKey == EMPTY_ROOT_KEY:
return err((VertexID(0),HashifyLeafToRootAllFailed))

# Update remaining hashes
var n = 0 # for logging
Expand Down Expand Up @@ -216,7 +225,7 @@ proc hashify*(
let error = HashifyExistingHashMismatch
debug "hashify failed", vid=fromVid, key=nodeKey,
expected=fromKey.pp, error
return err(error)
return err((fromVid,error))

done.incl fromVid

Expand All @@ -228,14 +237,14 @@ proc hashify*(
# Make sure that the algorithm proceeds
if done.len == 0:
let error = HashifyCannotComplete
return err(error)
return err((VertexID(0),error))

# Clean up dups from `backLink` and restart `downMost`
for vid in done.items:
backLink.del vid
downMost = redo

ok rootKey
ok thisRootKey

# ------------------------------------------------------------------------------
# Public debugging functions
Expand Down
7 changes: 7 additions & 0 deletions nimbus/db/aristo/aristo_merge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,13 @@ proc topIsEmptyAddLeaf(
let nibble = hike.tail[0].int8
if not rootVtx.bVid[nibble].isZero:
return Hike(error: MergeRootBranchLinkBusy)

# Clear Merkle hashes (aka node keys) unless proof mode
if db.pPrf.len == 0:
db.clearMerkleKeys(hike, hike.root)
elif hike.root in db.pPrf:
return Hike(error: MergeBranchProofModeLock)

let
leafVid = db.vidFetch
leafVtx = VertexRef(
Expand Down
Loading

0 comments on commit 099444a

Please sign in to comment.