Skip to content

Commit

Permalink
Fringe case portal proof for existing account without storage tree (#…
Browse files Browse the repository at this point in the history
…2613)

detail:
  For practical reasons, ifsuch an account is asked for a slot, an empty
  proof list is returned. It is up to the user to provide an account
  proof that shows that there is no storage tree.
  • Loading branch information
mjfh authored Sep 11, 2024
1 parent 75808bc commit c667431
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 19 deletions.
1 change: 1 addition & 0 deletions nimbus/db/aristo/aristo_desc/desc_error.nim
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type
FetchLeafKeyInvalid
FetchPathInvalid
FetchPathNotFound
FetchPathStoRootMissing
FetchRootVidMissing
FetchStoRootNotAccepted

Expand Down
43 changes: 27 additions & 16 deletions nimbus/db/aristo/aristo_fetch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,23 @@ proc hasAccountPayload(
return ok(false)
err(error)

proc fetchStorageIdImpl(
db: AristoDbRef;
accPath: Hash256;
enaStoRootMissing = false;
): Result[VertexID,AristoError] =
## Helper function for retrieving a storage (vertex) ID for a given account.
let
payload = ?db.retrieveAccountPayload(accPath)
stoID = payload.stoID

if stoID.isValid:
ok stoID.vid
elif enaStoRootMissing:
err(FetchPathStoRootMissing)
else:
err(FetchPathNotFound)

# ------------------------------------------------------------------------------
# Public helpers
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -154,16 +171,11 @@ proc fetchStorageID*(
db: AristoDbRef;
accPath: Hash256;
): Result[VertexID,AristoError] =
## Public helper function for retrieving a storage (vertex) ID for a
## given account.
let
payload = ?db.retrieveAccountPayload(accPath)
stoID = payload.stoID

if not stoID.isValid:
return err(FetchPathNotFound)

ok stoID.vid
## Public helper function for retrieving a storage (vertex) ID for a given account. This
## function returns a separate error `FetchPathStoRootMissing` (from `FetchPathNotFound`)
## if the account for the argument path `accPath` exists but has no storage root.
##
db.fetchStorageIdImpl(accPath, enaStoRootMissing=true)

proc retrieveStoragePayload(
db: AristoDbRef;
Expand All @@ -184,9 +196,8 @@ proc retrieveStoragePayload(

# Updated payloads are stored in the layers so if we didn't find them there,
# it must have been in the database
let
leafVtx = db.retrieveLeaf(? db.fetchStorageID(accPath), stoPath.data).valueOr:
return err(error)
let leafVtx = db.retrieveLeaf(? db.fetchStorageIdImpl(accPath), stoPath.data).valueOr:
return err(error)

ok db.stoLeaves.lruAppend(mixKey, leafVtx, ACC_LRU_SIZE).lData.stoData

Expand Down Expand Up @@ -281,7 +292,7 @@ proc fetchStorageData*(
## For a storage tree related to account `accPath`, fetch the data record
## from the database indexed by `path`.
##
let leafVtx = ? db.retrieveLeaf(? db.fetchStorageID accPath, stoPath.data)
let leafVtx = ? db.retrieveLeaf(? db.fetchStorageIdImpl accPath, stoPath.data)
assert leafVtx.lData.pType == StoData # debugging only
ok leafVtx.lData.stoData

Expand All @@ -291,7 +302,7 @@ proc fetchStorageState*(
updateOk: bool;
): Result[Hash256,AristoError] =
## Fetch the Merkle hash of the storage root related to `accPath`.
let stoID = db.fetchStorageID(accPath).valueOr:
let stoID = db.fetchStorageIdImpl(accPath).valueOr:
if error == FetchPathNotFound:
return ok(EMPTY_ROOT_HASH) # no sub-tree
return err(error)
Expand All @@ -314,7 +325,7 @@ proc hasStorageData*(
## For a storage tree related to account `accPath`, query whether there
## is a non-empty data storage area at all.
##
let stoID = db.fetchStorageID(accPath).valueOr:
let stoID = db.fetchStorageIdImpl(accPath).valueOr:
if error == FetchPathNotFound:
return ok(false) # no sub-tree
return err(error)
Expand Down
9 changes: 6 additions & 3 deletions nimbus/db/aristo/aristo_part.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,12 @@ proc partStorageTwig*(
accPath: Hash256;
stoPath: Hash256;
): Result[(seq[Blob],bool), AristoError] =
## Variant of `partGenericTwig()`. Note that the function always returns an
## error unless the `accPath` is valid.
let vid = ? db.fetchStorageID accPath
## Variant of `partGenericTwig()`. Note that the function returns an error unless
## the argument `accPath` is valid.
let vid = db.fetchStorageID(accPath).valueOr:
if error == FetchPathStoRootMissing:
return ok((@[],false))
return err(error)
db.partGenericTwig(vid, NibblesBuf.fromBytes stoPath.data)

# ----------
Expand Down

0 comments on commit c667431

Please sign in to comment.