fix markCanonicalChain bug

This commit is contained in:
jangko 2022-07-04 12:35:56 +07:00
parent ce098bf88f
commit 709d8ef255
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
8 changed files with 37 additions and 13 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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):

View File

@ -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)

View File

@ -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 = %{

View File

@ -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