nimbus-eth1/nimbus/p2p/chain.nim

76 lines
2.8 KiB
Nim
Raw Normal View History

2019-07-07 10:12:01 +00:00
import ../db/[db_chain, state_db], eth/common, chronicles, ../vm_state, ../vm_types, ../transaction, stew/ranges,
2019-03-19 16:30:35 +00:00
../vm/[computation, message], ../constants, stint, nimcrypto,
2019-02-05 19:15:50 +00:00
../vm_state_transactions, sugar, ../utils, eth/trie/db, ../tracer, ./executor
2018-08-29 08:49:01 +00:00
type
Chain* = ref object of AbstractChainDB
db: BaseChainDB
proc newChain*(db: BaseChainDB): Chain =
result.new
result.db = db
method genesisHash*(c: Chain): KeccakHash {.gcsafe.} =
2018-08-29 08:49:01 +00:00
c.db.getBlockHash(0.toBlockNumber)
method getBlockHeader*(c: Chain, b: HashOrNum, output: var BlockHeader): bool {.gcsafe.} =
2018-08-29 08:49:01 +00:00
case b.isHash
of true:
c.db.getBlockHeader(b.hash, output)
else:
c.db.getBlockHeader(b.number, output)
method getBestBlockHeader*(c: Chain): BlockHeader {.gcsafe.} =
2018-08-29 08:49:01 +00:00
c.db.getCanonicalHead()
method getSuccessorHeader*(c: Chain, h: BlockHeader, output: var BlockHeader, skip = 0'u): bool {.gcsafe.} =
let offset = 1 + skip.toBlockNumber
if h.blockNumber <= (not 0.toBlockNumber) - offset:
result = c.db.getBlockHeader(h.blockNumber + offset, output)
method getAncestorHeader*(c: Chain, h: BlockHeader, output: var BlockHeader, skip = 0'u): bool {.gcsafe.} =
let offset = 1 + skip.toBlockNumber
if h.blockNumber >= offset:
result = c.db.getBlockHeader(h.blockNumber - offset, output)
2018-08-29 08:49:01 +00:00
method getBlockBody*(c: Chain, blockHash: KeccakHash): BlockBodyRef =
result = nil
method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarray[BlockBody]): ValidationResult =
2018-08-29 08:49:01 +00:00
# Run the VM here
if headers.len != bodies.len:
debug "Number of headers not matching number of bodies"
return ValidationResult.Error
2018-08-29 08:49:01 +00:00
let transaction = c.db.db.beginTransaction()
defer: transaction.dispose()
trace "Persisting blocks", fromBlock = headers[0].blockNumber, toBlock = headers[^1].blockNumber
2018-08-29 08:49:01 +00:00
for i in 0 ..< headers.len:
2018-09-10 08:44:07 +00:00
let head = c.db.getCanonicalHead()
2019-02-14 15:20:41 +00:00
let vmState = newBaseVMState(head.stateRoot, headers[i], c.db)
2019-03-20 03:22:37 +00:00
let validationResult = processBlock(c.db, headers[i], bodies[i], vmState)
2018-09-10 08:44:07 +00:00
2019-01-12 12:49:08 +00:00
when not defined(release):
if validationResult == ValidationResult.Error and
bodies[i].transactions.calcTxRoot == headers[i].txRoot:
dumpDebuggingMetaData(c.db, headers[i], bodies[i], vmState)
warn "Validation error. Debugging metadata dumped."
2018-09-10 08:44:07 +00:00
2019-01-09 08:35:02 +00:00
if validationResult != ValidationResult.OK:
2019-03-31 20:34:11 +00:00
return validationResult
2018-12-10 12:04:34 +00:00
discard c.db.persistHeaderToDb(headers[i])
if c.db.getCanonicalHead().blockHash != headers[i].blockHash:
debug "Stored block header hash doesn't match declared hash"
return ValidationResult.Error
c.db.persistTransactions(headers[i].blockNumber, bodies[i].transactions)
2018-12-25 05:58:55 +00:00
c.db.persistReceipts(vmState.receipts)
transaction.commit()
method getTrieDB*(c: Chain): TrieDatabaseRef {.gcsafe.} =
c.db.db