Fringe case portal proof for existing account without storage tree (#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.
This commit is contained in:
Jordan Hrycaj 2024-09-11 20:27:42 +00:00 committed by GitHub
parent 75808bc03b
commit c6674311eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 19 deletions

View File

@ -98,6 +98,7 @@ type
FetchLeafKeyInvalid FetchLeafKeyInvalid
FetchPathInvalid FetchPathInvalid
FetchPathNotFound FetchPathNotFound
FetchPathStoRootMissing
FetchRootVidMissing FetchRootVidMissing
FetchStoRootNotAccepted FetchStoRootNotAccepted

View File

@ -123,6 +123,23 @@ proc hasAccountPayload(
return ok(false) return ok(false)
err(error) 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 # Public helpers
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -154,16 +171,11 @@ proc fetchStorageID*(
db: AristoDbRef; db: AristoDbRef;
accPath: Hash256; accPath: Hash256;
): Result[VertexID,AristoError] = ): Result[VertexID,AristoError] =
## Public helper function for retrieving a storage (vertex) ID for a ## Public helper function for retrieving a storage (vertex) ID for a given account. This
## given account. ## function returns a separate error `FetchPathStoRootMissing` (from `FetchPathNotFound`)
let ## if the account for the argument path `accPath` exists but has no storage root.
payload = ?db.retrieveAccountPayload(accPath) ##
stoID = payload.stoID db.fetchStorageIdImpl(accPath, enaStoRootMissing=true)
if not stoID.isValid:
return err(FetchPathNotFound)
ok stoID.vid
proc retrieveStoragePayload( proc retrieveStoragePayload(
db: AristoDbRef; db: AristoDbRef;
@ -184,8 +196,7 @@ proc retrieveStoragePayload(
# 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(? db.fetchStorageIdImpl(accPath), stoPath.data).valueOr:
leafVtx = db.retrieveLeaf(? db.fetchStorageID(accPath), stoPath.data).valueOr:
return err(error) return err(error)
ok db.stoLeaves.lruAppend(mixKey, leafVtx, ACC_LRU_SIZE).lData.stoData ok db.stoLeaves.lruAppend(mixKey, leafVtx, ACC_LRU_SIZE).lData.stoData
@ -281,7 +292,7 @@ proc fetchStorageData*(
## For a storage tree related to account `accPath`, fetch the data record ## For a storage tree related to account `accPath`, fetch the data record
## from the database indexed by `path`. ## 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 assert leafVtx.lData.pType == StoData # debugging only
ok leafVtx.lData.stoData ok leafVtx.lData.stoData
@ -291,7 +302,7 @@ proc fetchStorageState*(
updateOk: bool; updateOk: bool;
): Result[Hash256,AristoError] = ): Result[Hash256,AristoError] =
## Fetch the Merkle hash of the storage root related to `accPath`. ## 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: if error == FetchPathNotFound:
return ok(EMPTY_ROOT_HASH) # no sub-tree return ok(EMPTY_ROOT_HASH) # no sub-tree
return err(error) return err(error)
@ -314,7 +325,7 @@ proc hasStorageData*(
## For a storage tree related to account `accPath`, query whether there ## For a storage tree related to account `accPath`, query whether there
## is a non-empty data storage area at all. ## is a non-empty data storage area at all.
## ##
let stoID = db.fetchStorageID(accPath).valueOr: let stoID = db.fetchStorageIdImpl(accPath).valueOr:
if error == FetchPathNotFound: if error == FetchPathNotFound:
return ok(false) # no sub-tree return ok(false) # no sub-tree
return err(error) return err(error)

View File

@ -111,9 +111,12 @@ proc partStorageTwig*(
accPath: Hash256; accPath: Hash256;
stoPath: Hash256; stoPath: Hash256;
): Result[(seq[Blob],bool), AristoError] = ): Result[(seq[Blob],bool), AristoError] =
## Variant of `partGenericTwig()`. Note that the function always returns an ## Variant of `partGenericTwig()`. Note that the function returns an error unless
## error unless the `accPath` is valid. ## the argument `accPath` is valid.
let vid = ? db.fetchStorageID accPath let vid = db.fetchStorageID(accPath).valueOr:
if error == FetchPathStoRootMissing:
return ok((@[],false))
return err(error)
db.partGenericTwig(vid, NibblesBuf.fromBytes stoPath.data) db.partGenericTwig(vid, NibblesBuf.fromBytes stoPath.data)
# ---------- # ----------