Fix LedgerRef storage iterator and add test (#2458)
This commit is contained in:
parent
6fe7411ac0
commit
c775c906a2
|
@ -474,14 +474,14 @@ iterator rightPairsStorage*(
|
||||||
db: AristoDbRef; # Database layer
|
db: AristoDbRef; # Database layer
|
||||||
accPath: Hash256; # Account the storage data belong to
|
accPath: Hash256; # Account the storage data belong to
|
||||||
start = low(PathID); # Before or at first value
|
start = low(PathID); # Before or at first value
|
||||||
): (PathID,Blob) =
|
): (PathID,UInt256) =
|
||||||
## Variant of `rightPairs()` for a storage tree
|
## Variant of `rightPairs()` for a storage tree
|
||||||
block body:
|
block body:
|
||||||
let stoID = db.fetchStorageID(accPath).valueOr:
|
let stoID = db.fetchStorageID(accPath).valueOr:
|
||||||
break body
|
break body
|
||||||
if stoID.isValid:
|
if stoID.isValid:
|
||||||
for (lty,pyl) in db.rightPairs LeafTie(root: stoID, path: start):
|
for (lty,pyl) in db.rightPairs LeafTie(root: stoID, path: start):
|
||||||
yield (lty.path, pyl.rawBlob)
|
yield (lty.path, pyl.stoData)
|
||||||
|
|
||||||
# ----------------
|
# ----------------
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ iterator pairs*(mpt: CoreDbMptRef): (Blob, Blob) =
|
||||||
raiseAssert: "Unsupported database type: " & $mpt.dbType
|
raiseAssert: "Unsupported database type: " & $mpt.dbType
|
||||||
mpt.ifTrackNewApi: debug newApiTxt, api, elapsed
|
mpt.ifTrackNewApi: debug newApiTxt, api, elapsed
|
||||||
|
|
||||||
iterator slotPairs*(acc: CoreDbAccRef; accPath: Hash256): (Blob, Blob) =
|
iterator slotPairs*(acc: CoreDbAccRef; accPath: Hash256): (Blob, UInt256) =
|
||||||
## Trie traversal, only supported for `CoreDbMptRef`
|
## Trie traversal, only supported for `CoreDbMptRef`
|
||||||
##
|
##
|
||||||
acc.setTrackNewApi AccSlotPairsIt
|
acc.setTrackNewApi AccSlotPairsIt
|
||||||
|
|
|
@ -13,14 +13,15 @@
|
||||||
import
|
import
|
||||||
std/[tables, hashes, sets, typetraits],
|
std/[tables, hashes, sets, typetraits],
|
||||||
chronicles,
|
chronicles,
|
||||||
eth/[common, rlp],
|
eth/common,
|
||||||
results,
|
results,
|
||||||
stew/keyed_queue,
|
stew/keyed_queue,
|
||||||
../../stateless/multi_keys,
|
../../stateless/multi_keys,
|
||||||
"../.."/[constants, utils/utils],
|
"../.."/[constants, utils/utils],
|
||||||
../access_list as ac_access_list,
|
../access_list as ac_access_list,
|
||||||
../../evm/code_bytes,
|
../../evm/code_bytes,
|
||||||
".."/[core_db, storage_types, transient_storage]
|
".."/[core_db, storage_types, transient_storage],
|
||||||
|
../aristo/aristo_blobify
|
||||||
|
|
||||||
export code_bytes
|
export code_bytes
|
||||||
|
|
||||||
|
@ -142,12 +143,6 @@ proc resetCoreDbAccount(ac: AccountsLedgerRef, acc: AccountRef) =
|
||||||
acc.statement.balance = emptyEthAccount.balance
|
acc.statement.balance = emptyEthAccount.balance
|
||||||
acc.statement.codeHash = emptyEthAccount.codeHash
|
acc.statement.codeHash = emptyEthAccount.codeHash
|
||||||
|
|
||||||
template noRlpException(info: static[string]; code: untyped) =
|
|
||||||
try:
|
|
||||||
code
|
|
||||||
except RlpError as e:
|
|
||||||
raiseAssert info & ", name=\"" & $e.name & "\", msg=\"" & e.msg & "\""
|
|
||||||
|
|
||||||
# The AccountsLedgerRef is modeled after TrieDatabase for it's transaction style
|
# The AccountsLedgerRef is modeled after TrieDatabase for it's transaction style
|
||||||
proc init*(x: typedesc[AccountsLedgerRef], db: CoreDbRef,
|
proc init*(x: typedesc[AccountsLedgerRef], db: CoreDbRef,
|
||||||
root: KeccakHash): AccountsLedgerRef =
|
root: KeccakHash): AccountsLedgerRef =
|
||||||
|
@ -384,7 +379,7 @@ proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef) =
|
||||||
discard
|
discard
|
||||||
let
|
let
|
||||||
key = slot.toBytesBE.keccakHash.data.slotHashToSlotKey
|
key = slot.toBytesBE.keccakHash.data.slotHashToSlotKey
|
||||||
rc = ac.kvt.put(key.toOpenArray, rlp.encode(slot))
|
rc = ac.kvt.put(key.toOpenArray, blobify(slot).data)
|
||||||
if rc.isErr:
|
if rc.isErr:
|
||||||
warn logTxt "persistStorage()", slot, error=($$rc.error)
|
warn logTxt "persistStorage()", slot, error=($$rc.error)
|
||||||
|
|
||||||
|
@ -727,13 +722,16 @@ iterator storage*(
|
||||||
): (UInt256, UInt256) =
|
): (UInt256, UInt256) =
|
||||||
# beware that if the account not persisted,
|
# beware that if the account not persisted,
|
||||||
# the storage root will not be updated
|
# the storage root will not be updated
|
||||||
noRlpException "storage()":
|
|
||||||
for (slotHash, value) in ac.ledger.slotPairs eAddr.toAccountKey:
|
for (slotHash, value) in ac.ledger.slotPairs eAddr.toAccountKey:
|
||||||
let rc = ac.kvt.get(slotHashToSlotKey(slotHash).toOpenArray)
|
let rc = ac.kvt.get(slotHashToSlotKey(slotHash).toOpenArray)
|
||||||
if rc.isErr:
|
if rc.isErr:
|
||||||
warn logTxt "storage()", slotHash, error=($$rc.error)
|
warn logTxt "storage()", slotHash, error=($$rc.error)
|
||||||
else:
|
continue
|
||||||
yield (rlp.decode(rc.value, UInt256), rlp.decode(value, UInt256))
|
let r = deblobify(rc.value, UInt256)
|
||||||
|
if r.isErr:
|
||||||
|
warn logTxt "storage.deblobify", slotHash, msg=r.error
|
||||||
|
continue
|
||||||
|
yield (r.value, value)
|
||||||
|
|
||||||
iterator cachedStorage*(ac: AccountsLedgerRef, address: EthAddress): (UInt256, UInt256) =
|
iterator cachedStorage*(ac: AccountsLedgerRef, address: EthAddress): (UInt256, UInt256) =
|
||||||
let acc = ac.getAccount(address, false)
|
let acc = ac.getAccount(address, false)
|
||||||
|
|
|
@ -28,7 +28,9 @@ import
|
||||||
const
|
const
|
||||||
genesisFile = "tests/customgenesis/cancun123.json"
|
genesisFile = "tests/customgenesis/cancun123.json"
|
||||||
hexPrivKey = "af1a9be9f1a54421cac82943820a0fe0f601bb5f4f6d0bccc81c613f0ce6ae22"
|
hexPrivKey = "af1a9be9f1a54421cac82943820a0fe0f601bb5f4f6d0bccc81c613f0ce6ae22"
|
||||||
senderAddr = hexToByteArray[20]("73cf19657412508833f618a15e8251306b3e6ee5")
|
|
||||||
|
# The above privKey will generate this address
|
||||||
|
# senderAddr = hexToByteArray[20]("73cf19657412508833f618a15e8251306b3e6ee5")
|
||||||
|
|
||||||
type
|
type
|
||||||
TestEnv = object
|
TestEnv = object
|
||||||
|
@ -391,7 +393,7 @@ proc runLedgerTransactionTests(noisy = true) =
|
||||||
let ledger = env.com.getLedger(head)
|
let ledger = env.com.getLedger(head)
|
||||||
env.runTrial4(ledger, n, rollback = true)
|
env.runTrial4(ledger, n, rollback = true)
|
||||||
|
|
||||||
proc runLedgerBesicOperationsTests() =
|
proc runLedgerBasicOperationsTests() =
|
||||||
suite "Ledger basic operations tests":
|
suite "Ledger basic operations tests":
|
||||||
setup:
|
setup:
|
||||||
const emptyAcc {.used.} = newAccount()
|
const emptyAcc {.used.} = newAccount()
|
||||||
|
@ -454,7 +456,7 @@ proc runLedgerBesicOperationsTests() =
|
||||||
check x.originalStorage.len == 3
|
check x.originalStorage.len == 3
|
||||||
check y.originalStorage.len == 3
|
check y.originalStorage.len == 3
|
||||||
|
|
||||||
test "accounts cache":
|
test "Ledger various operations":
|
||||||
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
||||||
var addr1 = initAddr(1)
|
var addr1 = initAddr(1)
|
||||||
|
|
||||||
|
@ -494,8 +496,7 @@ proc runLedgerBesicOperationsTests() =
|
||||||
db.setStorage(addr1, 1.u256, 10.u256)
|
db.setStorage(addr1, 1.u256, 10.u256)
|
||||||
check rootHash == db.rootHash
|
check rootHash == db.rootHash
|
||||||
|
|
||||||
# accounts cache readonly operations
|
# Ledger readonly operations using previous hash
|
||||||
# use previous hash
|
|
||||||
var ac2 = LedgerRef.init(memDB, rootHash)
|
var ac2 = LedgerRef.init(memDB, rootHash)
|
||||||
var addr2 = initAddr(2)
|
var addr2 = initAddr(2)
|
||||||
|
|
||||||
|
@ -515,7 +516,7 @@ proc runLedgerBesicOperationsTests() =
|
||||||
# state trie at all
|
# state trie at all
|
||||||
check ac2.rootHash == rootHash
|
check ac2.rootHash == rootHash
|
||||||
|
|
||||||
test "accounts cache code retrieval after persist called":
|
test "Ledger code retrieval after persist called":
|
||||||
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
||||||
var addr2 = initAddr(2)
|
var addr2 = initAddr(2)
|
||||||
ac.setCode(addr2, code)
|
ac.setCode(addr2, code)
|
||||||
|
@ -656,7 +657,7 @@ proc runLedgerBesicOperationsTests() =
|
||||||
check ac.vts(0xcc, 7, 88) == false
|
check ac.vts(0xcc, 7, 88) == false
|
||||||
check ac.vts(0xdd, 2, 66) == false
|
check ac.vts(0xdd, 2, 66) == false
|
||||||
|
|
||||||
test "accounts cache contractCollision":
|
test "ledger contractCollision":
|
||||||
# use previous hash
|
# use previous hash
|
||||||
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
||||||
let addr2 = initAddr(2)
|
let addr2 = initAddr(2)
|
||||||
|
@ -678,13 +679,79 @@ proc runLedgerBesicOperationsTests() =
|
||||||
ac.setNonce(addr4, 1)
|
ac.setNonce(addr4, 1)
|
||||||
check ac.contractCollision(addr4) == true
|
check ac.contractCollision(addr4) == true
|
||||||
|
|
||||||
|
test "Ledger storage iterator":
|
||||||
|
var ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
|
||||||
|
let addr2 = initAddr(2)
|
||||||
|
ac.setStorage(addr2, 1.u256, 2.u256)
|
||||||
|
ac.setStorage(addr2, 2.u256, 3.u256)
|
||||||
|
|
||||||
|
var keys: seq[UInt256]
|
||||||
|
var vals: seq[UInt256]
|
||||||
|
for k, v in ac.cachedStorage(addr2):
|
||||||
|
keys.add k
|
||||||
|
vals.add v
|
||||||
|
|
||||||
|
# before persist, there are storages in cache
|
||||||
|
check keys.len == 2
|
||||||
|
check vals.len == 2
|
||||||
|
|
||||||
|
check 1.u256 in keys
|
||||||
|
check 2.u256 in keys
|
||||||
|
|
||||||
|
# before persist, the values are all original values
|
||||||
|
check vals == @[0.u256, 0.u256]
|
||||||
|
|
||||||
|
keys.reset
|
||||||
|
vals.reset
|
||||||
|
|
||||||
|
for k, v in ac.storage(addr2):
|
||||||
|
keys.add k
|
||||||
|
vals.add k
|
||||||
|
|
||||||
|
# before persist, there are no storages in db
|
||||||
|
check keys.len == 0
|
||||||
|
check vals.len == 0
|
||||||
|
|
||||||
|
ac.persist()
|
||||||
|
for k, v in ac.cachedStorage(addr2):
|
||||||
|
keys.add k
|
||||||
|
vals.add v
|
||||||
|
|
||||||
|
# after persist, there are storages in cache
|
||||||
|
check keys.len == 2
|
||||||
|
check vals.len == 2
|
||||||
|
|
||||||
|
check 1.u256 in keys
|
||||||
|
check 2.u256 in keys
|
||||||
|
|
||||||
|
# after persist, the values are what we put into
|
||||||
|
check 2.u256 in vals
|
||||||
|
check 3.u256 in vals
|
||||||
|
|
||||||
|
keys.reset
|
||||||
|
vals.reset
|
||||||
|
|
||||||
|
for k, v in ac.storage(addr2):
|
||||||
|
keys.add k
|
||||||
|
vals.add v
|
||||||
|
|
||||||
|
# after persist, there are storages in db
|
||||||
|
check keys.len == 2
|
||||||
|
check vals.len == 2
|
||||||
|
|
||||||
|
check 1.u256 in keys
|
||||||
|
check 2.u256 in keys
|
||||||
|
|
||||||
|
check 2.u256 in vals
|
||||||
|
check 3.u256 in vals
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Main function(s)
|
# Main function(s)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc ledgerMain*(noisy = defined(debug)) =
|
proc ledgerMain*(noisy = defined(debug)) =
|
||||||
noisy.runLedgerTransactionTests
|
noisy.runLedgerTransactionTests
|
||||||
runLedgerBesicOperationsTests()
|
runLedgerBasicOperationsTests()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var noisy = defined(debug)
|
var noisy = defined(debug)
|
||||||
|
|
Loading…
Reference in New Issue