198 lines
6.1 KiB
Nim
198 lines
6.1 KiB
Nim
# 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.
|
|
|
|
{.push raises: [].}
|
|
|
|
## Parked here, currently uded only for trancode tests
|
|
|
|
import
|
|
std/tables,
|
|
eth/common,
|
|
stew/results,
|
|
../../nimbus/db/aristo/[aristo_desc, aristo_transcode, aristo_vid]
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Private helpers
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc convertPartially(
|
|
db: AristoDbRef;
|
|
vtx: VertexRef;
|
|
nd: var NodeRef;
|
|
): seq[VertexID] =
|
|
## Returns true if completely converted by looking up the cached hashes.
|
|
## This function does not recurse. It will return the vertex IDs that are
|
|
## are missing in order to convert in a single step.
|
|
case vtx.vType:
|
|
of Leaf:
|
|
nd = NodeRef(
|
|
vType: Leaf,
|
|
lPfx: vtx.lPfx,
|
|
lData: vtx.lData)
|
|
if vtx.lData.pType != AccountData:
|
|
return
|
|
let vid = vtx.lData.account.storageID
|
|
if vid.isValid:
|
|
let lbl = db.top.kMap.getOrVoid vid
|
|
if lbl.isValid:
|
|
nd.key[0] = lbl.key
|
|
return
|
|
result.add vid
|
|
of Extension:
|
|
nd = NodeRef(
|
|
vType: Extension,
|
|
ePfx: vtx.ePfx,
|
|
eVid: vtx.eVid)
|
|
let lbl = db.top.kMap.getOrVoid vtx.eVid
|
|
if lbl.isValid:
|
|
nd.key[0] = lbl.key
|
|
return
|
|
result.add vtx.eVid
|
|
of Branch:
|
|
nd = NodeRef(
|
|
vType: Branch,
|
|
bVid: vtx.bVid)
|
|
for n in 0..15:
|
|
if vtx.bVid[n].isValid:
|
|
let lbl = db.top.kMap.getOrVoid vtx.bVid[n]
|
|
if lbl.isValid:
|
|
nd.key[n] = lbl.key
|
|
continue
|
|
result.add vtx.bVid[n]
|
|
|
|
proc convertPartiallyOk(
|
|
db: AristoDbRef;
|
|
vtx: VertexRef;
|
|
nd: var NodeRef;
|
|
): bool =
|
|
## Variant of `convertPartially()`, shortcut for `convertPartially().le==0`.
|
|
case vtx.vType:
|
|
of Leaf:
|
|
nd = NodeRef(
|
|
vType: Leaf,
|
|
lPfx: vtx.lPfx,
|
|
lData: vtx.lData)
|
|
if vtx.lData.pType != AccountData:
|
|
result = true
|
|
else:
|
|
let vid = vtx.lData.account.storageID
|
|
if vid.isValid:
|
|
let lbl = db.top.kMap.getOrVoid vid
|
|
if lbl.isValid:
|
|
nd.key[0] = lbl.key
|
|
result = true
|
|
of Extension:
|
|
nd = NodeRef(
|
|
vType: Extension,
|
|
ePfx: vtx.ePfx,
|
|
eVid: vtx.eVid)
|
|
let lbl = db.top.kMap.getOrVoid vtx.eVid
|
|
if lbl.isValid:
|
|
nd.key[0] = lbl.key
|
|
result = true
|
|
of Branch:
|
|
nd = NodeRef(
|
|
vType: Branch,
|
|
bVid: vtx.bVid)
|
|
result = true
|
|
for n in 0..15:
|
|
if vtx.bVid[n].isValid:
|
|
let lbl = db.top.kMap.getOrVoid vtx.bVid[n]
|
|
if lbl.isValid:
|
|
nd.key[n] = lbl.key
|
|
continue
|
|
return false
|
|
|
|
proc cachedVID(db: AristoDbRef; lbl: HashLabel): VertexID =
|
|
## Get vertex ID from reverse cache
|
|
result = db.top.pAmk.getOrVoid lbl
|
|
if not result.isValid:
|
|
result = db.vidAttach lbl
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public functions for `VertexID` => `HashKey` mapping
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc pal*(db: AristoDbRef; 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
|
|
## table is checked whether the cache can be updated.
|
|
if not db.top.isNil:
|
|
|
|
let lbl = db.top.kMap.getOrVoid vid
|
|
if lbl.isValid:
|
|
return lbl.key
|
|
|
|
let vtx = db.top.sTab.getOrVoid vid
|
|
if vtx.isValid:
|
|
var node: NodeRef
|
|
if db.convertPartiallyOk(vtx,node):
|
|
var w = initRlpWriter()
|
|
w.append node
|
|
result = w.finish.keccakHash.data.HashKey
|
|
db.top.kMap[vid] = HashLabel(root: rootID, key: result)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public funcions extending/completing vertex records
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc updated*(nd: NodeRef; root: VertexID; db: AristoDbRef): NodeRef =
|
|
## Return a copy of the argument node `nd` with updated missing vertex IDs.
|
|
##
|
|
## 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 `HashKey`
|
|
## objects) are zero for either `Extension` or `Leaf` nodes.
|
|
if nd.isValid:
|
|
case nd.vType:
|
|
of Leaf:
|
|
result = NodeRef(
|
|
vType: Leaf,
|
|
lPfx: nd.lPfx,
|
|
lData: nd.lData)
|
|
of Extension:
|
|
result = NodeRef(
|
|
vType: Extension,
|
|
ePfx: nd.ePfx)
|
|
if nd.key[0].isValid:
|
|
result.eVid = db.cachedVID HashLabel(root: root, key: nd.key[0])
|
|
result.key[0] = nd.key[0]
|
|
of Branch:
|
|
result = NodeRef(
|
|
vType: Branch,
|
|
key: nd.key)
|
|
for n in 0..15:
|
|
if nd.key[n].isValid:
|
|
result.bVid[n] = db.cachedVID HashLabel(root: root, key: nd.key[n])
|
|
|
|
proc asNode*(vtx: VertexRef; db: AristoDbRef): NodeRef =
|
|
## Return a `NodeRef` object by augmenting missing `Merkel` hashes (aka
|
|
## `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
|
|
## result object is a wrapper around an error code.
|
|
if not db.convertPartiallyOk(vtx, result):
|
|
return NodeRef(error: CacheMissingNodekeys)
|
|
|
|
proc asNode*(rc: Result[VertexRef,AristoError]; db: AristoDbRef): NodeRef =
|
|
## Variant of `asNode()`.
|
|
if rc.isErr:
|
|
return NodeRef(error: rc.error)
|
|
rc.value.asNode(db)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# End
|
|
# ------------------------------------------------------------------------------
|