nimbus-eth1
nimbus-eth1 copied to clipboard
Storage trie is not removed from database when the account is removed.
import
std/[importutils, tables],
eth/trie/trie_defs,
eth/common/eth_types,
stew/[byteutils, endians2],
unittest2,
../nimbus/db/storage_types,
../nimbus/db/core_db,
../nimbus/db/ledger,
../nimbus/db/ledger/accounts_ledger {.all.} # import all private symbols
func initAddr(z: int): EthAddress =
const L = sizeof(result)
result[L-sizeof(uint32)..^1] = toBytesBE(z.uint32)
proc kvtLen(db: CoreDbRef): int =
let kvt = db.kvt
for _, _ in kvt:
inc result
proc mptLen(db: LedgerRef): int =
let mpt = db.getMpt
for _, _ in mpt:
inc result
test "storage trie removed from database":
let addr1 = initAddr(1)
let addr2 = initAddr(2)
let ac = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
ac.addBalance(addr1, 1.u256)
ac.setStorage(addr1, 1.u256, 1.u256)
ac.persist()
# only one storage trie
check memDB.kvtLen == 1
# only one account
check ac.mptLen == 1
ac.addBalance(addr2, 1.u256)
ac.setStorage(addr2, 1.u256, 1.u256)
ac.persist()
let root1 = ac.state()
# both addr1 and addr2 share the same storage trie
# only one storage trie
check memDB.kvtLen == 1 # ok # I think this should 2 storage tries, one for each account.
# now there are two accounts
check ac.mptLen == 2 # ok
ac.setStorage(addr2, 2.u256, 1.u256)
ac.persist()
# now there will be two storage tries
check memDB.kvtLen == 2 # ok
# delete slot 2
ac.setStorage(addr2, 2.u256, 0.u256)
ac.persist()
# the state root should be the same as when there is no slot 2 of addr2
check ac.state() == root1 # ok
check memDB.kvtLen == 1 # fails with 2 storage tries in db
ac.deleteAccount(addr2)
ac.persist()
check memDB.kvtLen == 1 # fails with 2 storage tries in db
# only one account
check ac.mptLen == 1 # ok