add validateKinship in persistBlocks of nimbus/p2p/chain.nim

put jordan's work #668 into effect, and this bring down
failing consensus test cases from 59 to 44
This commit is contained in:
jangko 2021-05-27 13:59:45 +07:00
parent 2539bd9904
commit 5fc57e4093
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 20 additions and 3 deletions

View File

@ -25,7 +25,7 @@ proc importRlpBlock*(importFile: string, chainDB: BasechainDB): bool =
error "failed to import", fileName = importFile error "failed to import", fileName = importFile
return false return false
var chain = newChain(chainDB) var chain = newChain(chainDB, extraValidation = true)
# the encoded rlp can contains one or more blocks # the encoded rlp can contains one or more blocks
var rlp = rlpFromBytes(res.get) var rlp = rlpFromBytes(res.get)
let head = chainDB.getCanonicalHead() let head = chainDB.getCanonicalHead()

View File

@ -1,7 +1,7 @@
import ../db/db_chain, eth/common, chronicles, ../vm_state, ../vm_types, import ../db/db_chain, eth/common, chronicles, ../vm_state, ../vm_types,
../vm_computation, ../vm_message, ../vm_types2, stint, nimcrypto, ../vm_computation, ../vm_message, ../vm_types2, stint, nimcrypto,
../utils, eth/trie/db, ./executor, ../chain_config, ../genesis, ../utils, ../utils, eth/trie/db, ./executor, ../chain_config, ../genesis, ../utils,
stew/endians2 stew/endians2, ./validate, ./validate/epoch_hash_cache
when not defined(release): when not defined(release):
import ../tracer import ../tracer
@ -25,6 +25,8 @@ type
db: BaseChainDB db: BaseChainDB
forkIds: array[ChainFork, ForkID] forkIds: array[ChainFork, ForkID]
blockZeroHash: KeccakHash blockZeroHash: KeccakHash
cacheByEpoch: EpochHashCache
extraValidation: bool
func toChainFork(c: ChainConfig, number: BlockNumber): ChainFork = func toChainFork(c: ChainConfig, number: BlockNumber): ChainFork =
if number >= c.berlinBlock: Berlin if number >= c.berlinBlock: Berlin
@ -87,7 +89,7 @@ func calculateForkIds(c: ChainConfig, genesisCRC: uint32): array[ChainFork, Fork
prevFork = result[fork].nextFork prevFork = result[fork].nextFork
prevCRC = result[fork].crc prevCRC = result[fork].crc
proc newChain*(db: BaseChainDB): Chain = proc newChain*(db: BaseChainDB, extraValidation = false): Chain =
result.new result.new
result.db = db result.db = db
@ -97,6 +99,10 @@ proc newChain*(db: BaseChainDB): Chain =
result.blockZeroHash = g.toBlock.blockHash result.blockZeroHash = g.toBlock.blockHash
let genesisCRC = crc32(0, result.blockZeroHash.data) let genesisCRC = crc32(0, result.blockZeroHash.data)
result.forkIds = calculateForkIds(db.config, genesisCRC) result.forkIds = calculateForkIds(db.config, genesisCRC)
result.extraValidation = extraValidation
if extraValidation:
result.cacheByEpoch.initEpochHashCache
method genesisHash*(c: Chain): KeccakHash {.gcsafe.} = method genesisHash*(c: Chain): KeccakHash {.gcsafe.} =
c.blockZeroHash c.blockZeroHash
@ -149,6 +155,17 @@ method persistBlocks*(c: Chain, headers: openarray[BlockHeader], bodies: openarr
if validationResult != ValidationResult.OK: if validationResult != ValidationResult.OK:
return validationResult return validationResult
if c.extraValidation:
let res = validateKinship(
c.db, headers[i],
bodies[i].uncles,
checkSealOK = false, # TODO: how to checkseal from here
c.cacheByEpoch
)
if res.isErr:
debug "kinship validation error", msg = res.error
return ValidationResult.Error
discard c.db.persistHeaderToDb(headers[i]) discard c.db.persistHeaderToDb(headers[i])
if c.db.getCanonicalHead().blockHash != headers[i].blockHash: if c.db.getCanonicalHead().blockHash != headers[i].blockHash:
debug "Stored block header hash doesn't match declared hash" debug "Stored block header hash doesn't match declared hash"