fix markCanonicalChain bug
This commit is contained in:
parent
ce098bf88f
commit
709d8ef255
|
@ -332,13 +332,26 @@ proc headerExists*(self: BaseChainDB; blockHash: Hash256): bool =
|
|||
## Returns True if the header with the given block hash is in our DB.
|
||||
self.db.contains(genericHashKey(blockHash).toOpenArray)
|
||||
|
||||
proc markCanonicalChain(self: BaseChainDB, header: BlockHeader, headerHash: Hash256) =
|
||||
proc markCanonicalChain(self: BaseChainDB, header: BlockHeader, headerHash: Hash256): bool =
|
||||
## mark this chain as canonical by adding block number to hash lookup
|
||||
## down to forking point
|
||||
var
|
||||
currHash = headerHash
|
||||
currHeader = header
|
||||
|
||||
# mark current header as canonical
|
||||
let key = blockNumberToHashKey(currHeader.blockNumber)
|
||||
self.db.put(key.toOpenArray, rlp.encode(currHash))
|
||||
|
||||
# it is a genesis block, done
|
||||
if currHeader.parentHash == Hash256():
|
||||
return true
|
||||
|
||||
# mark ancestor blocks as canonical too
|
||||
currHash = currHeader.parentHash
|
||||
if not self.getBlockHeader(currHeader.parentHash, currHeader):
|
||||
return false
|
||||
|
||||
while currHash != Hash256():
|
||||
let key = blockNumberToHashKey(currHeader.blockNumber)
|
||||
let data = self.db.get(key.toOpenArray)
|
||||
|
@ -352,24 +365,34 @@ proc markCanonicalChain(self: BaseChainDB, header: BlockHeader, headerHash: Hash
|
|||
# forking point, done
|
||||
break
|
||||
|
||||
if currHeader.parentHash == Hash256():
|
||||
break
|
||||
|
||||
currHash = currHeader.parentHash
|
||||
currHeader = self.getBlockHeader(currHeader.parentHash)
|
||||
if not self.getBlockHeader(currHeader.parentHash, currHeader):
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
proc setHead*(self: BaseChainDB, blockHash: Hash256): bool =
|
||||
var header: BlockHeader
|
||||
if not self.getBlockHeader(blockHash, header):
|
||||
return false
|
||||
|
||||
self.markCanonicalChain(header, blockHash)
|
||||
if not self.markCanonicalChain(header, blockHash):
|
||||
return false
|
||||
|
||||
self.db.put(canonicalHeadHashKey().toOpenArray, rlp.encode(blockHash))
|
||||
return true
|
||||
|
||||
proc setHead*(self: BaseChainDB, header: BlockHeader, writeHeader = false) =
|
||||
proc setHead*(self: BaseChainDB, header: BlockHeader, writeHeader = false): bool =
|
||||
var headerHash = rlpHash(header)
|
||||
if writeHeader:
|
||||
self.db.put(genericHashKey(headerHash).toOpenArray, rlp.encode(header))
|
||||
self.markCanonicalChain(header, headerHash)
|
||||
if not self.markCanonicalChain(header, headerHash):
|
||||
return false
|
||||
self.db.put(canonicalHeadHashKey().toOpenArray, rlp.encode(headerHash))
|
||||
return true
|
||||
|
||||
proc persistReceipts*(self: BaseChainDB, receipts: openArray[Receipt]): Hash256 =
|
||||
var trie = initHexaryTrie(self.db)
|
||||
|
|
|
@ -114,10 +114,10 @@ proc setupDebugRpc*(chainDB: BaseChainDB, rpcsrv: RpcServer) =
|
|||
|
||||
result = traceBlock(chainDB, header, body, flags)
|
||||
|
||||
rpcsrv.rpc("debug_setHead") do(quantityTag: string):
|
||||
rpcsrv.rpc("debug_setHead") do(quantityTag: string) -> bool:
|
||||
## Sets the current head of the local chain by block number.
|
||||
## Note, this is a destructive action and may severely damage your chain.
|
||||
## Use with extreme caution.
|
||||
let
|
||||
header = chainDB.headerFromTag(quantityTag)
|
||||
chainDB.setHead(header)
|
||||
result = chainDB.setHead(header)
|
||||
|
|
|
@ -28,7 +28,7 @@ proc dumpDebug(chainDB: BaseChainDB, blockNumber: UInt256) =
|
|||
body = captureChainDB.getBlockBody(headerHash)
|
||||
vmState = BaseVMState.new(parent, header, captureChainDB)
|
||||
|
||||
captureChainDB.setHead(parent, true)
|
||||
discard captureChainDB.setHead(parent, true)
|
||||
discard vmState.processBlockNotPoA(header, body)
|
||||
|
||||
transaction.rollback()
|
||||
|
|
|
@ -95,7 +95,7 @@ proc huntProblematicBlock(blockNumber: UInt256): ValidationResult =
|
|||
# try to execute current block
|
||||
chainDB = newBaseChainDB(memoryDB, false)
|
||||
|
||||
chainDB.setHead(parentBlock.header, true)
|
||||
discard chainDB.setHead(parentBlock.header, true)
|
||||
|
||||
let transaction = memoryDB.beginTransaction()
|
||||
defer: transaction.dispose()
|
||||
|
|
|
@ -47,7 +47,7 @@ proc main() {.used.} =
|
|||
# move head to block number ...
|
||||
if conf.head != 0.u256:
|
||||
var parentBlock = requestBlock(conf.head)
|
||||
chainDB.setHead(parentBlock.header)
|
||||
discard chainDB.setHead(parentBlock.header)
|
||||
|
||||
if canonicalHeadHashKey().toOpenArray notin trieDB:
|
||||
persistToDb(db):
|
||||
|
|
|
@ -12,7 +12,7 @@ proc generatePrestate*(nimbus, geth: JsonNode, blockNumber: UInt256, parent, hea
|
|||
memoryDB = newMemoryDB()
|
||||
chainDB = newBaseChainDB(memoryDB, false)
|
||||
|
||||
chainDB.setHead(parent, true)
|
||||
discard chainDB.setHead(parent, true)
|
||||
discard chainDB.persistTransactions(blockNumber, body.transactions)
|
||||
discard chainDB.persistUncles(body.uncles)
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ proc dumpTest(chainDB: BaseChainDB, blockNumber: int) =
|
|||
headers = @[header]
|
||||
bodies = @[blockBody]
|
||||
|
||||
captureChainDB.setHead(parent, true)
|
||||
discard captureChainDB.setHead(parent, true)
|
||||
discard chain.persistBlocks(headers, bodies)
|
||||
|
||||
var metaData = %{
|
||||
|
|
|
@ -34,7 +34,8 @@ proc testFixture(node: JsonNode, testStatusIMPL: var TestStatus) =
|
|||
headers = @[header]
|
||||
bodies = @[blockBody]
|
||||
|
||||
chainDB.setHead(parent, true)
|
||||
# it's ok if setHead fails here because of missing ancestors
|
||||
discard chainDB.setHead(parent, true)
|
||||
let validationResult = chain.persistBlocks(headers, bodies)
|
||||
check validationResult == ValidationResult.OK
|
||||
|
||||
|
|
Loading…
Reference in New Issue