add ccountExist and isDeadAccount to AccountStateDB

This commit is contained in:
andri lim 2019-02-01 16:25:10 +07:00 committed by zah
parent 481c6cf4ed
commit 4cc0ef427c
3 changed files with 65 additions and 4 deletions

View File

@ -171,13 +171,26 @@ proc getCode*(db: AccountStateDB, address: EthAddress): ByteRange =
let data = triedb.get(contractHashKey(db.getCodeHash(address)).toOpenArray) let data = triedb.get(contractHashKey(db.getCodeHash(address)).toOpenArray)
data.toRange data.toRange
proc hasCodeOrNonce*(account: AccountStateDB, address: EthAddress): bool {.inline.} = proc hasCodeOrNonce*(db: AccountStateDB, address: EthAddress): bool {.inline.} =
account.getNonce(address) != 0 or account.getCodeHash(address) != EMPTY_SHA3 db.getNonce(address) != 0 or db.getCodeHash(address) != EMPTY_SHA3
proc dumpAccount*(db: AccountStateDB, addressS: string): string = proc dumpAccount*(db: AccountStateDB, addressS: string): string =
let address = addressS.parseAddress let address = addressS.parseAddress
return fmt"{addressS}: Storage: {db.getStorage(address, 0.u256)}; getAccount: {db.getAccount address}" return fmt"{addressS}: Storage: {db.getStorage(address, 0.u256)}; getAccount: {db.getAccount address}"
proc accountExist*(db: AccountStateDB, address: EthAddress): bool =
db.trie.get(createRangeFromAddress address).len > 0
proc isDeadAccount*(db: AccountStateDB, address: EthAddress): bool =
let recordFound = db.trie.get(createRangeFromAddress address)
if recordFound.len > 0:
let account = rlp.decode(recordFound, Account)
result = account.codeHash == EMPTY_SHA3 and
account.balance.isZero and
account.nonce == 0
else:
result = true
proc rootHash*(db: ReadOnlyStateDB): KeccakHash {.borrow.} proc rootHash*(db: ReadOnlyStateDB): KeccakHash {.borrow.}
proc getAccount*(db: ReadOnlyStateDB, address: EthAddress): Account {.borrow.} proc getAccount*(db: ReadOnlyStateDB, address: EthAddress): Account {.borrow.}
proc getCodeHash*(db: ReadOnlyStateDB, address: EthAddress): Hash256 {.borrow.} proc getCodeHash*(db: ReadOnlyStateDB, address: EthAddress): Hash256 {.borrow.}
@ -186,4 +199,6 @@ proc getStorageRoot*(db: ReadOnlyStateDB, address: EthAddress): Hash256 {.borrow
proc getStorage*(db: ReadOnlyStateDB, address: EthAddress, slot: UInt256): (UInt256, bool) {.borrow.} proc getStorage*(db: ReadOnlyStateDB, address: EthAddress, slot: UInt256): (UInt256, bool) {.borrow.}
proc getNonce*(db: ReadOnlyStateDB, address: EthAddress): AccountNonce {.borrow.} proc getNonce*(db: ReadOnlyStateDB, address: EthAddress): AccountNonce {.borrow.}
proc getCode*(db: ReadOnlyStateDB, address: EthAddress): ByteRange {.borrow.} proc getCode*(db: ReadOnlyStateDB, address: EthAddress): ByteRange {.borrow.}
proc hasCodeOrNonce*(account: ReadOnlyStateDB, address: EthAddress): bool {.borrow.} proc hasCodeOrNonce*(db: ReadOnlyStateDB, address: EthAddress): bool {.borrow.}
proc accountExist*(db: ReadOnlyStateDB, address: EthAddress): bool {.borrow.}
proc isDeadAccount*(db: ReadOnlyStateDB, address: EthAddress): bool {.borrow.}

View File

@ -21,4 +21,5 @@ import ./test_code_stream,
./test_op_bit, ./test_op_bit,
./test_op_env, ./test_op_env,
./test_op_memory, ./test_op_memory,
./test_op_misc ./test_op_misc,
./test_state_db

45
tests/test_state_db.nim Normal file
View File

@ -0,0 +1,45 @@
# Nimbus
# Copyright (c) 2018 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 unittest, strutils, eth_trie/[hexary, db],
../nimbus/db/state_db, byteutils, eth_common,
ranges
suite "Account State DB":
var
memDB = newMemoryDB()
trie = initHexaryTrie(memDB)
stateDB = newAccountStateDB(memDB, trie.rootHash, true)
address: EthAddress
hexToByteArray("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", address)
test "accountExist and isDeadAccount":
check stateDB.accountExist(address) == false
check stateDB.isDeadAccount(address) == true
var acc = stateDB.getAccount(address)
acc.balance = 1000.u256
stateDB.setAccount(address, acc)
check stateDB.accountExist(address) == true
check stateDB.isDeadAccount(address) == false
acc.balance = 0.u256
acc.nonce = 1
stateDB.setAccount(address, acc)
check stateDB.isDeadAccount(address) == false
var code = hexToSeqByte("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")
stateDB.setCode(address, code.toRange)
stateDB.setNonce(address, 0)
check stateDB.isDeadAccount(address) == false
code = @[]
stateDB.setCode(address, code.toRange)
check stateDB.isDeadAccount(address) == true
check stateDB.accountExist(address) == true