mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-02 15:24:01 +00:00
Core db update api and fix tracer methods (#1816)
* CoreDB: Re-org API details: Legacy API internally uses vertex ID for root node abstraction * Cosmetics: Move some unit test helpers to common sub-directory * Extract constant from `accouns_cache.nim` => `constants.nim` * Fix tracer methods why: Logger dump data were wrongly dumped from the production database. This caused an assert exception when iterating over the persistent database (instead of the memory logger.) This event in turn was enabled after fixing another inconsistency which just set up an empty iterator. Unit tests failed to detect that.
This commit is contained in:
parent
3444ffaf30
commit
786263c0b8
@ -92,4 +92,9 @@ const
|
|||||||
# SystemAddress is where the system-transaction is sent from as per EIP-4788
|
# SystemAddress is where the system-transaction is sent from as per EIP-4788
|
||||||
SystemAddress* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe")
|
SystemAddress* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe")
|
||||||
|
|
||||||
|
RIPEMD_ADDR* = block:
|
||||||
|
proc initAddress(x: int): EthAddress {.compileTime.} =
|
||||||
|
result[19] = x.byte
|
||||||
|
initAddress(3)
|
||||||
|
|
||||||
# End
|
# End
|
||||||
|
@ -81,11 +81,6 @@ const
|
|||||||
NewlyCreated
|
NewlyCreated
|
||||||
}
|
}
|
||||||
|
|
||||||
ripemdAddr* = block:
|
|
||||||
proc initAddress(x: int): EthAddress {.compileTime.} =
|
|
||||||
result[19] = x.byte
|
|
||||||
initAddress(3)
|
|
||||||
|
|
||||||
when debugAccountsCache:
|
when debugAccountsCache:
|
||||||
import
|
import
|
||||||
stew/byteutils
|
stew/byteutils
|
||||||
@ -105,7 +100,7 @@ proc beginSavepoint*(ac: var AccountsCache): SavePoint {.gcsafe.}
|
|||||||
proc rawTrie*(ac: AccountsCache): AccountsTrie = ac.trie
|
proc rawTrie*(ac: AccountsCache): AccountsTrie = ac.trie
|
||||||
|
|
||||||
func db(ac: AccountsCache): CoreDbRef = ac.trie.db
|
func db(ac: AccountsCache): CoreDbRef = ac.trie.db
|
||||||
func kvt(ac: AccountsCache): CoreDbKvtRef = ac.db.kvt
|
proc kvt(ac: AccountsCache): CoreDbKvtRef = ac.db.kvt
|
||||||
|
|
||||||
# The AccountsCache is modeled after TrieDatabase for it's transaction style
|
# The AccountsCache is modeled after TrieDatabase for it's transaction style
|
||||||
proc init*(x: typedesc[AccountsCache], db: CoreDbRef,
|
proc init*(x: typedesc[AccountsCache], db: CoreDbRef,
|
||||||
@ -560,7 +555,7 @@ proc clearEmptyAccounts(ac: AccountsCache) =
|
|||||||
|
|
||||||
# https://github.com/ethereum/EIPs/issues/716
|
# https://github.com/ethereum/EIPs/issues/716
|
||||||
if ac.ripemdSpecial:
|
if ac.ripemdSpecial:
|
||||||
ac.deleteEmptyAccount(ripemdAddr)
|
ac.deleteEmptyAccount(RIPEMD_ADDR)
|
||||||
ac.ripemdSpecial = false
|
ac.ripemdSpecial = false
|
||||||
|
|
||||||
proc persist*(ac: AccountsCache,
|
proc persist*(ac: AccountsCache,
|
||||||
|
@ -14,24 +14,40 @@ import
|
|||||||
std/options,
|
std/options,
|
||||||
eth/[common, rlp, trie/db, trie/hexary],
|
eth/[common, rlp, trie/db, trie/hexary],
|
||||||
results,
|
results,
|
||||||
../../errors,
|
../../../errors,
|
||||||
"."/[base, base/base_desc]
|
".."/[base, base/base_desc]
|
||||||
|
|
||||||
type
|
type
|
||||||
LegacyApiRlpError* = object of CoreDbApiError
|
LegacyApiRlpError* = object of CoreDbApiError
|
||||||
## For re-routing exceptions in iterator closure
|
## For re-routing exceptions in iterator closure
|
||||||
|
|
||||||
LegacyDbRef* = ref object of CoreDbRef
|
# -----------
|
||||||
tdb: TrieDatabaseRef # copy of descriptor reference captured with closures
|
|
||||||
|
|
||||||
HexaryTrieRef = ref object
|
LegacyDbRef* = ref object of CoreDbRef
|
||||||
trie: HexaryTrie # needed for descriptor capturing with closures
|
kvt: CoreDxKvtRef ## Cache, no need to rebuild methods descriptor
|
||||||
|
tdb: TrieDatabaseRef ## Copy of descriptor reference captured with closures
|
||||||
|
|
||||||
|
LegacyDbClose* = proc() {.gcsafe, raises: [].}
|
||||||
|
## Custom destructor
|
||||||
|
|
||||||
|
HexaryChildDbRef = ref object
|
||||||
|
trie: HexaryTrie ## needed for descriptor capturing with closures
|
||||||
|
|
||||||
RecorderRef = ref object of RootRef
|
RecorderRef = ref object of RootRef
|
||||||
flags: set[CoreDbCaptFlags]
|
flags: set[CoreDbCaptFlags]
|
||||||
parent: TrieDatabaseRef
|
parent: TrieDatabaseRef
|
||||||
recorder: TrieDatabaseRef
|
logger: LegacyDbRef
|
||||||
appDb: CoreDbRef
|
appDb: LegacyDbRef
|
||||||
|
|
||||||
|
LegacyCoreDbVid* = ref object of CoreDbVidRef
|
||||||
|
vHash: Hash256 ## Hash key
|
||||||
|
|
||||||
|
LegacyCoreDbError = ref object of CoreDbErrorRef
|
||||||
|
ctx: string ## Context where the exception or error occured
|
||||||
|
name: string ## name of exception
|
||||||
|
msg: string ## Exception info
|
||||||
|
|
||||||
|
# ------------
|
||||||
|
|
||||||
LegacyCoreDbBE = ref object of CoreDbBackendRef
|
LegacyCoreDbBE = ref object of CoreDbBackendRef
|
||||||
base: LegacyDbRef
|
base: LegacyDbRef
|
||||||
@ -42,15 +58,14 @@ type
|
|||||||
LegacyCoreDbMptBE = ref object of CoreDbMptBackendRef
|
LegacyCoreDbMptBE = ref object of CoreDbMptBackendRef
|
||||||
mpt: HexaryTrie
|
mpt: HexaryTrie
|
||||||
|
|
||||||
LegacyCoreDbError = ref object of CoreDbErrorRef
|
LegacyCoreDbAccBE = ref object of CoreDbAccBackendRef
|
||||||
ctx: string ## Context where the exception or error occured
|
mpt: HexaryTrie
|
||||||
name: string ## name of exception
|
|
||||||
msg: string ## Exception info
|
|
||||||
|
|
||||||
proc init*(
|
proc init*(
|
||||||
db: LegacyDbRef;
|
db: LegacyDbRef;
|
||||||
dbType: CoreDbType;
|
dbType: CoreDbType;
|
||||||
tdb: TrieDatabaseRef;
|
tdb: TrieDatabaseRef;
|
||||||
|
closeDb = LegacyDbClose(nil);
|
||||||
): CoreDbRef
|
): CoreDbRef
|
||||||
{.gcsafe.}
|
{.gcsafe.}
|
||||||
|
|
||||||
@ -62,11 +77,11 @@ template mapRlpException(db: LegacyDbRef; info: static[string]; code: untyped) =
|
|||||||
try:
|
try:
|
||||||
code
|
code
|
||||||
except RlpError as e:
|
except RlpError as e:
|
||||||
var w = LegacyCoreDbError(
|
return err(db.bless LegacyCoreDbError(
|
||||||
ctx: info,
|
error: RlpException,
|
||||||
name: $e.name,
|
ctx: info,
|
||||||
msg: e.msg)
|
name: $e.name,
|
||||||
return err(db.bless w)
|
msg: e.msg))
|
||||||
|
|
||||||
template reraiseRlpException(info: static[string]; code: untyped) =
|
template reraiseRlpException(info: static[string]; code: untyped) =
|
||||||
try:
|
try:
|
||||||
@ -75,92 +90,91 @@ template reraiseRlpException(info: static[string]; code: untyped) =
|
|||||||
let msg = info & ", name=\"" & $e.name & "\", msg=\"" & e.msg & "\""
|
let msg = info & ", name=\"" & $e.name & "\", msg=\"" & e.msg & "\""
|
||||||
raise (ref LegacyApiRlpError)(msg: msg)
|
raise (ref LegacyApiRlpError)(msg: msg)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Private helpers, other functions
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc errorPrint(e: CoreDbErrorRef): string =
|
||||||
|
if not e.isNil:
|
||||||
|
let e = e.LegacyCoreDbError
|
||||||
|
result &= "ctx=\"" & $e.ctx & "\""
|
||||||
|
if e.name != "":
|
||||||
|
result &= ", name=\"" & $e.name & "\""
|
||||||
|
if e.msg != "":
|
||||||
|
result &= ", msg=\"" & $e.msg & "\""
|
||||||
|
|
||||||
|
func lvHash(vid: CoreDbVidRef): Hash256 =
|
||||||
|
if not vid.isNil and vid.ready:
|
||||||
|
return vid.LegacyCoreDbVid.vHash
|
||||||
|
EMPTY_ROOT_HASH
|
||||||
|
|
||||||
|
proc toCoreDbAccount(
|
||||||
|
data: Blob;
|
||||||
|
db: LegacyDbRef;
|
||||||
|
): CoreDbAccount
|
||||||
|
{.gcsafe, raises: [RlpError].} =
|
||||||
|
let acc = rlp.decode(data, Account)
|
||||||
|
CoreDbAccount(
|
||||||
|
nonce: acc.nonce,
|
||||||
|
balance: acc.balance,
|
||||||
|
codeHash: acc.codeHash,
|
||||||
|
storageVid: db.bless LegacyCoreDbVid(vHash: acc.storageRoot))
|
||||||
|
|
||||||
|
proc toAccount(
|
||||||
|
account: CoreDbAccount
|
||||||
|
): Account =
|
||||||
|
## Fast rewrite of `recast()` from base which reures to `vidHashFn()`
|
||||||
|
Account(
|
||||||
|
nonce: account.nonce,
|
||||||
|
balance: account.balance,
|
||||||
|
codeHash: account.codeHash,
|
||||||
|
storageRoot: account.storageVid.lvHash)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private mixin methods for `trieDB` (backport from capturedb/tracer sources)
|
# Private mixin methods for `trieDB` (backport from capturedb/tracer sources)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc get(db: RecorderRef, key: openArray[byte]): Blob =
|
proc get(db: RecorderRef, key: openArray[byte]): Blob =
|
||||||
## Mixin for `trieDB()`
|
## Mixin for `trieDB()`
|
||||||
result = db.recorder.get(key)
|
result = db.logger.tdb.get(key)
|
||||||
if result.len == 0:
|
if result.len == 0:
|
||||||
result = db.parent.get(key)
|
result = db.parent.get(key)
|
||||||
if result.len != 0:
|
if result.len != 0:
|
||||||
db.recorder.put(key, result)
|
db.logger.tdb.put(key, result)
|
||||||
|
|
||||||
proc put(db: RecorderRef, key, value: openArray[byte]) =
|
proc put(db: RecorderRef, key, value: openArray[byte]) =
|
||||||
## Mixin for `trieDB()`
|
## Mixin for `trieDB()`
|
||||||
db.recorder.put(key, value)
|
db.logger.tdb.put(key, value)
|
||||||
if PersistPut in db.flags:
|
if PersistPut in db.flags:
|
||||||
db.parent.put(key, value)
|
db.parent.put(key, value)
|
||||||
|
|
||||||
proc contains(db: RecorderRef, key: openArray[byte]): bool =
|
proc contains(db: RecorderRef, key: openArray[byte]): bool =
|
||||||
## Mixin for `trieDB()`
|
## Mixin for `trieDB()`
|
||||||
result = db.parent.contains(key)
|
result = db.parent.contains(key)
|
||||||
doAssert(db.recorder.contains(key) == result)
|
doAssert(db.logger.tdb.contains(key) == result)
|
||||||
|
|
||||||
proc del(db: RecorderRef, key: openArray[byte]) =
|
proc del(db: RecorderRef, key: openArray[byte]) =
|
||||||
## Mixin for `trieDB()`
|
## Mixin for `trieDB()`
|
||||||
db.recorder.del(key)
|
db.logger.tdb.del(key)
|
||||||
if PersistDel in db.flags:
|
if PersistDel in db.flags:
|
||||||
db.parent.del(key)
|
db.parent.del(key)
|
||||||
|
|
||||||
proc newRecorderRef(
|
proc newRecorderRef(
|
||||||
tdb: TrieDatabaseRef;
|
tdb: TrieDatabaseRef;
|
||||||
|
dbType: CoreDbType,
|
||||||
flags: set[CoreDbCaptFlags];
|
flags: set[CoreDbCaptFlags];
|
||||||
): RecorderRef =
|
): RecorderRef =
|
||||||
## Capture constuctor, uses `mixin` values from above
|
## Capture constuctor, uses `mixin` values from above
|
||||||
result = RecorderRef(
|
result = RecorderRef(
|
||||||
flags: flags,
|
flags: flags,
|
||||||
parent: tdb,
|
parent: tdb,
|
||||||
recorder: newMemoryDB())
|
logger: LegacyDbRef().init(LegacyDbMemory, newMemoryDB()).LegacyDbRef)
|
||||||
result.appDb = LegacyDbRef().init(LegacyDbMemory, trieDB result)
|
result.appDb = LegacyDbRef().init(dbType, trieDB result).LegacyDbRef
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private database method function tables
|
# Private database method function tables
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc miscMethods(db: LegacyDbRef): CoreDbMiscFns =
|
|
||||||
CoreDbMiscFns(
|
|
||||||
backendFn: proc(): CoreDbBackendRef =
|
|
||||||
db.bless(LegacyCoreDbBE(base: db)),
|
|
||||||
|
|
||||||
errorPrintFn: proc(e: CoreDbErrorRef): string =
|
|
||||||
if not e.isNil:
|
|
||||||
let e = e.LegacyCoreDbError
|
|
||||||
result &= "ctx=\"" & $e.ctx & "\"" & " , "
|
|
||||||
result &= "name=\"" & $e.name & "\"" & ", "
|
|
||||||
result &= "msg=\"" & $e.msg & "\""
|
|
||||||
discard,
|
|
||||||
|
|
||||||
legacySetupFn: proc() =
|
|
||||||
db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]))
|
|
||||||
|
|
||||||
proc kvtHandlers(db: LegacyDbRef): CoreDxKvtRef =
|
|
||||||
## Key-value database table handlers
|
|
||||||
let tdb = db.tdb
|
|
||||||
CoreDxKvtRef(
|
|
||||||
methods: CoreDbKvtFns(
|
|
||||||
backendFn: proc(): CoreDbKvtBackendRef =
|
|
||||||
db.bless(LegacyCoreDbKvtBE(tdb: tdb)),
|
|
||||||
|
|
||||||
getFn: proc(k: openArray[byte]): CoreDbRc[Blob] =
|
|
||||||
ok(tdb.get(k)),
|
|
||||||
|
|
||||||
delFn: proc(k: openArray[byte]): CoreDbRc[void] =
|
|
||||||
tdb.del(k)
|
|
||||||
ok(),
|
|
||||||
|
|
||||||
putFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
|
|
||||||
tdb.put(k,v)
|
|
||||||
ok(),
|
|
||||||
|
|
||||||
containsFn: proc(k: openArray[byte]): CoreDbRc[bool] =
|
|
||||||
ok(tdb.contains(k)),
|
|
||||||
|
|
||||||
pairsIt: iterator(): (Blob, Blob) =
|
|
||||||
for k,v in tdb.pairsInMemoryDB:
|
|
||||||
yield (k,v)))
|
|
||||||
|
|
||||||
proc kvtMethods(db: LegacyDbRef): CoreDbKvtFns =
|
proc kvtMethods(db: LegacyDbRef): CoreDbKvtFns =
|
||||||
## Key-value database table handlers
|
## Key-value database table handlers
|
||||||
let tdb = db.tdb
|
let tdb = db.tdb
|
||||||
@ -186,23 +200,23 @@ proc kvtMethods(db: LegacyDbRef): CoreDbKvtFns =
|
|||||||
for k,v in tdb.pairsInMemoryDB:
|
for k,v in tdb.pairsInMemoryDB:
|
||||||
yield (k,v))
|
yield (k,v))
|
||||||
|
|
||||||
proc mptMethods(mpt: HexaryTrieRef; db: LegacyDbRef): CoreDbMptFns =
|
proc mptMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbMptFns =
|
||||||
## Hexary trie database handlers
|
## Hexary trie database handlers
|
||||||
CoreDbMptFns(
|
CoreDbMptFns(
|
||||||
backendFn: proc(): CoreDbMptBackendRef =
|
backendFn: proc(): CoreDbMptBackendRef =
|
||||||
db.bless(LegacyCoreDbMptBE(mpt: mpt.trie)),
|
db.bless(LegacyCoreDbMptBE(mpt: mpt.trie)),
|
||||||
|
|
||||||
getFn: proc(k: openArray[byte]): CoreDbRc[Blob] =
|
fetchFn: proc(k: openArray[byte]): CoreDbRc[Blob] =
|
||||||
db.mapRlpException("legacy/mpt/get()"):
|
db.mapRlpException("legacy/mpt/get()"):
|
||||||
return ok(mpt.trie.get(k))
|
return ok(mpt.trie.get(k))
|
||||||
discard,
|
discard,
|
||||||
|
|
||||||
delFn: proc(k: openArray[byte]): CoreDbRc[void] =
|
deleteFn: proc(k: openArray[byte]): CoreDbRc[void] =
|
||||||
db.mapRlpException("legacy/mpt/del()"):
|
db.mapRlpException("legacy/mpt/del()"):
|
||||||
mpt.trie.del(k)
|
mpt.trie.del(k)
|
||||||
ok(),
|
ok(),
|
||||||
|
|
||||||
putFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
|
mergeFn: proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
|
||||||
db.mapRlpException("legacy/mpt/put()"):
|
db.mapRlpException("legacy/mpt/put()"):
|
||||||
mpt.trie.put(k,v)
|
mpt.trie.put(k,v)
|
||||||
ok(),
|
ok(),
|
||||||
@ -212,24 +226,57 @@ proc mptMethods(mpt: HexaryTrieRef; db: LegacyDbRef): CoreDbMptFns =
|
|||||||
return ok(mpt.trie.contains(k))
|
return ok(mpt.trie.contains(k))
|
||||||
discard,
|
discard,
|
||||||
|
|
||||||
rootHashFn: proc(): CoreDbRc[Hash256] =
|
rootVidFn: proc(): CoreDbVidRef =
|
||||||
ok(mpt.trie.rootHash),
|
db.bless(LegacyCoreDbVid(vHash: mpt.trie.rootHash)),
|
||||||
|
|
||||||
isPruningFn: proc(): bool =
|
isPruningFn: proc(): bool =
|
||||||
mpt.trie.isPruning,
|
mpt.trie.isPruning,
|
||||||
|
|
||||||
pairsIt: iterator(): (Blob, Blob) {.gcsafe, raises: [CoreDbApiError].} =
|
pairsIt: iterator: (Blob,Blob) {.gcsafe, raises: [LegacyApiRlpError].} =
|
||||||
reraiseRlpException("legacy/mpt/pairs()"):
|
reraiseRlpException("legacy/mpt/pairs()"):
|
||||||
for k,v in mpt.trie.pairs():
|
for k,v in mpt.trie.pairs():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
discard,
|
discard,
|
||||||
|
|
||||||
replicateIt: iterator(): (Blob, Blob) {.gcsafe, raises: [CoreDbApiError].} =
|
replicateIt: iterator: (Blob,Blob) {.gcsafe, raises: [LegacyApiRlpError].} =
|
||||||
reraiseRlpException("legacy/mpt/replicate()"):
|
reraiseRlpException("legacy/mpt/replicate()"):
|
||||||
for k,v in mpt.trie.replicate():
|
for k,v in mpt.trie.replicate():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
discard)
|
discard)
|
||||||
|
|
||||||
|
proc accMethods(mpt: HexaryChildDbRef; db: LegacyDbRef): CoreDbAccFns =
|
||||||
|
## Hexary trie database handlers
|
||||||
|
CoreDbAccFns(
|
||||||
|
backendFn: proc(): CoreDbAccBackendRef =
|
||||||
|
db.bless(LegacyCoreDbAccBE(mpt: mpt.trie)),
|
||||||
|
|
||||||
|
fetchFn: proc(k: EthAddress): CoreDbRc[CoreDbAccount] =
|
||||||
|
const info = "legacy/mpt/getAccount()"
|
||||||
|
db.mapRlpException info:
|
||||||
|
return ok mpt.trie.get(k.keccakHash.data).toCoreDbAccount(db)
|
||||||
|
return err(db.bless LegacyCoreDbError(error: MptNotFound, ctx: info)),
|
||||||
|
|
||||||
|
deleteFn: proc(k: EthAddress): CoreDbRc[void] =
|
||||||
|
db.mapRlpException("legacy/mpt/del()"):
|
||||||
|
mpt.trie.del(k.keccakHash.data)
|
||||||
|
ok(),
|
||||||
|
|
||||||
|
mergeFn: proc(k: EthAddress; v: CoreDbAccount): CoreDbRc[void] =
|
||||||
|
db.mapRlpException("legacy/mpt/put()"):
|
||||||
|
mpt.trie.put(k.keccakHash.data, rlp.encode v.toAccount)
|
||||||
|
ok(),
|
||||||
|
|
||||||
|
containsFn: proc(k: EthAddress): CoreDbRc[bool] =
|
||||||
|
db.mapRlpException("legacy/mpt/put()"):
|
||||||
|
return ok(mpt.trie.contains k.keccakHash.data)
|
||||||
|
discard,
|
||||||
|
|
||||||
|
rootVidFn: proc(): CoreDbVidRef =
|
||||||
|
db.bless(LegacyCoreDbVid(vHash: mpt.trie.rootHash)),
|
||||||
|
|
||||||
|
isPruningFn: proc(): bool =
|
||||||
|
mpt.trie.isPruning)
|
||||||
|
|
||||||
proc txMethods(tx: DbTransaction): CoreDbTxFns =
|
proc txMethods(tx: DbTransaction): CoreDbTxFns =
|
||||||
CoreDbTxFns(
|
CoreDbTxFns(
|
||||||
commitFn: proc(applyDeletes: bool): CoreDbRc[void] =
|
commitFn: proc(applyDeletes: bool): CoreDbRc[void] =
|
||||||
@ -259,37 +306,72 @@ proc cptMethods(cpt: RecorderRef): CoreDbCaptFns =
|
|||||||
recorderFn: proc(): CoreDbRc[CoreDbRef] =
|
recorderFn: proc(): CoreDbRc[CoreDbRef] =
|
||||||
ok(cpt.appDb),
|
ok(cpt.appDb),
|
||||||
|
|
||||||
|
logDbFn: proc(): CoreDbRc[CoreDbRef] =
|
||||||
|
ok(cpt.logger),
|
||||||
|
|
||||||
getFlagsFn: proc(): set[CoreDbCaptFlags] =
|
getFlagsFn: proc(): set[CoreDbCaptFlags] =
|
||||||
cpt.flags)
|
cpt.flags)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private constructor functions table
|
# Private base methods (including constructors)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc constructors(db: LegacyDbRef): CoreDbConstructorFns =
|
proc baseMethods(
|
||||||
|
db: LegacyDbRef;
|
||||||
|
dbType: CoreDbType;
|
||||||
|
closeDb: LegacyDbClose;
|
||||||
|
): CoreDbBaseFns =
|
||||||
let tdb = db.tdb
|
let tdb = db.tdb
|
||||||
CoreDbConstructorFns(
|
CoreDbBaseFns(
|
||||||
mptFn: proc(root: Hash256): CoreDbRc[CoreDxMptRef] =
|
backendFn: proc(): CoreDbBackendRef =
|
||||||
let mpt = HexaryTrieRef(trie: initHexaryTrie(tdb, root, false))
|
db.bless(LegacyCoreDbBE(base: db)),
|
||||||
var dsc = CoreDxMptRef(methods: mpt.mptMethods(db))
|
|
||||||
ok(db.bless dsc),
|
|
||||||
|
|
||||||
legacyMptFn: proc(root: Hash256; prune: bool): CoreDbRc[CoreDxMptRef] =
|
destroyFn: proc(ignore: bool) =
|
||||||
let mpt = HexaryTrieRef(trie: initHexaryTrie(tdb, root, prune))
|
if not closeDb.isNil:
|
||||||
var dsc = CoreDxMptRef(methods: mpt.mptMethods(db))
|
closeDb()
|
||||||
ok(db.bless dsc),
|
discard,
|
||||||
|
|
||||||
|
vidHashFn: proc(vid: CoreDbVidRef): Result[Hash256,void] =
|
||||||
|
ok(vid.lvHash),
|
||||||
|
|
||||||
|
errorPrintFn: proc(e: CoreDbErrorRef): string =
|
||||||
|
e.errorPrint(),
|
||||||
|
|
||||||
|
legacySetupFn: proc() =
|
||||||
|
db.tdb.put(EMPTY_ROOT_HASH.data, @[0x80u8]),
|
||||||
|
|
||||||
|
getRootFn: proc(root: Hash256; createOk: bool): CoreDbRc[CoreDbVidRef] =
|
||||||
|
if root == EMPTY_CODE_HASH:
|
||||||
|
return ok(db.bless LegacyCoreDbVid(vHash: EMPTY_CODE_HASH))
|
||||||
|
|
||||||
|
# Due to the way it is used for creating a ne root node, `createOk` must
|
||||||
|
# be checked before `contains()` is run. Otherwise it might bail out in
|
||||||
|
# the assertion of the above trace/recorder mixin `contains()` function.
|
||||||
|
if createOk or tdb.contains(root.data):
|
||||||
|
return ok(db.bless LegacyCoreDbVid(vHash: root))
|
||||||
|
|
||||||
|
err(db.bless LegacyCoreDbError(error: RootNotFound, ctx: "getRoot()")),
|
||||||
|
|
||||||
|
newKvtFn: proc(): CoreDxKvtRef =
|
||||||
|
db.kvt,
|
||||||
|
|
||||||
|
newMptFn: proc(root: CoreDbVidRef, prune: bool): CoreDbRc[CoreDxMptRef] =
|
||||||
|
let mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, root.lvHash, prune))
|
||||||
|
ok(db.bless CoreDxMptRef(methods: mpt.mptMethods db)),
|
||||||
|
|
||||||
|
newAccFn: proc(root: CoreDbVidRef, prune: bool): CoreDbRc[CoreDxAccRef] =
|
||||||
|
let mpt = HexaryChildDbRef(trie: initHexaryTrie(tdb, root.lvHash, prune))
|
||||||
|
ok(db.bless CoreDxAccRef(methods: mpt.accMethods db)),
|
||||||
|
|
||||||
getIdFn: proc(): CoreDbRc[CoreDxTxID] =
|
getIdFn: proc(): CoreDbRc[CoreDxTxID] =
|
||||||
var dsc = CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb))
|
ok(db.bless CoreDxTxID(methods: tdb.getTransactionID.tidMethods(tdb))),
|
||||||
ok(db.bless dsc),
|
|
||||||
|
|
||||||
beginFn: proc(): CoreDbRc[CoreDxTxRef] =
|
beginFn: proc(): CoreDbRc[CoreDxTxRef] =
|
||||||
var dsc = CoreDxTxRef(methods: tdb.beginTransaction.txMethods)
|
ok(db.bless CoreDxTxRef(methods: tdb.beginTransaction.txMethods)),
|
||||||
ok(db.bless dsc),
|
|
||||||
|
|
||||||
captureFn: proc(flags: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] =
|
captureFn: proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] =
|
||||||
var dsc = CoreDxCaptRef(methods: newRecorderRef(tdb, flags).cptMethods)
|
let fns = newRecorderRef(tdb, dbtype, flgs).cptMethods
|
||||||
ok(db.bless dsc))
|
ok(db.bless CoreDxCaptRef(methods: fns)))
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public constructor helpers
|
# Public constructor helpers
|
||||||
@ -299,14 +381,18 @@ proc init*(
|
|||||||
db: LegacyDbRef;
|
db: LegacyDbRef;
|
||||||
dbType: CoreDbType;
|
dbType: CoreDbType;
|
||||||
tdb: TrieDatabaseRef;
|
tdb: TrieDatabaseRef;
|
||||||
|
closeDb = LegacyDbClose(nil);
|
||||||
): CoreDbRef =
|
): CoreDbRef =
|
||||||
|
## Constructor helper
|
||||||
|
|
||||||
|
# Local extensions
|
||||||
db.tdb = tdb
|
db.tdb = tdb
|
||||||
db.init(
|
db.kvt = db.bless CoreDxKvtRef(methods: db.kvtMethods())
|
||||||
dbType = dbType,
|
|
||||||
dbMethods = db.miscMethods,
|
# Base descriptor
|
||||||
kvtMethods = db.kvtMethods,
|
db.dbType = dbType
|
||||||
newSubMod = db.constructors)
|
db.methods = db.baseMethods(dbType, closeDb)
|
||||||
db
|
db.bless
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public constructor and low level data retrieval, storage & transation frame
|
# Public constructor and low level data retrieval, storage & transation frame
|
||||||
@ -336,7 +422,11 @@ func toLegacy*(be: CoreDbKvtBackendRef): TrieDatabaseRef =
|
|||||||
func toLegacy*(be: CoreDbMptBackendRef): HexaryTrie =
|
func toLegacy*(be: CoreDbMptBackendRef): HexaryTrie =
|
||||||
if be.parent.isLegacy:
|
if be.parent.isLegacy:
|
||||||
return be.LegacyCoreDbMptBE.mpt
|
return be.LegacyCoreDbMptBE.mpt
|
||||||
|
|
||||||
|
func toLegacy*(be: CoreDbAccBackendRef): HexaryTrie =
|
||||||
|
if be.parent.isLegacy:
|
||||||
|
return be.LegacyCoreDbAccBE.mpt
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
@ -12,13 +12,18 @@
|
|||||||
|
|
||||||
import
|
import
|
||||||
eth/trie/db,
|
eth/trie/db,
|
||||||
../select_backend,
|
rocksdb,
|
||||||
"."/[base, legacy_db]
|
"../.."/select_backend,
|
||||||
|
../base,
|
||||||
|
./legacy_db
|
||||||
|
|
||||||
type
|
type
|
||||||
LegaPersDbRef = ref object of LegacyDbRef
|
LegaPersDbRef = ref object of LegacyDbRef
|
||||||
rdb: RocksStoreRef # for backend access with legacy mode
|
rdb: RocksStoreRef # for backend access with legacy mode
|
||||||
|
|
||||||
|
# No other backend supported
|
||||||
|
doAssert nimbus_db_backend == "rocksdb"
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public constructor and low level data retrieval, storage & transation frame
|
# Public constructor and low level data retrieval, storage & transation frame
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -41,7 +46,11 @@ proc newLegacyPersistentCoreDbRef*(path: string): CoreDbRef =
|
|||||||
except CatchableError as e:
|
except CatchableError as e:
|
||||||
let msg = "DB initialisation error(" & $e.name & "): " & e.msg
|
let msg = "DB initialisation error(" & $e.name & "): " & e.msg
|
||||||
raise (ref ResultDefect)(msg: msg)
|
raise (ref ResultDefect)(msg: msg)
|
||||||
LegaPersDbRef(rdb: backend.rdb).init(LegacyDbPersistent, backend.trieDB)
|
|
||||||
|
proc done() =
|
||||||
|
backend.rdb.store.close()
|
||||||
|
|
||||||
|
LegaPersDbRef(rdb: backend.rdb).init(LegacyDbPersistent, backend.trieDB, done)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public helper for direct backend access
|
# Public helper for direct backend access
|
@ -19,13 +19,19 @@ import
|
|||||||
./base/[base_desc, validate]
|
./base/[base_desc, validate]
|
||||||
|
|
||||||
export
|
export
|
||||||
|
CoreDbAccount,
|
||||||
|
CoreDbApiError,
|
||||||
CoreDbBackendRef,
|
CoreDbBackendRef,
|
||||||
CoreDbCaptFlags,
|
CoreDbCaptFlags,
|
||||||
|
CoreDbErrorCode,
|
||||||
CoreDbErrorRef,
|
CoreDbErrorRef,
|
||||||
|
CoreDbAccBackendRef,
|
||||||
CoreDbKvtBackendRef,
|
CoreDbKvtBackendRef,
|
||||||
CoreDbMptBackendRef,
|
CoreDbMptBackendRef,
|
||||||
CoreDbRef,
|
CoreDbRef,
|
||||||
CoreDbType,
|
CoreDbType,
|
||||||
|
CoreDbVidRef,
|
||||||
|
CoreDxAccRef,
|
||||||
CoreDxCaptRef,
|
CoreDxCaptRef,
|
||||||
CoreDxKvtRef,
|
CoreDxKvtRef,
|
||||||
CoreDxMptRef,
|
CoreDxMptRef,
|
||||||
@ -52,7 +58,7 @@ const
|
|||||||
when ProvideCoreDbLegacyAPI:
|
when ProvideCoreDbLegacyAPI:
|
||||||
type
|
type
|
||||||
TxWrapperApiError* = object of CoreDbApiError
|
TxWrapperApiError* = object of CoreDbApiError
|
||||||
## For re-routing exceptions in iterator closure
|
## For re-routing exception on tx/action template
|
||||||
|
|
||||||
CoreDbKvtRef* = distinct CoreDxKvtRef ## Let methods defect on error
|
CoreDbKvtRef* = distinct CoreDxKvtRef ## Let methods defect on error
|
||||||
CoreDbMptRef* = distinct CoreDxMptRef ## ...
|
CoreDbMptRef* = distinct CoreDxMptRef ## ...
|
||||||
@ -61,22 +67,27 @@ when ProvideCoreDbLegacyAPI:
|
|||||||
CoreDbTxID* = distinct CoreDxTxID
|
CoreDbTxID* = distinct CoreDxTxID
|
||||||
CoreDbCaptRef* = distinct CoreDxCaptRef
|
CoreDbCaptRef* = distinct CoreDxCaptRef
|
||||||
|
|
||||||
CoreDbTrieRef* = CoreDbMptRef | CoreDbPhkRef
|
CoreDbTrieRefs* = CoreDbMptRef | CoreDbPhkRef
|
||||||
## Shortcut, *MPT* modules for (legacy API)
|
## Shortcut, *MPT* modules for (legacy API)
|
||||||
|
|
||||||
CoreDbChldRef* = CoreDbKvtRef | CoreDbTrieRef | CoreDbTxRef | CoreDbTxID |
|
CoreDbChldRefs* = CoreDbKvtRef | CoreDbTrieRefs | CoreDbTxRef | CoreDbTxID |
|
||||||
CoreDbCaptRef
|
CoreDbCaptRef
|
||||||
## Shortcut, all modules with a `parent` (for legacy API)
|
## Shortcut, all modules with a `parent` entry (for legacy API)
|
||||||
|
|
||||||
type
|
type
|
||||||
CoreDxTrieRef* = CoreDxMptRef | CoreDxPhkRef
|
CoreDxTrieRefs = CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef
|
||||||
## Shortcut, *MPT* modules
|
## Shortcut, *MPT* descriptors
|
||||||
|
|
||||||
CoreDxChldRef* = CoreDxKvtRef | CoreDxTrieRef | CoreDxTxRef | CoreDxTxID |
|
CoreDxTrieRelated = CoreDxTrieRefs | CoreDxTxRef | CoreDxTxID | CoreDxCaptRef
|
||||||
CoreDxCaptRef |
|
## Shortcut, descriptors for sub-modules running on an *MPT*
|
||||||
CoreDbErrorRef |
|
|
||||||
CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef
|
CoreDbBackends = CoreDbBackendRef | CoreDbKvtBackendRef |
|
||||||
## Shortcut, all modules with a `parent`
|
CoreDbMptBackendRef | CoreDbAccBackendRef
|
||||||
|
## Shortcut, all backend descriptors.
|
||||||
|
|
||||||
|
CoreDxChldRefs = CoreDxKvtRef | CoreDxTrieRelated | CoreDbBackends |
|
||||||
|
CoreDbErrorRef
|
||||||
|
## Shortcut, all descriptors with a `parent` entry.
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private functions: helpers
|
# Private functions: helpers
|
||||||
@ -96,17 +107,17 @@ func toCoreDxPhkRef(mpt: CoreDxMptRef): CoreDxPhkRef =
|
|||||||
fromMpt: mpt,
|
fromMpt: mpt,
|
||||||
methods: mpt.methods)
|
methods: mpt.methods)
|
||||||
|
|
||||||
result.methods.getFn =
|
result.methods.fetchFn =
|
||||||
proc(k: openArray[byte]): CoreDbRc[Blob] =
|
proc(k: openArray[byte]): CoreDbRc[Blob] =
|
||||||
mpt.methods.getFn(k.keccakHash.data)
|
mpt.methods.fetchFn(k.keccakHash.data)
|
||||||
|
|
||||||
result.methods.delFn =
|
result.methods.deleteFn =
|
||||||
proc(k: openArray[byte]): CoreDbRc[void] =
|
proc(k: openArray[byte]): CoreDbRc[void] =
|
||||||
mpt.methods.delFn(k.keccakHash.data)
|
mpt.methods.deleteFn(k.keccakHash.data)
|
||||||
|
|
||||||
result.methods.putFn =
|
result.methods.mergeFn =
|
||||||
proc(k:openArray[byte]; v:openArray[byte]): CoreDbRc[void] =
|
proc(k:openArray[byte]; v: openArray[byte]): CoreDbRc[void] =
|
||||||
mpt.methods.putFn(k.keccakHash.data, v)
|
mpt.methods.mergeFn(k.keccakHash.data, v)
|
||||||
|
|
||||||
result.methods.containsFn =
|
result.methods.containsFn =
|
||||||
proc(k: openArray[byte]): CoreDbRc[bool] =
|
proc(k: openArray[byte]): CoreDbRc[bool] =
|
||||||
@ -128,49 +139,47 @@ func parent(phk: CoreDxPhkRef): CoreDbRef =
|
|||||||
phk.fromMpt.parent
|
phk.fromMpt.parent
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public constructor
|
# Public constructor helper
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
template bless*(db: CoreDbRef; child: untyped): auto =
|
proc bless*(db: CoreDbRef): CoreDbRef =
|
||||||
## Complete sub-module descriptor, fill in `parent`
|
## Verify descriptor
|
||||||
|
when AutoValidateDescriptors:
|
||||||
|
db.validate
|
||||||
|
db
|
||||||
|
|
||||||
|
proc bless*(db: CoreDbRef; child: CoreDbVidRef): CoreDbVidRef =
|
||||||
|
## Complete sub-module descriptor, fill in `parent` and actvate it.
|
||||||
child.parent = db
|
child.parent = db
|
||||||
|
child.ready = true
|
||||||
when AutoValidateDescriptors:
|
when AutoValidateDescriptors:
|
||||||
child.validate
|
child.validate
|
||||||
child
|
child
|
||||||
|
|
||||||
proc init*(
|
proc bless*(db: CoreDbRef; child: CoreDxKvtRef): CoreDxKvtRef =
|
||||||
db: CoreDbRef; # Main descriptor, locally extended
|
## Complete sub-module descriptor, fill in `parent` and de-actvate
|
||||||
dbType: CoreDbType; # Backend symbol
|
## iterator for persistent database.
|
||||||
dbMethods: CoreDbMiscFns; # General methods
|
child.parent = db
|
||||||
kvtMethods: CoreDbKvtFns; # Kvt related methods
|
|
||||||
newSubMod: CoreDbConstructorFns; # Sub-module constructors
|
|
||||||
) =
|
|
||||||
## Base descriptor initaliser
|
|
||||||
db.dbType = dbType
|
|
||||||
db.methods = dbMethods
|
|
||||||
db.new = newSubMod
|
|
||||||
|
|
||||||
db.kvtRef = CoreDxKvtRef(
|
|
||||||
parent: db,
|
|
||||||
methods: kvtMethods)
|
|
||||||
|
|
||||||
# Disable interator for non-memory instances
|
# Disable interator for non-memory instances
|
||||||
if dbType in CoreDbPersistentTypes:
|
if db.dbType in CoreDbPersistentTypes:
|
||||||
db.kvtRef.methods.pairsIt = iterator(): (Blob, Blob) =
|
child.methods.pairsIt = iterator(): (Blob, Blob) =
|
||||||
db.itNotImplemented "pairs/kvt"
|
db.itNotImplemented "pairs/kvt"
|
||||||
|
|
||||||
when AutoValidateDescriptors:
|
when AutoValidateDescriptors:
|
||||||
db.validate
|
child.validate
|
||||||
|
child
|
||||||
|
|
||||||
|
|
||||||
proc newCoreDbCaptRef*(db: CoreDbRef; methods: CoreDbCaptFns): CoreDxCaptRef =
|
proc bless*[T: CoreDxTrieRelated | CoreDbErrorRef | CoreDbBackends](
|
||||||
## Capture constructor helper.
|
db: CoreDbRef;
|
||||||
result = CoreDxCaptRef(
|
child: T;
|
||||||
parent: db,
|
): auto =
|
||||||
methods: methods)
|
## Complete sub-module descriptor, fill in `parent`.
|
||||||
|
child.parent = db
|
||||||
when AutoValidateDescriptors:
|
when AutoValidateDescriptors:
|
||||||
db.validate
|
child.validate
|
||||||
|
child
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public main descriptor methods
|
# Public main descriptor methods
|
||||||
@ -180,32 +189,87 @@ proc dbType*(db: CoreDbRef): CoreDbType =
|
|||||||
## Getter
|
## Getter
|
||||||
db.dbType
|
db.dbType
|
||||||
|
|
||||||
# On the persistent legacy hexary trie, this function is needed for
|
|
||||||
# bootstrapping and Genesis setup when the `purge` flag is activated.
|
|
||||||
proc compensateLegacySetup*(db: CoreDbRef) =
|
proc compensateLegacySetup*(db: CoreDbRef) =
|
||||||
|
## On the persistent legacy hexary trie, this function is needed for
|
||||||
|
## bootstrapping and Genesis setup when the `purge` flag is activated.
|
||||||
|
## Otherwise the database backend may defect on an internal inconsistency.
|
||||||
db.methods.legacySetupFn()
|
db.methods.legacySetupFn()
|
||||||
|
|
||||||
func parent*(cld: CoreDxChldRef): CoreDbRef =
|
func parent*(cld: CoreDxChldRefs): CoreDbRef =
|
||||||
## Getter, common method for all sub-modules
|
## Getter, common method for all sub-modules
|
||||||
cld.parent
|
cld.parent
|
||||||
|
|
||||||
proc backend*(db: CoreDbRef): CoreDbBackendRef =
|
proc backend*(dsc: CoreDxKvtRef | CoreDxTrieRelated | CoreDbRef): auto =
|
||||||
## Getter, retrieves the *raw* backend object for special support.
|
## Getter, retrieves the *raw* backend object for special/localised support.
|
||||||
result = db.methods.backendFn()
|
dsc.methods.backendFn()
|
||||||
result.parent = db
|
|
||||||
|
proc finish*(db: CoreDbRef; flush = false) =
|
||||||
|
## Database destructor. If the argument `flush` is set `false`, the database
|
||||||
|
## is left as-is and only the in-memory handlers are cleaned up.
|
||||||
|
##
|
||||||
|
## Otherwise the destructor is allowed to remove the database. This feature
|
||||||
|
## depends on the backend database. Currently, only the `AristoDbRocks` type
|
||||||
|
## backend removes the database on `true`.
|
||||||
|
db.methods.destroyFn flush
|
||||||
|
|
||||||
proc `$$`*(e: CoreDbErrorRef): string =
|
proc `$$`*(e: CoreDbErrorRef): string =
|
||||||
## Pretty print error symbol, note that this directive may have side effects
|
## Pretty print error symbol, note that this directive may have side effects
|
||||||
## as it calls a backend function.
|
## as it calls a backend function.
|
||||||
e.parent.methods.errorPrintFn(e)
|
e.parent.methods.errorPrintFn(e)
|
||||||
|
|
||||||
|
proc hash*(vid: CoreDbVidRef): Result[Hash256,void] =
|
||||||
|
## Getter (well, sort of), retrieves the hash for a `vid` argument. The
|
||||||
|
## function might fail if there is currently no hash available (e.g. on
|
||||||
|
## `Aristo`.) Note that this is different from succeeding with an
|
||||||
|
## `EMPTY_ROOT_HASH` value.
|
||||||
|
##
|
||||||
|
## The value `EMPTY_ROOT_HASH` is also returned on an empty `vid` argument
|
||||||
|
## `CoreDbVidRef(nil)`, say.
|
||||||
|
##
|
||||||
|
if not vid.isNil and vid.ready:
|
||||||
|
return vid.parent.methods.vidHashFn vid
|
||||||
|
ok EMPTY_ROOT_HASH
|
||||||
|
|
||||||
|
proc recast*(account: CoreDbAccount): Result[Account,void] =
|
||||||
|
## Convert the argument `account` to the portable Ethereum representation
|
||||||
|
## of an account. This conversion may fail if the storage root hash (see
|
||||||
|
## `hash()` above) is currently unavailable.
|
||||||
|
##
|
||||||
|
## Note that for the legacy backend, this function always succeeds.
|
||||||
|
##
|
||||||
|
ok Account(
|
||||||
|
nonce: account.nonce,
|
||||||
|
balance: account.balance,
|
||||||
|
codeHash: account.codeHash,
|
||||||
|
storageRoot: ? account.storageVid.hash)
|
||||||
|
|
||||||
|
proc getRoot*(
|
||||||
|
db: CoreDbRef;
|
||||||
|
root: Hash256;
|
||||||
|
createOk = false;
|
||||||
|
): CoreDbRc[CoreDbVidRef] =
|
||||||
|
## Find root node with argument hash `root` in database and return the
|
||||||
|
## corresponding `CoreDbVidRef` object. If the `root` arguent is set
|
||||||
|
## `EMPTY_CODE_HASH`, this function always succeeds, otherwise it fails
|
||||||
|
## unless a root node with the corresponding hash exists.
|
||||||
|
##
|
||||||
|
## This function is intended to open a virtual accounts trie database as in:
|
||||||
|
## ::
|
||||||
|
## proc openAccountLedger(db: CoreDbRef, rootHash: Hash256): CoreDxMptRef =
|
||||||
|
## let root = db.getRoot(rootHash).isOkOr:
|
||||||
|
## # some error handling
|
||||||
|
## return
|
||||||
|
## db.newAccMpt root
|
||||||
|
##
|
||||||
|
db.methods.getRootFn(root, createOk)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public key-value table methods
|
# Public key-value table methods
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
func toKvt*(db: CoreDbRef): CoreDxKvtRef =
|
proc newKvt*(db: CoreDbRef): CoreDxKvtRef =
|
||||||
## Getter (pseudo constructor)
|
## Getter (pseudo constructor)
|
||||||
db.kvtRef
|
db.methods.newKvtFn()
|
||||||
|
|
||||||
proc get*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] =
|
proc get*(kvt: CoreDxKvtRef; key: openArray[byte]): CoreDbRc[Blob] =
|
||||||
kvt.methods.getFn key
|
kvt.methods.getFn key
|
||||||
@ -228,74 +292,67 @@ iterator pairs*(kvt: CoreDxKvtRef): (Blob, Blob) {.apiRaise.} =
|
|||||||
for k,v in kvt.methods.pairsIt():
|
for k,v in kvt.methods.pairsIt():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
|
|
||||||
proc backend*(kvt: CoreDxKvtRef): CoreDbKvtBackendRef =
|
|
||||||
## Getter, retrieves the *raw* backend object for special support.
|
|
||||||
result = kvt.methods.backendFn()
|
|
||||||
result.parent = kvt.parent
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public Merkle Patricia Tree, hexary trie constructors
|
# Public Merkle Patricia Tree, hexary trie constructors
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc newMpt*(db: CoreDbRef; root=EMPTY_ROOT_HASH): CoreDbRc[CoreDxMptRef] =
|
proc newMpt*(db: CoreDbRef; root: CoreDbVidRef; prune = true): CoreDxMptRef =
|
||||||
## Constructor
|
## Constructor, will defect on failure (note that the legacy backend
|
||||||
db.new.mptFn root
|
## always succeeds)
|
||||||
|
db.methods.newMptFn(root, prune).valueOr: raiseAssert $$error
|
||||||
|
|
||||||
|
proc newAccMpt*(db: CoreDbRef; root: CoreDbVidRef; prune = true): CoreDxAccRef =
|
||||||
|
## Similar to `newMpt()` for handling accounts. Although this sub-trie can
|
||||||
|
## be emulated by means of `newMpt(..).toPhk()`, it is recommended using
|
||||||
|
## this constructor which implies its own subset of methods to handle that
|
||||||
|
## trie.
|
||||||
|
db.methods.newAccFn(root, prune).valueOr: raiseAssert $$error
|
||||||
|
|
||||||
proc toMpt*(phk: CoreDxPhkRef): CoreDxMptRef =
|
proc toMpt*(phk: CoreDxPhkRef): CoreDxMptRef =
|
||||||
## Replaces the pre-hashed argument trie `phk` by the non pre-hashed *MPT*.
|
## Replaces the pre-hashed argument trie `phk` by the non pre-hashed *MPT*.
|
||||||
|
## Note that this does not apply to an accounts trie that was created by
|
||||||
|
## `newAccMpt()`.
|
||||||
phk.fromMpt
|
phk.fromMpt
|
||||||
|
|
||||||
proc toPhk*(mpt: CoreDxMptRef): CoreDxPhkRef =
|
proc toPhk*(mpt: CoreDxMptRef): CoreDxPhkRef =
|
||||||
## Replaces argument `mpt` by a pre-hashed *MPT*.
|
## Replaces argument `mpt` by a pre-hashed *MPT*.
|
||||||
|
## Note that this does not apply to an accounts trie that was created by
|
||||||
|
## `newAaccMpt()`.
|
||||||
mpt.toCoreDxPhkRef
|
mpt.toCoreDxPhkRef
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public hexary trie legacy constructors
|
# Public common methods for all hexary trie databases (`mpt`, `phk`, or `acc`)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc newMptPrune*(
|
proc isPruning*(dsc: CoreDxTrieRefs | CoreDxAccRef): bool =
|
||||||
db: CoreDbRef;
|
|
||||||
root = EMPTY_ROOT_HASH;
|
|
||||||
prune = true;
|
|
||||||
): CoreDbRc[CoreDxMptRef] =
|
|
||||||
## Constructor, `HexaryTrie` compliant
|
|
||||||
db.new.legacyMptFn(root, prune)
|
|
||||||
|
|
||||||
proc newPhkPrune*(
|
|
||||||
db: CoreDbRef;
|
|
||||||
root = EMPTY_ROOT_HASH;
|
|
||||||
prune = true;
|
|
||||||
): CoreDbRc[CoreDxPhkRef] =
|
|
||||||
## Constructor, `SecureHexaryTrie` compliant
|
|
||||||
ok (? db.new.legacyMptFn(root, prune)).toCoreDxPhkRef
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Public hexary trie database methods (`mpt` or `phk`)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
proc isPruning*(trie: CoreDxTrieRef): bool =
|
|
||||||
## Getter
|
## Getter
|
||||||
trie.methods.isPruningFn()
|
dsc.methods.isPruningFn()
|
||||||
|
|
||||||
proc get*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[Blob] =
|
proc rootVid*(dsc: CoreDxTrieRefs | CoreDxAccRef): CoreDbVidRef =
|
||||||
trie.methods.getFn(key)
|
## Getter, result is not `nil`
|
||||||
|
dsc.methods.rootVidFn()
|
||||||
|
|
||||||
proc del*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[void] =
|
# ------------------------------------------------------------------------------
|
||||||
trie.methods.delFn key
|
# Public generic hexary trie database methods (`mpt` or `phk`)
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc put*(
|
proc fetch*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[Blob] =
|
||||||
trie: CoreDxTrieRef;
|
## Fetch data from the argument `trie`
|
||||||
|
trie.methods.fetchFn(key)
|
||||||
|
|
||||||
|
proc delete*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[void] =
|
||||||
|
trie.methods.deleteFn key
|
||||||
|
|
||||||
|
proc merge*(
|
||||||
|
trie: CoreDxTrieRefs;
|
||||||
key: openArray[byte];
|
key: openArray[byte];
|
||||||
value: openArray[byte];
|
value: openArray[byte];
|
||||||
): CoreDbRc[void] =
|
): CoreDbRc[void] =
|
||||||
trie.methods.putFn(key, value)
|
trie.methods.mergeFn(key, value)
|
||||||
|
|
||||||
proc contains*(trie: CoreDxTrieRef; key: openArray[byte]): CoreDbRc[bool] =
|
proc contains*(trie: CoreDxTrieRefs; key: openArray[byte]): CoreDbRc[bool] =
|
||||||
trie.methods.containsFn key
|
trie.methods.containsFn key
|
||||||
|
|
||||||
proc rootHash*(trie: CoreDxTrieRef): CoreDbRc[Hash256] =
|
|
||||||
trie.methods.rootHashFn()
|
|
||||||
|
|
||||||
iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} =
|
iterator pairs*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} =
|
||||||
## Trie traversal, only supported for `CoreDxMptRef`
|
## Trie traversal, only supported for `CoreDxMptRef`
|
||||||
for k,v in mpt.methods.pairsIt():
|
for k,v in mpt.methods.pairsIt():
|
||||||
@ -306,10 +363,26 @@ iterator replicate*(mpt: CoreDxMptRef): (Blob, Blob) {.apiRaise.} =
|
|||||||
for k,v in mpt.methods.replicateIt():
|
for k,v in mpt.methods.replicateIt():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
|
|
||||||
proc backend*(trie: CoreDxTrieRef): CoreDbMptBackendRef =
|
# ------------------------------------------------------------------------------
|
||||||
## Getter, retrieves the *raw* backend object for special support.
|
# Public trie database methods for accounts
|
||||||
result = trie.methods.backendFn()
|
# ------------------------------------------------------------------------------
|
||||||
result.parent = trie.parent
|
|
||||||
|
proc fetch*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[CoreDbAccount] =
|
||||||
|
## Fetch data from the argument `trie`
|
||||||
|
acc.methods.fetchFn address
|
||||||
|
|
||||||
|
proc delete*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[void] =
|
||||||
|
acc.methods.deleteFn address
|
||||||
|
|
||||||
|
proc merge*(
|
||||||
|
acc: CoreDxAccRef;
|
||||||
|
address: EthAddress;
|
||||||
|
account: CoreDbAccount;
|
||||||
|
): CoreDbRc[void] =
|
||||||
|
acc.methods.mergeFn(address, account)
|
||||||
|
|
||||||
|
proc contains*(acc: CoreDxAccRef; address: EthAddress): CoreDbRc[bool] =
|
||||||
|
acc.methods.containsFn address
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public transaction related methods
|
# Public transaction related methods
|
||||||
@ -317,7 +390,7 @@ proc backend*(trie: CoreDxTrieRef): CoreDbMptBackendRef =
|
|||||||
|
|
||||||
proc toTransactionID*(db: CoreDbRef): CoreDbRc[CoreDxTxID] =
|
proc toTransactionID*(db: CoreDbRef): CoreDbRc[CoreDxTxID] =
|
||||||
## Getter, current transaction state
|
## Getter, current transaction state
|
||||||
db.new.getIdFn()
|
db.methods.getIdFn()
|
||||||
|
|
||||||
proc shortTimeReadOnly*(
|
proc shortTimeReadOnly*(
|
||||||
id: CoreDxTxID;
|
id: CoreDxTxID;
|
||||||
@ -329,7 +402,7 @@ proc shortTimeReadOnly*(
|
|||||||
|
|
||||||
proc newTransaction*(db: CoreDbRef): CoreDbRc[CoreDxTxRef] =
|
proc newTransaction*(db: CoreDbRef): CoreDbRc[CoreDxTxRef] =
|
||||||
## Constructor
|
## Constructor
|
||||||
db.new.beginFn()
|
db.methods.beginFn()
|
||||||
|
|
||||||
proc commit*(tx: CoreDxTxRef, applyDeletes = true): CoreDbRc[void] =
|
proc commit*(tx: CoreDxTxRef, applyDeletes = true): CoreDbRc[void] =
|
||||||
tx.methods.commitFn applyDeletes
|
tx.methods.commitFn applyDeletes
|
||||||
@ -352,12 +425,15 @@ proc newCapture*(
|
|||||||
flags: set[CoreDbCaptFlags] = {};
|
flags: set[CoreDbCaptFlags] = {};
|
||||||
): CoreDbRc[CoreDxCaptRef] =
|
): CoreDbRc[CoreDxCaptRef] =
|
||||||
## Constructor
|
## Constructor
|
||||||
db.new.captureFn flags
|
db.methods.captureFn flags
|
||||||
|
|
||||||
proc recorder*(db: CoreDxCaptRef): CoreDbRc[CoreDbRef] =
|
proc recorder*(db: CoreDxCaptRef): CoreDbRc[CoreDbRef] =
|
||||||
## Getter
|
## Getter
|
||||||
db.methods.recorderFn()
|
db.methods.recorderFn()
|
||||||
|
|
||||||
|
proc logDb*(db: CoreDxCaptRef): CoreDbRc[CoreDbRef] =
|
||||||
|
db.methods.logDbFn()
|
||||||
|
|
||||||
proc flags*(db: CoreDxCaptRef): set[CoreDbCaptFlags] =
|
proc flags*(db: CoreDxCaptRef): set[CoreDbCaptFlags] =
|
||||||
## Getter
|
## Getter
|
||||||
db.methods.getFlagsFn()
|
db.methods.getFlagsFn()
|
||||||
@ -368,15 +444,18 @@ proc flags*(db: CoreDxCaptRef): set[CoreDbCaptFlags] =
|
|||||||
|
|
||||||
when ProvideCoreDbLegacyAPI:
|
when ProvideCoreDbLegacyAPI:
|
||||||
|
|
||||||
func parent*(cld: CoreDbChldRef): CoreDbRef =
|
func parent*(cld: CoreDbChldRefs): CoreDbRef =
|
||||||
## Getter, common method for all sub-modules
|
## Getter, common method for all sub-modules
|
||||||
cld.distinctBase.parent()
|
cld.distinctBase.parent()
|
||||||
|
|
||||||
|
proc backend*(dsc: CoreDbChldRefs): auto =
|
||||||
|
dsc.distinctBase.backend
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
func kvt*(db: CoreDbRef): CoreDbKvtRef =
|
proc kvt*(db: CoreDbRef): CoreDbKvtRef =
|
||||||
## Legacy pseudo constructor, see `toKvt()` for production constructor
|
## Legacy pseudo constructor, see `toKvt()` for production constructor
|
||||||
db.toKvt.CoreDbKvtRef
|
db.newKvt().CoreDbKvtRef
|
||||||
|
|
||||||
proc get*(kvt: CoreDbKvtRef; key: openArray[byte]): Blob =
|
proc get*(kvt: CoreDbKvtRef; key: openArray[byte]): Blob =
|
||||||
kvt.distinctBase.get(key).expect "kvt/get()"
|
kvt.distinctBase.get(key).expect "kvt/get()"
|
||||||
@ -394,22 +473,17 @@ when ProvideCoreDbLegacyAPI:
|
|||||||
for k,v in kvt.distinctBase.pairs():
|
for k,v in kvt.distinctBase.pairs():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
|
|
||||||
proc backend*(kvt: CoreDbKvtRef): CoreDbKvtBackendRef =
|
|
||||||
kvt.distinctBase.backend
|
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
proc toMpt*(phk: CoreDbPhkRef): CoreDbMptRef =
|
proc toMpt*(phk: CoreDbPhkRef): CoreDbMptRef =
|
||||||
phk.distinctBase.toMpt.CoreDbMptRef
|
phk.distinctBase.toMpt.CoreDbMptRef
|
||||||
|
|
||||||
proc mpt*(db: CoreDbRef; root=EMPTY_ROOT_HASH): CoreDbMptRef =
|
|
||||||
db.newMpt(root).expect("db/mpt()").CoreDbMptRef
|
|
||||||
|
|
||||||
proc mptPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbMptRef =
|
proc mptPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbMptRef =
|
||||||
db.newMptPrune(root, prune).expect("db/mptPrune()").CoreDbMptRef
|
let vid = db.getRoot(root, createOk=true).expect "mpt/getRoot()"
|
||||||
|
db.newMpt(vid, prune).CoreDbMptRef
|
||||||
|
|
||||||
proc mptPrune*(db: CoreDbRef; prune = true): CoreDbMptRef =
|
proc mptPrune*(db: CoreDbRef; prune = true): CoreDbMptRef =
|
||||||
db.newMptPrune(EMPTY_ROOT_HASH, prune).expect("db/mptPrune()").CoreDbMptRef
|
db.newMpt(CoreDbVidRef(nil), prune).CoreDbMptRef
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
@ -417,48 +491,42 @@ when ProvideCoreDbLegacyAPI:
|
|||||||
mpt.distinctBase.toPhk.CoreDbPhkRef
|
mpt.distinctBase.toPhk.CoreDbPhkRef
|
||||||
|
|
||||||
proc phkPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbPhkRef =
|
proc phkPrune*(db: CoreDbRef; root: Hash256; prune = true): CoreDbPhkRef =
|
||||||
db.newPhkPrune(root, prune).expect("db/phkPrune()").CoreDbPhkRef
|
let vid = db.getRoot(root, createOk=true).expect "phk/getRoot()"
|
||||||
|
db.newMpt(vid, prune).toCoreDxPhkRef.CoreDbPhkRef
|
||||||
|
|
||||||
proc phkPrune*(db: CoreDbRef; prune = true): CoreDbPhkRef =
|
proc phkPrune*(db: CoreDbRef; prune = true): CoreDbPhkRef =
|
||||||
db.newPhkPrune(EMPTY_ROOT_HASH, prune).expect("db/phkPrune()").CoreDbPhkRef
|
db.newMpt(CoreDbVidRef(nil), prune).toCoreDxPhkRef.CoreDbPhkRef
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
proc isPruning*(trie: CoreDbTrieRef): bool =
|
proc isPruning*(trie: CoreDbTrieRefs): bool =
|
||||||
trie.distinctBase.isPruning()
|
trie.distinctBase.isPruning()
|
||||||
|
|
||||||
proc get*(trie: CoreDbTrieRef; key: openArray[byte]): Blob =
|
proc get*(trie: CoreDbTrieRefs; key: openArray[byte]): Blob =
|
||||||
trie.distinctBase.get(key).expect "trie/get()"
|
trie.distinctBase.fetch(key).expect "trie/get()"
|
||||||
|
|
||||||
proc del*(trie: CoreDbTrieRef; key: openArray[byte]) =
|
proc del*(trie: CoreDbTrieRefs; key: openArray[byte]) =
|
||||||
trie.distinctBase.del(key).expect "trie/del()"
|
trie.distinctBase.delete(key).expect "trie/del()"
|
||||||
|
|
||||||
proc put*(
|
proc put*(trie: CoreDbTrieRefs; key: openArray[byte]; val: openArray[byte]) =
|
||||||
trie: CoreDbTrieRef;
|
trie.distinctBase.merge(key, val).expect "trie/put()"
|
||||||
key: openArray[byte];
|
|
||||||
value: openArray[byte];
|
|
||||||
) =
|
|
||||||
trie.distinctBase.put(key, value).expect "trie/put()"
|
|
||||||
|
|
||||||
proc contains*(trie: CoreDbTrieRef; key: openArray[byte]): bool =
|
proc contains*(trie: CoreDbTrieRefs; key: openArray[byte]): bool =
|
||||||
trie.distinctBase.contains(key).expect "trie/contains()"
|
trie.distinctBase.contains(key).expect "trie/contains()"
|
||||||
|
|
||||||
proc rootHash*(trie: CoreDbTrieRef): Hash256 =
|
proc rootHash*(trie: CoreDbTrieRefs): Hash256 =
|
||||||
trie.distinctBase.rootHash().expect "trie/rootHash()"
|
trie.distinctBase.rootVid().hash().expect "trie/rootHash()"
|
||||||
|
|
||||||
iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
|
iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
|
||||||
## Trie traversal, only supported for `CoreDbMptRef`
|
## Trie traversal, not supported for `CoreDbPhkRef`
|
||||||
for k,v in mpt.distinctBase.pairs():
|
for k,v in mpt.distinctBase.pairs():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
|
|
||||||
iterator replicate*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
|
iterator replicate*(mpt: CoreDbMptRef): (Blob, Blob) {.apiRaise.} =
|
||||||
## Low level trie dump, only supported for `CoreDbMptRef`
|
## Low level trie dump, not supported for `CoreDbPhkRef`
|
||||||
for k,v in mpt.distinctBase.replicate():
|
for k,v in mpt.distinctBase.replicate():
|
||||||
yield (k,v)
|
yield (k,v)
|
||||||
|
|
||||||
proc backend*(trie: CoreDbTrieRef): CoreDbMptBackendRef =
|
|
||||||
trie.distinctBase.backend
|
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
proc getTransactionID*(db: CoreDbRef): CoreDbTxID =
|
proc getTransactionID*(db: CoreDbRef): CoreDbTxID =
|
||||||
@ -512,6 +580,9 @@ when ProvideCoreDbLegacyAPI:
|
|||||||
proc recorder*(db: CoreDbCaptRef): CoreDbRef =
|
proc recorder*(db: CoreDbCaptRef): CoreDbRef =
|
||||||
db.distinctBase.recorder().expect("db/recorder()")
|
db.distinctBase.recorder().expect("db/recorder()")
|
||||||
|
|
||||||
|
proc logDb*(db: CoreDbCaptRef): CoreDbRef =
|
||||||
|
db.distinctBase.logDb().expect("db/logDb()")
|
||||||
|
|
||||||
proc flags*(db: CoreDbCaptRef): set[CoreDbCaptFlags] =
|
proc flags*(db: CoreDbCaptRef): set[CoreDbCaptFlags] =
|
||||||
db.distinctBase.flags()
|
db.distinctBase.flags()
|
||||||
|
|
||||||
|
@ -24,57 +24,76 @@ type
|
|||||||
Ooops
|
Ooops
|
||||||
LegacyDbMemory
|
LegacyDbMemory
|
||||||
LegacyDbPersistent
|
LegacyDbPersistent
|
||||||
# AristoDbMemory
|
AristoDbMemory ## Memory backend emulator
|
||||||
# AristoDbPersistent
|
AristoDbRocks ## RocksDB backend
|
||||||
|
AristoDbVoid ## No backend (to be prefered over `XxxDbMemory`)
|
||||||
|
|
||||||
const
|
const
|
||||||
CoreDbPersistentTypes* = {LegacyDbPersistent}
|
CoreDbPersistentTypes* = {LegacyDbPersistent, AristoDbRocks}
|
||||||
|
|
||||||
type
|
type
|
||||||
CoreDbRc*[T] = Result[T,CoreDbErrorRef]
|
CoreDbRc*[T] = Result[T,CoreDbErrorRef]
|
||||||
|
|
||||||
|
CoreDbAccount* = object
|
||||||
|
## Generic account representation referencing an *MPT* sub-trie
|
||||||
|
nonce*: AccountNonce ## Some `uint64` type
|
||||||
|
balance*: UInt256
|
||||||
|
storageVid*: CoreDbVidRef ## Implies storage root sub-MPT
|
||||||
|
codeHash*: Hash256
|
||||||
|
|
||||||
|
CoreDbErrorCode* = enum
|
||||||
|
Unspecified = 0
|
||||||
|
RlpException
|
||||||
|
KvtNotFound
|
||||||
|
MptNotFound
|
||||||
|
RootNotFound
|
||||||
|
|
||||||
CoreDbCaptFlags* {.pure.} = enum
|
CoreDbCaptFlags* {.pure.} = enum
|
||||||
PersistPut
|
PersistPut
|
||||||
PersistDel
|
PersistDel
|
||||||
|
|
||||||
# --------------------------------------------------
|
|
||||||
# Constructors
|
|
||||||
# --------------------------------------------------
|
|
||||||
CoreDbNewMptFn* =
|
|
||||||
proc(root: Hash256): CoreDbRc[CoreDxMptRef] {.noRaise.}
|
|
||||||
CoreDbNewLegaMptFn* =
|
|
||||||
proc(root: Hash256; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.}
|
|
||||||
CoreDbNewTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.}
|
|
||||||
CoreDbNewTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.}
|
|
||||||
CoreDbNewCaptFn* =
|
|
||||||
proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.}
|
|
||||||
|
|
||||||
CoreDbConstructorFns* = object
|
|
||||||
## Constructors
|
|
||||||
|
|
||||||
# Hexary trie
|
|
||||||
mptFn*: CoreDbNewMptFn
|
|
||||||
legacyMptFn*: CoreDbNewLegaMptFn # Legacy handler, should go away
|
|
||||||
|
|
||||||
# Transactions
|
|
||||||
getIdFn*: CoreDbNewTxGetIdFn
|
|
||||||
beginFn*: CoreDbNewTxBeginFn
|
|
||||||
|
|
||||||
# capture/tracer
|
|
||||||
captureFn*: CoreDbNewCaptFn
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# Sub-descriptor: Misc methods for main descriptor
|
# Sub-descriptor: Misc methods for main descriptor
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
CoreDbBackendFn* = proc(): CoreDbBackendRef {.noRaise.}
|
CoreDbBaseBackendFn* = proc(): CoreDbBackendRef {.noRaise.}
|
||||||
CoreDbErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.}
|
CoreDbBaseDestroyFn* = proc(flush = true) {.noRaise.}
|
||||||
CoreDbInitLegaSetupFn* = proc() {.noRaise.}
|
CoreDbBaseVidHashFn* =
|
||||||
|
proc(vid: CoreDbVidRef): Result[Hash256,void] {.noRaise.}
|
||||||
|
CoreDbBaseErrorPrintFn* = proc(e: CoreDbErrorRef): string {.noRaise.}
|
||||||
|
CoreDbBaseInitLegaSetupFn* = proc() {.noRaise.}
|
||||||
|
CoreDbBaseRootFn* =
|
||||||
|
proc(root: Hash256; createOk: bool): CoreDbRc[CoreDbVidRef] {.noRaise.}
|
||||||
|
CoreDbBaseKvtFn* = proc(): CoreDxKvtRef {.noRaise.}
|
||||||
|
CoreDbBaseMptFn* =
|
||||||
|
proc(root: CoreDbVidRef; prune: bool): CoreDbRc[CoreDxMptRef] {.noRaise.}
|
||||||
|
CoreDbBaseAccFn* =
|
||||||
|
proc(root: CoreDbVidRef; prune: bool): CoreDbRc[CoreDxAccRef] {.noRaise.}
|
||||||
|
CoreDbBaseTxGetIdFn* = proc(): CoreDbRc[CoreDxTxID] {.noRaise.}
|
||||||
|
CoreDbBaseTxBeginFn* = proc(): CoreDbRc[CoreDxTxRef] {.noRaise.}
|
||||||
|
CoreDbBaseCaptFn* =
|
||||||
|
proc(flgs: set[CoreDbCaptFlags]): CoreDbRc[CoreDxCaptRef] {.noRaise.}
|
||||||
|
|
||||||
CoreDbMiscFns* = object
|
CoreDbBaseFns* = object
|
||||||
backendFn*: CoreDbBackendFn
|
backendFn*: CoreDbBaseBackendFn
|
||||||
errorPrintFn*: CoreDbErrorPrintFn
|
destroyFn*: CoreDbBaseDestroyFn
|
||||||
legacySetupFn*: CoreDbInitLegaSetupFn
|
vidHashFn*: CoreDbBaseVidHashFn
|
||||||
|
errorPrintFn*: CoreDbBaseErrorPrintFn
|
||||||
|
legacySetupFn*: CoreDbBaseInitLegaSetupFn
|
||||||
|
getRootFn*: CoreDbBaseRootFn
|
||||||
|
|
||||||
|
# Kvt constructor
|
||||||
|
newKvtFn*: CoreDbBaseKvtFn
|
||||||
|
|
||||||
|
# Hexary trie constructors
|
||||||
|
newMptFn*: CoreDbBaseMptFn
|
||||||
|
newAccFn*: CoreDbBaseAccFn
|
||||||
|
|
||||||
|
# Transactions constructors
|
||||||
|
getIdFn*: CoreDbBaseTxGetIdFn
|
||||||
|
beginFn*: CoreDbBaseTxBeginFn
|
||||||
|
|
||||||
|
# capture/tracer constructors
|
||||||
|
captureFn*: CoreDbBaseCaptFn
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
@ -99,32 +118,59 @@ type
|
|||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# Sub-descriptor: Mpt/hexary trie methods
|
# Sub-descriptor: generic Mpt/hexary trie methods
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
CoreDbMptBackendFn* = proc(): CoreDbMptBackendRef {.noRaise.}
|
CoreDbMptBackendFn* = proc(): CoreDbMptBackendRef {.noRaise.}
|
||||||
CoreDbMptGetFn* =
|
CoreDbMptFetchFn* =
|
||||||
proc(k: openArray[byte]): CoreDbRc[Blob] {.noRaise.}
|
proc(k: openArray[byte]): CoreDbRc[Blob] {.noRaise.}
|
||||||
CoreDbMptDelFn* =
|
CoreDbMptFetchAccountFn* =
|
||||||
|
proc(k: openArray[byte]): CoreDbRc[CoreDbAccount] {.noRaise.}
|
||||||
|
CoreDbMptDeleteFn* =
|
||||||
proc(k: openArray[byte]): CoreDbRc[void] {.noRaise.}
|
proc(k: openArray[byte]): CoreDbRc[void] {.noRaise.}
|
||||||
CoreDbMptPutFn* =
|
CoreDbMptMergeFn* =
|
||||||
proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void ] {.noRaise.}
|
proc(k: openArray[byte]; v: openArray[byte]): CoreDbRc[void] {.noRaise.}
|
||||||
|
CoreDbMptMergeAccountFn* =
|
||||||
|
proc(k: openArray[byte]; v: CoreDbAccount): CoreDbRc[void] {.noRaise.}
|
||||||
CoreDbMptContainsFn* = proc(k: openArray[byte]): CoreDbRc[bool] {.noRaise.}
|
CoreDbMptContainsFn* = proc(k: openArray[byte]): CoreDbRc[bool] {.noRaise.}
|
||||||
CoreDbMptRootHashFn* = proc(): CoreDbRc[Hash256] {.noRaise.}
|
CoreDbMptRootVidFn* = proc(): CoreDbVidRef {.noRaise.}
|
||||||
CoreDbMptIsPruningFn* = proc(): bool {.noRaise.}
|
CoreDbMptIsPruningFn* = proc(): bool {.noRaise.}
|
||||||
CoreDbMptPairsIt* = iterator(): (Blob,Blob) {.apiRaise.}
|
CoreDbMptPairsIt* = iterator(): (Blob,Blob) {.apiRaise.}
|
||||||
CoreDbMptReplicateIt* = iterator(): (Blob,Blob) {.apiRaise.}
|
CoreDbMptReplicateIt* = iterator(): (Blob,Blob) {.apiRaise.}
|
||||||
|
|
||||||
CoreDbMptFns* = object
|
CoreDbMptFns* = object
|
||||||
## Methods for trie objects
|
## Methods for trie objects
|
||||||
backendFn*: CoreDbMptBackendFn
|
backendFn*: CoreDbMptBackendFn
|
||||||
getFn*: CoreDbMptGetFn
|
fetchFn*: CoreDbMptFetchFn
|
||||||
delFn*: CoreDbMptDelFn
|
deleteFn*: CoreDbMptDeleteFn
|
||||||
putFn*: CoreDbMptPutFn
|
mergeFn*: CoreDbMptMergeFn
|
||||||
containsFn*: CoreDbMptContainsFn
|
containsFn*: CoreDbMptContainsFn
|
||||||
rootHashFn*: CoreDbMptRootHashFn
|
rootVidFn*: CoreDbMptRootVidFn
|
||||||
pairsIt*: CoreDbMptPairsIt
|
pairsIt*: CoreDbMptPairsIt
|
||||||
replicateIt*: CoreDbMptReplicateIt
|
replicateIt*: CoreDbMptReplicateIt
|
||||||
isPruningFn*: CoreDbMptIsPruningFn # Legacy handler, should go away
|
isPruningFn*: CoreDbMptIsPruningFn
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# Sub-descriptor: Mpt/hexary trie methods for accounts
|
||||||
|
# ------------------------------------------------------
|
||||||
|
CoreDbAccBackendFn* = proc(): CoreDbAccBackendRef {.noRaise.}
|
||||||
|
CoreDbAccFetchFn* = proc(k: EthAddress): CoreDbRc[CoreDbAccount] {.noRaise.}
|
||||||
|
CoreDbAccDeleteFn* = proc(k: EthAddress): CoreDbRc[void] {.noRaise.}
|
||||||
|
CoreDbAccMergeFn* =
|
||||||
|
proc(k: EthAddress; v: CoreDbAccount): CoreDbRc[void] {.noRaise.}
|
||||||
|
CoreDbAccContainsFn* = proc(k: EthAddress): CoreDbRc[bool] {.noRaise.}
|
||||||
|
CoreDbAccRootVidFn* = proc(): CoreDbVidRef {.noRaise.}
|
||||||
|
CoreDbAccIsPruningFn* = proc(): bool {.noRaise.}
|
||||||
|
|
||||||
|
CoreDbAccFns* = object
|
||||||
|
## Methods for trie objects
|
||||||
|
backendFn*: CoreDbAccBackendFn
|
||||||
|
fetchFn*: CoreDbAccFetchFn
|
||||||
|
deleteFn*: CoreDbAccDeleteFn
|
||||||
|
mergeFn*: CoreDbAccMergeFn
|
||||||
|
containsFn*: CoreDbAccContainsFn
|
||||||
|
rootVidFn*: CoreDbAccRootVidFn
|
||||||
|
isPruningFn*: CoreDbAccIsPruningFn
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
@ -156,10 +202,12 @@ type
|
|||||||
# Sub-descriptor: capture recorder methods
|
# Sub-descriptor: capture recorder methods
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
CoreDbCaptRecorderFn* = proc(): CoreDbRc[CoreDbRef] {.noRaise.}
|
CoreDbCaptRecorderFn* = proc(): CoreDbRc[CoreDbRef] {.noRaise.}
|
||||||
|
CoreDbCaptLogDbFn* = proc(): CoreDbRc[CoreDbRef] {.noRaise.}
|
||||||
CoreDbCaptFlagsFn* = proc(): set[CoreDbCaptFlags] {.noRaise.}
|
CoreDbCaptFlagsFn* = proc(): set[CoreDbCaptFlags] {.noRaise.}
|
||||||
|
|
||||||
CoreDbCaptFns* = object
|
CoreDbCaptFns* = object
|
||||||
recorderFn*: CoreDbCaptRecorderFn
|
recorderFn*: CoreDbCaptRecorderFn
|
||||||
|
logDbFn*: CoreDbCaptLogDbFn
|
||||||
getFlagsFn*: CoreDbCaptFlagsFn
|
getFlagsFn*: CoreDbCaptFlagsFn
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
@ -168,12 +216,11 @@ type
|
|||||||
CoreDbRef* = ref object of RootRef
|
CoreDbRef* = ref object of RootRef
|
||||||
## Database descriptor
|
## Database descriptor
|
||||||
dbType*: CoreDbType
|
dbType*: CoreDbType
|
||||||
kvtRef*: CoreDxKvtRef
|
methods*: CoreDbBaseFns
|
||||||
new*: CoreDbConstructorFns
|
|
||||||
methods*: CoreDbMiscFns
|
|
||||||
|
|
||||||
CoreDbErrorRef* = ref object of RootRef
|
CoreDbErrorRef* = ref object of RootRef
|
||||||
## Generic error object
|
## Generic error object
|
||||||
|
error*: CoreDbErrorCode
|
||||||
parent*: CoreDbRef
|
parent*: CoreDbRef
|
||||||
|
|
||||||
CoreDbBackendRef* = ref object of RootRef
|
CoreDbBackendRef* = ref object of RootRef
|
||||||
@ -188,6 +235,10 @@ type
|
|||||||
## Backend wrapper for direct backend access
|
## Backend wrapper for direct backend access
|
||||||
parent*: CoreDbRef
|
parent*: CoreDbRef
|
||||||
|
|
||||||
|
CoreDbAccBackendRef* = ref object of RootRef
|
||||||
|
## Backend wrapper for direct backend access
|
||||||
|
parent*: CoreDbRef
|
||||||
|
|
||||||
CoreDxKvtRef* = ref object
|
CoreDxKvtRef* = ref object
|
||||||
## Statically initialised Key-Value pair table living in `CoreDbRef`
|
## Statically initialised Key-Value pair table living in `CoreDbRef`
|
||||||
parent*: CoreDbRef
|
parent*: CoreDbRef
|
||||||
@ -199,10 +250,22 @@ type
|
|||||||
parent*: CoreDbRef
|
parent*: CoreDbRef
|
||||||
methods*: CoreDbMptFns
|
methods*: CoreDbMptFns
|
||||||
|
|
||||||
|
CoreDxAccRef* = ref object
|
||||||
|
## Similar to `CoreDxKvtRef`, only dealing with `CoreDbAccount` data
|
||||||
|
## rather than `Blob` values.
|
||||||
|
parent*: CoreDbRef
|
||||||
|
methods*: CoreDbAccFns
|
||||||
|
|
||||||
|
CoreDbVidRef* = ref object of RootRef
|
||||||
|
## Generic state root: `Hash256` for legacy, `VertexID` for Aristo. This
|
||||||
|
## object makes only sense in the context od an *MPT*.
|
||||||
|
parent*: CoreDbRef
|
||||||
|
ready*: bool ## Must be set `true` to enable
|
||||||
|
|
||||||
CoreDxPhkRef* = ref object
|
CoreDxPhkRef* = ref object
|
||||||
## Similar to `CoreDbMptRef` but with pre-hashed keys. That is, any
|
## Similar to `CoreDbMptRef` but with pre-hashed keys. That is, any
|
||||||
## argument key for `put()`, `get()` etc. will be hashed first before
|
## argument key for `merge()`, `fetch()` etc. will be hashed first
|
||||||
## being applied.
|
## before being applied.
|
||||||
fromMpt*: CoreDxMptRef
|
fromMpt*: CoreDxMptRef
|
||||||
methods*: CoreDbMptFns
|
methods*: CoreDbMptFns
|
||||||
|
|
||||||
|
@ -14,22 +14,34 @@ import
|
|||||||
|
|
||||||
type
|
type
|
||||||
EphemMethodsDesc =
|
EphemMethodsDesc =
|
||||||
CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef
|
CoreDbBackendRef | CoreDbKvtBackendRef | CoreDbMptBackendRef |
|
||||||
|
CoreDbAccBackendRef | CoreDbVidRef
|
||||||
|
|
||||||
MethodsDesc =
|
MethodsDesc =
|
||||||
CoreDxKvtRef |
|
CoreDxKvtRef |
|
||||||
CoreDxMptRef | CoreDxPhkRef |
|
CoreDxMptRef | CoreDxPhkRef | CoreDxAccRef |
|
||||||
CoreDxTxRef | CoreDxTxID |
|
CoreDxTxRef | CoreDxTxID |
|
||||||
CoreDxCaptRef
|
CoreDxCaptRef
|
||||||
|
|
||||||
|
ValidateDesc* = MethodsDesc | EphemMethodsDesc | CoreDbErrorRef
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private helpers
|
# Private helpers
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc validateMethodsDesc(msc: CoreDbMiscFns) =
|
proc validateMethodsDesc(base: CoreDbBaseFns) =
|
||||||
doAssert not msc.backendFn.isNil
|
doAssert not base.backendFn.isNil
|
||||||
doAssert not msc.errorPrintFn.isNil
|
doAssert not base.destroyFn.isNil
|
||||||
doAssert not msc.legacySetupFn.isNil
|
doAssert not base.vidHashFn.isNil
|
||||||
|
doAssert not base.errorPrintFn.isNil
|
||||||
|
doAssert not base.legacySetupFn.isNil
|
||||||
|
doAssert not base.getRootFn.isNil
|
||||||
|
doAssert not base.newKvtFn.isNil
|
||||||
|
doAssert not base.newMptFn.isNil
|
||||||
|
doAssert not base.newAccFn.isNil
|
||||||
|
doAssert not base.getIdFn.isNil
|
||||||
|
doAssert not base.beginFn.isNil
|
||||||
|
doAssert not base.captureFn.isNil
|
||||||
|
|
||||||
proc validateMethodsDesc(kvt: CoreDbKvtFns) =
|
proc validateMethodsDesc(kvt: CoreDbKvtFns) =
|
||||||
doAssert not kvt.backendFn.isNil
|
doAssert not kvt.backendFn.isNil
|
||||||
@ -41,24 +53,31 @@ proc validateMethodsDesc(kvt: CoreDbKvtFns) =
|
|||||||
|
|
||||||
proc validateMethodsDesc(fns: CoreDbMptFns) =
|
proc validateMethodsDesc(fns: CoreDbMptFns) =
|
||||||
doAssert not fns.backendFn.isNil
|
doAssert not fns.backendFn.isNil
|
||||||
doAssert not fns.getFn.isNil
|
doAssert not fns.fetchFn.isNil
|
||||||
doAssert not fns.delFn.isNil
|
doAssert not fns.deleteFn.isNil
|
||||||
doAssert not fns.putFn.isNil
|
doAssert not fns.mergeFn.isNil
|
||||||
doAssert not fns.containsFn.isNil
|
doAssert not fns.containsFn.isNil
|
||||||
doAssert not fns.rootHashFn.isNil
|
doAssert not fns.rootVidFn.isNil
|
||||||
doAssert not fns.isPruningFn.isNil
|
doAssert not fns.isPruningFn.isNil
|
||||||
doAssert not fns.pairsIt.isNil
|
doAssert not fns.pairsIt.isNil
|
||||||
doAssert not fns.replicateIt.isNil
|
doAssert not fns.replicateIt.isNil
|
||||||
|
|
||||||
proc validateConstructors(new: CoreDbConstructorFns) =
|
proc validateMethodsDesc(fns: CoreDbAccFns) =
|
||||||
doAssert not new.mptFn.isNil
|
doAssert not fns.backendFn.isNil
|
||||||
doAssert not new.legacyMptFn.isNil
|
doAssert not fns.fetchFn.isNil
|
||||||
doAssert not new.getIdFn.isNil
|
doAssert not fns.deleteFn.isNil
|
||||||
doAssert not new.beginFn.isNil
|
doAssert not fns.mergeFn.isNil
|
||||||
doAssert not new.captureFn.isNil
|
doAssert not fns.containsFn.isNil
|
||||||
|
doAssert not fns.rootVidFn.isNil
|
||||||
|
doAssert not fns.isPruningFn.isNil
|
||||||
|
|
||||||
# ------------
|
# ------------
|
||||||
|
|
||||||
|
proc validateMethodsDesc(vid: CoreDbVidRef) =
|
||||||
|
doAssert not vid.isNil
|
||||||
|
doAssert not vid.parent.isNil
|
||||||
|
doAssert vid.ready == true
|
||||||
|
|
||||||
proc validateMethodsDesc(e: CoreDbErrorRef) =
|
proc validateMethodsDesc(e: CoreDbErrorRef) =
|
||||||
doAssert not e.isNil
|
doAssert not e.isNil
|
||||||
doAssert not e.parent.isNil
|
doAssert not e.parent.isNil
|
||||||
@ -66,7 +85,7 @@ proc validateMethodsDesc(e: CoreDbErrorRef) =
|
|||||||
proc validateMethodsDesc(eph: EphemMethodsDesc) =
|
proc validateMethodsDesc(eph: EphemMethodsDesc) =
|
||||||
doAssert not eph.isNil
|
doAssert not eph.isNil
|
||||||
doAssert not eph.parent.isNil
|
doAssert not eph.parent.isNil
|
||||||
|
|
||||||
proc validateMethodsDesc(kvt: CoreDxKvtRef) =
|
proc validateMethodsDesc(kvt: CoreDxKvtRef) =
|
||||||
doAssert not kvt.isNil
|
doAssert not kvt.isNil
|
||||||
doAssert not kvt.parent.isNil
|
doAssert not kvt.parent.isNil
|
||||||
@ -77,6 +96,11 @@ proc validateMethodsDesc(mpt: CoreDxMptRef) =
|
|||||||
doAssert not mpt.parent.isNil
|
doAssert not mpt.parent.isNil
|
||||||
mpt.methods.validateMethodsDesc
|
mpt.methods.validateMethodsDesc
|
||||||
|
|
||||||
|
proc validateMethodsDesc(acc: CoreDxAccRef) =
|
||||||
|
doAssert not acc.isNil
|
||||||
|
doAssert not acc.parent.isNil
|
||||||
|
acc.methods.validateMethodsDesc
|
||||||
|
|
||||||
proc validateMethodsDesc(phk: CoreDxPhkRef) =
|
proc validateMethodsDesc(phk: CoreDxPhkRef) =
|
||||||
doAssert not phk.isNil
|
doAssert not phk.isNil
|
||||||
doAssert not phk.fromMpt.isNil
|
doAssert not phk.fromMpt.isNil
|
||||||
@ -104,16 +128,14 @@ proc validateMethodsDesc(id: CoreDxTxID) =
|
|||||||
proc validateMethodsDesc(db: CoreDbRef) =
|
proc validateMethodsDesc(db: CoreDbRef) =
|
||||||
doAssert not db.isNil
|
doAssert not db.isNil
|
||||||
doAssert db.dbType != CoreDbType(0)
|
doAssert db.dbType != CoreDbType(0)
|
||||||
db.kvtRef.validateMethodsDesc
|
|
||||||
db.new.validateConstructors
|
|
||||||
db.methods.validateMethodsDesc
|
db.methods.validateMethodsDesc
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public debugging helpers
|
# Public debugging helpers
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc validate*(desc: MethodsDesc | EphemMethodsDesc | CoreDbErrorRef) =
|
proc validate*(dsc: ValidateDesc) =
|
||||||
desc.validateMethodsDesc
|
dsc.validateMethodsDesc
|
||||||
|
|
||||||
proc validate*(db: CoreDbRef) =
|
proc validate*(db: CoreDbRef) =
|
||||||
db.validateMethodsDesc
|
db.validateMethodsDesc
|
||||||
|
@ -13,14 +13,18 @@
|
|||||||
import
|
import
|
||||||
std/options,
|
std/options,
|
||||||
eth/[common, trie/db],
|
eth/[common, trie/db],
|
||||||
"."/[base, core_apps, legacy_db]
|
./backend/[legacy_db],
|
||||||
|
"."/[base, core_apps]
|
||||||
|
|
||||||
export
|
export
|
||||||
common,
|
common,
|
||||||
core_apps,
|
core_apps,
|
||||||
|
|
||||||
# Not all symbols from the object sources will be exported by default
|
# Not all symbols from the object sources will be exported by default
|
||||||
|
CoreDbAccount,
|
||||||
|
CoreDbApiError,
|
||||||
CoreDbCaptFlags,
|
CoreDbCaptFlags,
|
||||||
|
CoreDbErrorCode,
|
||||||
CoreDbErrorRef,
|
CoreDbErrorRef,
|
||||||
CoreDbCaptRef,
|
CoreDbCaptRef,
|
||||||
CoreDbKvtRef,
|
CoreDbKvtRef,
|
||||||
@ -30,6 +34,8 @@ export
|
|||||||
CoreDbTxID,
|
CoreDbTxID,
|
||||||
CoreDbTxRef,
|
CoreDbTxRef,
|
||||||
CoreDbType,
|
CoreDbType,
|
||||||
|
CoreDbVidRef,
|
||||||
|
CoreDxAccRef,
|
||||||
CoreDxCaptRef,
|
CoreDxCaptRef,
|
||||||
CoreDxKvtRef,
|
CoreDxKvtRef,
|
||||||
CoreDxMptRef,
|
CoreDxMptRef,
|
||||||
@ -44,26 +50,34 @@ export
|
|||||||
contains,
|
contains,
|
||||||
dbType,
|
dbType,
|
||||||
del,
|
del,
|
||||||
|
delete,
|
||||||
dispose,
|
dispose,
|
||||||
|
fetch,
|
||||||
|
finish,
|
||||||
get,
|
get,
|
||||||
|
getRoot,
|
||||||
getTransactionID,
|
getTransactionID,
|
||||||
|
hash,
|
||||||
isLegacy,
|
isLegacy,
|
||||||
isPruning,
|
isPruning,
|
||||||
kvt,
|
kvt,
|
||||||
|
logDb,
|
||||||
|
merge,
|
||||||
mptPrune,
|
mptPrune,
|
||||||
|
newAccMpt,
|
||||||
newCapture,
|
newCapture,
|
||||||
newMpt,
|
newMpt,
|
||||||
newMptPrune,
|
|
||||||
newPhkPrune,
|
|
||||||
newTransaction,
|
newTransaction,
|
||||||
pairs,
|
pairs,
|
||||||
parent,
|
parent,
|
||||||
phkPrune,
|
phkPrune,
|
||||||
put,
|
put,
|
||||||
|
recast,
|
||||||
recorder,
|
recorder,
|
||||||
replicate,
|
replicate,
|
||||||
rollback,
|
rollback,
|
||||||
rootHash,
|
rootHash,
|
||||||
|
rootVid,
|
||||||
safeDispose,
|
safeDispose,
|
||||||
setTransactionID,
|
setTransactionID,
|
||||||
toLegacy,
|
toLegacy,
|
||||||
@ -86,7 +100,9 @@ proc newCoreDbRef*(
|
|||||||
##
|
##
|
||||||
db.newLegacyPersistentCoreDbRef()
|
db.newLegacyPersistentCoreDbRef()
|
||||||
|
|
||||||
proc newCoreDbRef*(dbType: static[CoreDbType]): CoreDbRef =
|
proc newCoreDbRef*(
|
||||||
|
dbType: static[CoreDbType]; # Database type symbol
|
||||||
|
): CoreDbRef =
|
||||||
## Constructor for volatile/memory type DB
|
## Constructor for volatile/memory type DB
|
||||||
##
|
##
|
||||||
## Note: Using legacy notation `newCoreDbRef()` rather than
|
## Note: Using legacy notation `newCoreDbRef()` rather than
|
||||||
@ -96,7 +112,7 @@ proc newCoreDbRef*(dbType: static[CoreDbType]): CoreDbRef =
|
|||||||
newLegacyMemoryCoreDbRef()
|
newLegacyMemoryCoreDbRef()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
{.error: "Unsupported dbType for memory newCoreDbRef()".}
|
{.error: "Unsupported dbType for memory-only newCoreDbRef()".}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public template wrappers
|
# Public template wrappers
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# at your option. This file may not be copied, modified, or distributed except
|
# at your option. This file may not be copied, modified, or distributed except
|
||||||
# according to those terms.
|
# according to those terms.
|
||||||
|
|
||||||
## This module automatically pulls in the persistent backend library at the
|
## This module automatically pulls in the persistent backend libraries at the
|
||||||
## linking stage (e.g. `rocksdb`) which can be avoided for pure memory DB
|
## linking stage (e.g. `rocksdb`) which can be avoided for pure memory DB
|
||||||
## applications by importing `db/code_db/memory_only` (rather than
|
## applications by importing `db/code_db/memory_only` (rather than
|
||||||
## `db/core_db/persistent`.)
|
## `db/core_db/persistent`.)
|
||||||
@ -13,12 +13,18 @@
|
|||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
import
|
import
|
||||||
"."/[memory_only, legacy_rocksdb]
|
../aristo,
|
||||||
|
./backend/[legacy_rocksdb],
|
||||||
|
./memory_only
|
||||||
|
|
||||||
export
|
export
|
||||||
memory_only
|
memory_only,
|
||||||
|
toRocksStoreRef
|
||||||
|
|
||||||
proc newCoreDbRef*(dbType: static[CoreDbType]; path: string): CoreDbRef =
|
proc newCoreDbRef*(
|
||||||
|
dbType: static[CoreDbType]; # Database type symbol
|
||||||
|
path: string; # Storage path for database
|
||||||
|
): CoreDbRef =
|
||||||
## Constructor for persistent type DB
|
## Constructor for persistent type DB
|
||||||
##
|
##
|
||||||
## Note: Using legacy notation `newCoreDbRef()` rather than
|
## Note: Using legacy notation `newCoreDbRef()` rather than
|
||||||
@ -26,6 +32,9 @@ proc newCoreDbRef*(dbType: static[CoreDbType]; path: string): CoreDbRef =
|
|||||||
when dbType == LegacyDbPersistent:
|
when dbType == LegacyDbPersistent:
|
||||||
newLegacyPersistentCoreDbRef path
|
newLegacyPersistentCoreDbRef path
|
||||||
|
|
||||||
|
elif dbType == AristoDbRocks:
|
||||||
|
newAristoRocksDbCoreDbRef path
|
||||||
|
|
||||||
else:
|
else:
|
||||||
{.error: "Unsupported dbType for persistent newCoreDbRef()".}
|
{.error: "Unsupported dbType for persistent newCoreDbRef()".}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ proc pruneTrie*(db: AccountStateDB): bool =
|
|||||||
func db*(db: AccountStateDB): CoreDbRef =
|
func db*(db: AccountStateDB): CoreDbRef =
|
||||||
db.trie.db
|
db.trie.db
|
||||||
|
|
||||||
func kvt*(db: AccountStateDB): CoreDbKvtRef =
|
proc kvt*(db: AccountStateDB): CoreDbKvtRef =
|
||||||
db.trie.db.kvt
|
db.trie.db.kvt
|
||||||
|
|
||||||
proc rootHash*(db: AccountStateDB): KeccakHash =
|
proc rootHash*(db: AccountStateDB): KeccakHash =
|
||||||
|
@ -121,7 +121,7 @@ proc afterExecCall(c: Computation) =
|
|||||||
## also see: https://github.com/ethereum/EIPs/issues/716
|
## also see: https://github.com/ethereum/EIPs/issues/716
|
||||||
|
|
||||||
if c.isError or c.fork >= FkByzantium:
|
if c.isError or c.fork >= FkByzantium:
|
||||||
if c.msg.contractAddress == ripemdAddr:
|
if c.msg.contractAddress == RIPEMD_ADDR:
|
||||||
# Special case to account for geth+parity bug
|
# Special case to account for geth+parity bug
|
||||||
c.vmState.stateDB.ripemdSpecial()
|
c.vmState.stateDB.ripemdSpecial()
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import
|
|||||||
eth/[common, p2p, trie/db, trie/nibbles],
|
eth/[common, p2p, trie/db, trie/nibbles],
|
||||||
stew/[byteutils, interval_set],
|
stew/[byteutils, interval_set],
|
||||||
../../core/chain,
|
../../core/chain,
|
||||||
../../db/core_db/legacy_db,
|
../../db/core_db,
|
||||||
../snap/[constants, range_desc],
|
../snap/[constants, range_desc],
|
||||||
../snap/worker/db/[hexary_desc, hexary_error, hexary_paths,
|
../snap/worker/db/[hexary_desc, hexary_error, hexary_paths,
|
||||||
snapdb_persistent, hexary_range],
|
snapdb_persistent, hexary_range],
|
||||||
|
@ -14,7 +14,7 @@ import
|
|||||||
std/tables,
|
std/tables,
|
||||||
chronicles,
|
chronicles,
|
||||||
eth/[common, p2p, trie/nibbles],
|
eth/[common, p2p, trie/nibbles],
|
||||||
../../../../db/core_db/legacy_rocksdb,
|
../../../../db/core_db/persistent,
|
||||||
../../../../db/[core_db, select_backend, storage_types],
|
../../../../db/[core_db, select_backend, storage_types],
|
||||||
../../../protocol,
|
../../../protocol,
|
||||||
../../range_desc,
|
../../range_desc,
|
||||||
|
@ -14,7 +14,8 @@ import
|
|||||||
std/[algorithm, tables],
|
std/[algorithm, tables],
|
||||||
chronicles,
|
chronicles,
|
||||||
eth/[common, trie/db],
|
eth/[common, trie/db],
|
||||||
../../../../db/[core_db, core_db/legacy_db, kvstore_rocksdb],
|
results,
|
||||||
|
../../../../db/[core_db, kvstore_rocksdb],
|
||||||
../../range_desc,
|
../../range_desc,
|
||||||
"."/[hexary_desc, hexary_error, rocky_bulk_load, snapdb_desc]
|
"."/[hexary_desc, hexary_error, rocky_bulk_load, snapdb_desc]
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ proc dumpMemoryDB*(node: JsonNode, db: CoreDbRef) =
|
|||||||
node["state"] = n
|
node["state"] = n
|
||||||
|
|
||||||
proc dumpMemoryDB*(node: JsonNode, capture: CoreDbCaptRef) =
|
proc dumpMemoryDB*(node: JsonNode, capture: CoreDbCaptRef) =
|
||||||
node.dumpMemoryDB capture.recorder
|
node.dumpMemoryDB capture.logDb
|
||||||
|
|
||||||
const
|
const
|
||||||
senderName = "sender"
|
senderName = "sender"
|
||||||
|
50
tests/replay/xcheck.nim
Normal file
50
tests/replay/xcheck.nim
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Nimbus - Types, data structures and shared utilities used in network sync
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018-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.
|
||||||
|
|
||||||
|
import
|
||||||
|
unittest2
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Public workflow helpers
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template xCheck*(expr: untyped): untyped =
|
||||||
|
## Note: this check will invoke `expr` twice
|
||||||
|
if not (expr):
|
||||||
|
check expr
|
||||||
|
return
|
||||||
|
|
||||||
|
template xCheck*(expr: untyped; ifFalse: untyped): untyped =
|
||||||
|
## Note: this check will invoke `expr` twice
|
||||||
|
if not (expr):
|
||||||
|
ifFalse
|
||||||
|
check expr
|
||||||
|
return
|
||||||
|
|
||||||
|
template xCheckRc*(expr: untyped): untyped =
|
||||||
|
if rc.isErr:
|
||||||
|
xCheck(expr)
|
||||||
|
|
||||||
|
template xCheckRc*(expr: untyped; ifFalse: untyped): untyped =
|
||||||
|
if rc.isErr:
|
||||||
|
xCheck(expr, ifFalse)
|
||||||
|
|
||||||
|
template xCheckErr*(expr: untyped): untyped =
|
||||||
|
if rc.isOk:
|
||||||
|
xCheck(expr)
|
||||||
|
|
||||||
|
template xCheckErr*(expr: untyped; ifFalse: untyped): untyped =
|
||||||
|
if rc.isOk:
|
||||||
|
xCheck(expr, ifFalse)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# End
|
||||||
|
# ------------------------------------------------------------------------------
|
@ -28,6 +28,7 @@ import
|
|||||||
aristo_persistent,
|
aristo_persistent,
|
||||||
aristo_transcode,
|
aristo_transcode,
|
||||||
aristo_vid],
|
aristo_vid],
|
||||||
|
../replay/xcheck,
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -23,6 +23,7 @@ import
|
|||||||
../../nimbus/db/aristo,
|
../../nimbus/db/aristo,
|
||||||
../../nimbus/db/aristo/aristo_desc/desc_backend,
|
../../nimbus/db/aristo/aristo_desc/desc_backend,
|
||||||
../../nimbus/db/aristo/aristo_filter/[filter_fifos, filter_scheduler],
|
../../nimbus/db/aristo/aristo_filter/[filter_fifos, filter_scheduler],
|
||||||
|
../replay/xcheck,
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -192,39 +192,6 @@ proc mapRootVid*(
|
|||||||
leafTie: LeafTie(root: toVid, path: it.leafTie.path),
|
leafTie: LeafTie(root: toVid, path: it.leafTie.path),
|
||||||
payload: it.payload))
|
payload: it.payload))
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Public workflow helpers
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template xCheck*(expr: untyped): untyped =
|
|
||||||
## Note: this check will invoke `expr` twice
|
|
||||||
if not (expr):
|
|
||||||
check expr
|
|
||||||
return
|
|
||||||
|
|
||||||
template xCheck*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
## Note: this check will invoke `expr` twice
|
|
||||||
if not (expr):
|
|
||||||
ifFalse
|
|
||||||
check expr
|
|
||||||
return
|
|
||||||
|
|
||||||
template xCheckRc*(expr: untyped): untyped =
|
|
||||||
if rc.isErr:
|
|
||||||
xCheck(expr)
|
|
||||||
|
|
||||||
template xCheckRc*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
if rc.isErr:
|
|
||||||
xCheck(expr, ifFalse)
|
|
||||||
|
|
||||||
template xCheckErr*(expr: untyped): untyped =
|
|
||||||
if rc.isOk:
|
|
||||||
xCheck(expr)
|
|
||||||
|
|
||||||
template xCheckErr*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
if rc.isOk:
|
|
||||||
xCheck(expr, ifFalse)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -22,6 +22,7 @@ import
|
|||||||
../../nimbus/db/aristo/[
|
../../nimbus/db/aristo/[
|
||||||
aristo_debug, aristo_desc, aristo_transcode, aristo_vid],
|
aristo_debug, aristo_desc, aristo_transcode, aristo_vid],
|
||||||
../../nimbus/db/aristo/aristo_filter/filter_scheduler,
|
../../nimbus/db/aristo/aristo_filter/filter_scheduler,
|
||||||
|
../replay/xcheck,
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -21,6 +21,7 @@ import
|
|||||||
aristo_check, aristo_debug, aristo_delete, aristo_desc, aristo_get,
|
aristo_check, aristo_debug, aristo_delete, aristo_desc, aristo_get,
|
||||||
aristo_merge],
|
aristo_merge],
|
||||||
../../nimbus/db/[aristo, aristo/aristo_init/persistent],
|
../../nimbus/db/[aristo, aristo/aristo_init/persistent],
|
||||||
|
../replay/xcheck,
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -39,39 +39,6 @@ proc say*(noisy = false; pfx = "***"; args: varargs[string, `$`]) =
|
|||||||
# Public helpers
|
# Public helpers
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Public workflow helpers
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template xCheck*(expr: untyped): untyped =
|
|
||||||
## Note: this check will invoke `expr` twice
|
|
||||||
if not (expr):
|
|
||||||
check expr
|
|
||||||
return
|
|
||||||
|
|
||||||
template xCheck*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
## Note: this check will invoke `expr` twice
|
|
||||||
if not (expr):
|
|
||||||
ifFalse
|
|
||||||
check expr
|
|
||||||
return
|
|
||||||
|
|
||||||
template xCheckRc*(expr: untyped): untyped =
|
|
||||||
if rc.isErr:
|
|
||||||
xCheck(expr)
|
|
||||||
|
|
||||||
template xCheckRc*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
if rc.isErr:
|
|
||||||
xCheck(expr, ifFalse)
|
|
||||||
|
|
||||||
template xCheckErr*(expr: untyped): untyped =
|
|
||||||
if rc.isOk:
|
|
||||||
xCheck(expr)
|
|
||||||
|
|
||||||
template xCheckErr*(expr: untyped; ifFalse: untyped): untyped =
|
|
||||||
if rc.isOk:
|
|
||||||
xCheck(expr, ifFalse)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -15,7 +15,7 @@ import
|
|||||||
results,
|
results,
|
||||||
unittest2,
|
unittest2,
|
||||||
../../nimbus/[core/chain],
|
../../nimbus/[core/chain],
|
||||||
../replay/undump_blocks,
|
../replay/[undump_blocks, xcheck],
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -17,7 +17,7 @@ import
|
|||||||
eth/[common, p2p],
|
eth/[common, p2p],
|
||||||
rocksdb,
|
rocksdb,
|
||||||
unittest2,
|
unittest2,
|
||||||
../nimbus/db/core_db/[legacy_rocksdb, persistent],
|
../nimbus/db/core_db/persistent,
|
||||||
../nimbus/core/chain,
|
../nimbus/core/chain,
|
||||||
../nimbus/sync/snap/range_desc,
|
../nimbus/sync/snap/range_desc,
|
||||||
../nimbus/sync/snap/worker/db/hexary_desc,
|
../nimbus/sync/snap/worker/db/hexary_desc,
|
||||||
|
@ -18,7 +18,7 @@ import
|
|||||||
unittest2,
|
unittest2,
|
||||||
../../nimbus/core/chain,
|
../../nimbus/core/chain,
|
||||||
../../nimbus/db/core_db,
|
../../nimbus/db/core_db,
|
||||||
../../nimbus/db/core_db/legacy_rocksdb,
|
../../nimbus/db/core_db/persistent,
|
||||||
../../nimbus/sync/snap/range_desc,
|
../../nimbus/sync/snap/range_desc,
|
||||||
../../nimbus/sync/snap/worker/db/[hexary_desc, rocky_bulk_load],
|
../../nimbus/sync/snap/worker/db/[hexary_desc, rocky_bulk_load],
|
||||||
../../nimbus/utils/prettify,
|
../../nimbus/utils/prettify,
|
||||||
|
@ -18,7 +18,7 @@ import
|
|||||||
rocksdb,
|
rocksdb,
|
||||||
unittest2,
|
unittest2,
|
||||||
../nimbus/db/[core_db, kvstore_rocksdb],
|
../nimbus/db/[core_db, kvstore_rocksdb],
|
||||||
../nimbus/db/core_db/[legacy_rocksdb, persistent],
|
../nimbus/db/core_db/persistent,
|
||||||
../nimbus/core/chain,
|
../nimbus/core/chain,
|
||||||
../nimbus/sync/types,
|
../nimbus/sync/types,
|
||||||
../nimbus/sync/snap/range_desc,
|
../nimbus/sync/snap/range_desc,
|
||||||
|
@ -18,7 +18,7 @@ import
|
|||||||
unittest2,
|
unittest2,
|
||||||
../../nimbus/common as nimbus_common,
|
../../nimbus/common as nimbus_common,
|
||||||
../../nimbus/core/chain,
|
../../nimbus/core/chain,
|
||||||
../../nimbus/db/[core_db/legacy_db, storage_types],
|
../../nimbus/db/storage_types,
|
||||||
../../nimbus/sync/snap/worker/db/snapdb_desc,
|
../../nimbus/sync/snap/worker/db/snapdb_desc,
|
||||||
../replay/[pp, undump_blocks, undump_kvp],
|
../replay/[pp, undump_blocks, undump_kvp],
|
||||||
./test_helpers
|
./test_helpers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user