allow nimbus to read geth database
This commit is contained in:
parent
3eef659d19
commit
eabacb0a33
|
@ -222,6 +222,9 @@ proc persistMode(acc: RefAccount): PersistMode =
|
||||||
|
|
||||||
proc persistCode(acc: RefAccount, db: TrieDatabaseRef) =
|
proc persistCode(acc: RefAccount, db: TrieDatabaseRef) =
|
||||||
if acc.code.len != 0:
|
if acc.code.len != 0:
|
||||||
|
when defined(geth):
|
||||||
|
db.put(acc.account.codeHash.data, acc.code)
|
||||||
|
else:
|
||||||
db.put(contractHashKey(acc.account.codeHash).toOpenArray, acc.code)
|
db.put(contractHashKey(acc.account.codeHash).toOpenArray, acc.code)
|
||||||
|
|
||||||
proc persistStorage(acc: RefAccount, db: TrieDatabaseRef) =
|
proc persistStorage(acc: RefAccount, db: TrieDatabaseRef) =
|
||||||
|
@ -282,8 +285,12 @@ proc getCode*(ac: AccountsCache, address: EthAddress): seq[byte] =
|
||||||
|
|
||||||
if CodeLoaded in acc.flags or CodeChanged in acc.flags:
|
if CodeLoaded in acc.flags or CodeChanged in acc.flags:
|
||||||
result = acc.code
|
result = acc.code
|
||||||
|
else:
|
||||||
|
when defined(geth):
|
||||||
|
let data = ac.db.get(acc.account.codeHash.data)
|
||||||
else:
|
else:
|
||||||
let data = ac.db.get(contractHashKey(acc.account.codeHash).toOpenArray)
|
let data = ac.db.get(contractHashKey(acc.account.codeHash).toOpenArray)
|
||||||
|
|
||||||
acc.code = data
|
acc.code = data
|
||||||
acc.flags.incl CodeLoaded
|
acc.flags.incl CodeLoaded
|
||||||
result = acc.code
|
result = acc.code
|
||||||
|
@ -411,9 +418,10 @@ iterator storage*(ac: AccountsCache, address: EthAddress): (UInt256, UInt256) =
|
||||||
let storageRoot = acc.account.storageRoot
|
let storageRoot = acc.account.storageRoot
|
||||||
var trie = initHexaryTrie(ac.db, storageRoot)
|
var trie = initHexaryTrie(ac.db, storageRoot)
|
||||||
|
|
||||||
for slot, value in trie:
|
for slotHash, value in trie:
|
||||||
if slot.len != 0:
|
if slotHash.len == 0: continue
|
||||||
var keyData = ac.db.get(slotHashToSlotKey(slot).toOpenArray)
|
let keyData = ac.db.get(slotHashToSlotKey(slotHash).toOpenArray)
|
||||||
|
if keyData.len == 0: continue
|
||||||
yield (rlp.decode(keyData, UInt256), rlp.decode(value, UInt256))
|
yield (rlp.decode(keyData, UInt256), rlp.decode(value, UInt256))
|
||||||
|
|
||||||
proc getStorageRoot*(ac: AccountsCache, address: EthAddress): Hash256 =
|
proc getStorageRoot*(ac: AccountsCache, address: EthAddress): Hash256 =
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import eth/[rlp, common], db_chain, eth/trie/db
|
||||||
|
|
||||||
|
const
|
||||||
|
headerPrefix = 'h'.byte # headerPrefix + num (uint64 big endian) + hash -> header
|
||||||
|
headerHashSuffix = 'n'.byte # headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
|
||||||
|
blockBodyPrefix = 'b'.byte # blockBodyPrefix + num (uint64 big endian) + hash -> block body
|
||||||
|
|
||||||
|
proc headerHash*(db: BaseChainDB, number: uint64): Hash256 =
|
||||||
|
var key: array[10, byte]
|
||||||
|
key[0] = headerPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[^1] = headerHashSuffix
|
||||||
|
let res = db.db.get(key)
|
||||||
|
doAssert(res.len == 32)
|
||||||
|
result.data[0..31] = res[0..31]
|
||||||
|
|
||||||
|
proc blockHeader*(db: BaseChainDB, hash: Hash256, number: uint64): BlockHeader =
|
||||||
|
var key: array[41, byte]
|
||||||
|
key[0] = headerPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[9..40] = hash.data[0..^1]
|
||||||
|
let res = db.db.get(key)
|
||||||
|
result = rlp.decode(res, BlockHeader)
|
||||||
|
|
||||||
|
proc blockHeader*(db: BaseChainDB, number: uint64): BlockHeader =
|
||||||
|
let hash = db.headerHash(number)
|
||||||
|
db.blockHeader(hash, number)
|
||||||
|
|
||||||
|
proc blockBody*(db: BaseChainDB, hash: Hash256, number: uint64): BlockBody =
|
||||||
|
var key: array[41, byte]
|
||||||
|
key[0] = blockBodyPrefix
|
||||||
|
key[1..8] = toBytesBE(number)[0..^1]
|
||||||
|
key[9..40] = hash.data[0..^1]
|
||||||
|
let res = db.db.get(key)
|
||||||
|
result = rlp.decode(res, BlockBody)
|
|
@ -150,6 +150,9 @@ proc processBlock*(chainDB: BaseChainDB, header: BlockHeader, body: BlockBody, v
|
||||||
|
|
||||||
let stateDb = vmState.accountDb
|
let stateDb = vmState.accountDb
|
||||||
if header.stateRoot != stateDb.rootHash:
|
if header.stateRoot != stateDb.rootHash:
|
||||||
|
when defined(geth):
|
||||||
|
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash
|
||||||
|
else:
|
||||||
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash, arrivedFrom=chainDB.getCanonicalHead().stateRoot
|
error "Wrong state root in block", blockNumber=header.blockNumber, expected=header.stateRoot, actual=stateDb.rootHash, arrivedFrom=chainDB.getCanonicalHead().stateRoot
|
||||||
# this one is a show stopper until we are confident in our VM's
|
# this one is a show stopper until we are confident in our VM's
|
||||||
# compatibility with the main chain
|
# compatibility with the main chain
|
||||||
|
|
|
@ -5,6 +5,13 @@ import
|
||||||
chronicles, rpc/hexstrings, launcher,
|
chronicles, rpc/hexstrings, launcher,
|
||||||
vm/interpreter/vm_forks, ./config
|
vm/interpreter/vm_forks, ./config
|
||||||
|
|
||||||
|
when defined(geth):
|
||||||
|
import db/geth_db
|
||||||
|
|
||||||
|
proc getParentHeader(db: BaseChainDB, header: BlockHeader): BlockHeader =
|
||||||
|
db.blockHeader(header.blockNumber.truncate(uint64) - 1)
|
||||||
|
|
||||||
|
else:
|
||||||
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
proc getParentHeader(self: BaseChainDB, header: BlockHeader): BlockHeader =
|
||||||
self.getBlockHeader(header.parentHash)
|
self.getBlockHeader(header.parentHash)
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,9 @@ method difficulty*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||||
method gasLimit*(vmState: BaseVMState): GasInt {.base, gcsafe.} =
|
method gasLimit*(vmState: BaseVMState): GasInt {.base, gcsafe.} =
|
||||||
vmState.blockHeader.gasLimit
|
vmState.blockHeader.gasLimit
|
||||||
|
|
||||||
|
when defined(geth):
|
||||||
|
import db/geth_db
|
||||||
|
|
||||||
method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256 {.base, gcsafe.} =
|
method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256 {.base, gcsafe.} =
|
||||||
var ancestorDepth = vmState.blockHeader.blockNumber - blockNumber - 1
|
var ancestorDepth = vmState.blockHeader.blockNumber - blockNumber - 1
|
||||||
if ancestorDepth >= constants.MAX_PREV_HEADER_DEPTH:
|
if ancestorDepth >= constants.MAX_PREV_HEADER_DEPTH:
|
||||||
|
@ -82,6 +85,9 @@ method getAncestorHash*(vmState: BaseVMState, blockNumber: BlockNumber): Hash256
|
||||||
if blockNumber >= vmState.blockHeader.blockNumber:
|
if blockNumber >= vmState.blockHeader.blockNumber:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
when defined(geth):
|
||||||
|
result = vmState.chainDB.headerHash(blockNumber.truncate(uint64))
|
||||||
|
else:
|
||||||
result = vmState.chainDB.getBlockHash(blockNumber)
|
result = vmState.chainDB.getBlockHash(blockNumber)
|
||||||
#TODO: should we use deque here?
|
#TODO: should we use deque here?
|
||||||
# someday we may revive this code when
|
# someday we may revive this code when
|
||||||
|
|
Loading…
Reference in New Issue