2021-05-18 11:18:15 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2018 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
|
|
|
|
import
|
2021-06-24 15:29:21 +00:00
|
|
|
std/[sequtils, sets, tables, times],
|
2021-05-18 11:18:15 +00:00
|
|
|
../constants,
|
|
|
|
../db/[db_chain, accounts_cache],
|
|
|
|
../transaction,
|
|
|
|
../utils,
|
2021-06-24 15:29:21 +00:00
|
|
|
../utils/[difficulty, header],
|
2021-05-18 11:18:15 +00:00
|
|
|
../vm_state,
|
|
|
|
../vm_types,
|
2021-06-01 10:54:13 +00:00
|
|
|
../forks,
|
2021-06-24 15:29:21 +00:00
|
|
|
./dao,
|
2021-05-21 11:33:38 +00:00
|
|
|
./validate/epoch_hash_cache,
|
2021-06-29 07:41:01 +00:00
|
|
|
./gaslimit,
|
2021-05-18 11:18:15 +00:00
|
|
|
chronicles,
|
2021-05-19 10:40:03 +00:00
|
|
|
eth/[common, rlp, trie/trie_defs],
|
2021-05-18 11:18:15 +00:00
|
|
|
ethash,
|
|
|
|
nimcrypto,
|
|
|
|
options,
|
2021-06-24 15:29:21 +00:00
|
|
|
stew/[results, endians2]
|
|
|
|
|
|
|
|
from stew/byteutils
|
|
|
|
import nil
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
export
|
2021-05-21 11:33:38 +00:00
|
|
|
epoch_hash_cache.EpochHashCache,
|
|
|
|
epoch_hash_cache.initEpochHashCache,
|
2021-05-19 10:40:03 +00:00
|
|
|
results
|
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
const
|
|
|
|
daoForkBlockExtraData =
|
|
|
|
byteutils.hexToByteArray[13](DAOForkBlockExtra).toSeq
|
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
type
|
|
|
|
MiningHeader = object
|
|
|
|
parentHash : Hash256
|
|
|
|
ommersHash : Hash256
|
|
|
|
coinbase : EthAddress
|
|
|
|
stateRoot : Hash256
|
|
|
|
txRoot : Hash256
|
|
|
|
receiptRoot : Hash256
|
|
|
|
bloom : common.BloomFilter
|
|
|
|
difficulty : DifficultyInt
|
|
|
|
blockNumber : BlockNumber
|
|
|
|
gasLimit : GasInt
|
|
|
|
gasUsed : GasInt
|
|
|
|
timestamp : EthTime
|
|
|
|
extraData : Blob
|
|
|
|
|
|
|
|
Hash512 = MDigest[512]
|
|
|
|
|
2021-05-25 17:38:39 +00:00
|
|
|
{.push raises: [Defect,CatchableError].}
|
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
2021-05-19 10:40:03 +00:00
|
|
|
# Private Helpers
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
func toMiningHeader(header: BlockHeader): MiningHeader =
|
|
|
|
result.parentHash = header.parentHash
|
|
|
|
result.ommersHash = header.ommersHash
|
|
|
|
result.coinbase = header.coinbase
|
|
|
|
result.stateRoot = header.stateRoot
|
|
|
|
result.txRoot = header.txRoot
|
|
|
|
result.receiptRoot = header.receiptRoot
|
|
|
|
result.bloom = header.bloom
|
|
|
|
result.difficulty = header.difficulty
|
|
|
|
result.blockNumber = header.blockNumber
|
|
|
|
result.gasLimit = header.gasLimit
|
|
|
|
result.gasUsed = header.gasUsed
|
|
|
|
result.timestamp = header.timestamp
|
|
|
|
result.extraData = header.extraData
|
|
|
|
|
|
|
|
|
|
|
|
func hash(header: MiningHeader): Hash256 =
|
|
|
|
keccakHash(rlp.encode(header))
|
|
|
|
|
|
|
|
func isGenesis(header: BlockHeader): bool =
|
|
|
|
header.blockNumber == 0.u256 and
|
|
|
|
header.parentHash == GENESIS_PARENT_HASH
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Private cache management functions
|
2021-05-18 11:18:15 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2021-05-20 12:07:01 +00:00
|
|
|
func cacheHash(x: EpochHashDigest): Hash256 =
|
2021-05-18 11:18:15 +00:00
|
|
|
var ctx: keccak256
|
|
|
|
ctx.init()
|
|
|
|
|
|
|
|
for a in x:
|
|
|
|
ctx.update(a.data[0].unsafeAddr, uint(a.data.len))
|
|
|
|
|
|
|
|
ctx.finish result.data
|
|
|
|
ctx.clear()
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Pivate validator functions
|
|
|
|
# ------------------------------------------------------------------------------
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
proc checkPOW(blockNumber: Uint256; miningHash, mixHash: Hash256;
|
|
|
|
nonce: BlockNonce; difficulty: DifficultyInt;
|
2021-05-21 11:33:38 +00:00
|
|
|
hashCache: var EpochHashCache): Result[void,string] =
|
2021-05-19 10:40:03 +00:00
|
|
|
let
|
|
|
|
blockNumber = blockNumber.truncate(uint64)
|
2021-05-21 11:33:38 +00:00
|
|
|
cache = hashCache.getEpochHash(blockNumber)
|
2021-05-19 10:40:03 +00:00
|
|
|
size = getDataSize(blockNumber)
|
|
|
|
miningOutput = hashimotoLight(
|
|
|
|
size, cache, miningHash, uint64.fromBytesBE(nonce))
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if miningOutput.mixDigest != mixHash:
|
2021-05-19 10:40:03 +00:00
|
|
|
debug "mixHash mismatch",
|
|
|
|
actual = miningOutput.mixDigest,
|
|
|
|
expected = mixHash,
|
|
|
|
blockNumber = blockNumber,
|
|
|
|
miningHash = miningHash,
|
|
|
|
nonce = nonce.toHex,
|
|
|
|
difficulty = difficulty,
|
|
|
|
size = size,
|
|
|
|
cachedHash = cacheHash(cache)
|
|
|
|
return err("mixHash mismatch")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
let value = Uint256.fromBytesBE(miningOutput.value.data)
|
|
|
|
if value > Uint256.high div difficulty:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("mining difficulty error")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
result = ok()
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
|
2021-05-21 11:33:38 +00:00
|
|
|
proc validateSeal(hashCache: var EpochHashCache;
|
2021-05-19 10:40:03 +00:00
|
|
|
header: BlockHeader): Result[void,string] =
|
2021-05-18 11:18:15 +00:00
|
|
|
let miningHeader = header.toMiningHeader
|
|
|
|
let miningHash = miningHeader.hash
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
checkPOW(header.blockNumber, miningHash,
|
2021-05-21 11:33:38 +00:00
|
|
|
header.mixDigest, header.nonce, header.difficulty, hashCache)
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
proc validateHeader(db: BaseChainDB; header, parentHeader: BlockHeader;
|
|
|
|
numTransactions: int; checkSealOK: bool;
|
|
|
|
hashCache: var EpochHashCache): Result[void,string] =
|
2021-10-12 04:06:39 +00:00
|
|
|
|
|
|
|
template inDAOExtraRange(blockNumber: BlockNumber): bool =
|
|
|
|
# EIP-799
|
|
|
|
# Blocks with block numbers in the range [1_920_000, 1_920_009]
|
|
|
|
# MUST have DAOForkBlockExtra
|
|
|
|
let DAOHigh = db.config.daoForkBlock + DAOForkExtraRange.u256
|
|
|
|
db.config.daoForkBlock <= blockNumber and
|
|
|
|
blockNumber < DAOHigh
|
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
if header.extraData.len > 32:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("BlockHeader.extraData larger than 32 bytes")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
if header.gasUsed == 0 and 0 < numTransactions:
|
|
|
|
return err("zero gasUsed but tranactions present");
|
|
|
|
|
2021-06-30 09:42:55 +00:00
|
|
|
if header.gasUsed < 0 or header.gasUsed > header.gasLimit:
|
|
|
|
return err("gasUsed should be non negative and smaller or equal gasLimit")
|
2021-09-28 15:16:15 +00:00
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
if header.blockNumber != parentHeader.blockNumber + 1:
|
2021-06-24 15:29:21 +00:00
|
|
|
return err("Blocks must be numbered consecutively")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if header.timestamp.toUnix <= parentHeader.timestamp.toUnix:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("timestamp must be strictly later than parent")
|
|
|
|
|
2021-10-12 04:06:39 +00:00
|
|
|
if db.config.daoForkSupport and inDAOExtraRange(header.blockNumber):
|
|
|
|
if header.extraData != daoForkBlockExtraData:
|
|
|
|
return err("header extra data should be marked DAO")
|
2021-06-24 15:29:21 +00:00
|
|
|
|
|
|
|
let calcDiffc = db.config.calcDifficulty(header.timestamp, parentHeader)
|
|
|
|
if header.difficulty < calcDiffc:
|
|
|
|
return err("provided header difficulty is too low")
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if checkSealOK:
|
2021-05-21 11:33:38 +00:00
|
|
|
return hashCache.validateSeal(header)
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
result = ok()
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
func validateUncle(currBlock, uncle, uncleParent: BlockHeader):
|
|
|
|
Result[void,string] =
|
2021-05-18 11:18:15 +00:00
|
|
|
if uncle.blockNumber >= currBlock.blockNumber:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("uncle block number larger than current block number")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if uncle.blockNumber != uncleParent.blockNumber + 1:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Uncle number is not one above ancestor's number")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if uncle.timestamp.toUnix < uncleParent.timestamp.toUnix:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Uncle timestamp is before ancestor's timestamp")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if uncle.gasUsed > uncle.gasLimit:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Uncle's gas usage is above the limit")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
result = ok()
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
proc validateUncles(chainDB: BaseChainDB; header: BlockHeader;
|
|
|
|
uncles: seq[BlockHeader]; checkSealOK: bool;
|
2021-05-21 11:33:38 +00:00
|
|
|
hashCache: var EpochHashCache): Result[void,string] =
|
2021-05-19 10:40:03 +00:00
|
|
|
let hasUncles = uncles.len > 0
|
|
|
|
let shouldHaveUncles = header.ommersHash != EMPTY_UNCLE_HASH
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if not hasUncles and not shouldHaveUncles:
|
|
|
|
# optimization to avoid loading ancestors from DB, since the block has
|
|
|
|
# no uncles
|
2021-05-19 10:40:03 +00:00
|
|
|
return ok()
|
|
|
|
if hasUncles and not shouldHaveUncles:
|
|
|
|
return err("Block has uncles but header suggests uncles should be empty")
|
|
|
|
if shouldHaveUncles and not hasUncles:
|
|
|
|
return err("Header suggests block should have uncles but block has none")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
# Check for duplicates
|
|
|
|
var uncleSet = initHashSet[Hash256]()
|
2021-05-19 10:40:03 +00:00
|
|
|
for uncle in uncles:
|
2021-07-30 14:06:51 +00:00
|
|
|
let uncleHash = uncle.blockHash
|
2021-05-18 11:18:15 +00:00
|
|
|
if uncleHash in uncleSet:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Block contains duplicate uncles")
|
2021-05-18 11:18:15 +00:00
|
|
|
else:
|
|
|
|
uncleSet.incl uncleHash
|
|
|
|
|
|
|
|
let recentAncestorHashes = chainDB.getAncestorsHashes(
|
2021-05-19 10:40:03 +00:00
|
|
|
MAX_UNCLE_DEPTH + 1, header)
|
2021-05-18 11:18:15 +00:00
|
|
|
let recentUncleHashes = chainDB.getUncleHashes(recentAncestorHashes)
|
2021-07-30 14:06:51 +00:00
|
|
|
let blockHash = header.blockHash
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
for uncle in uncles:
|
2021-07-30 14:06:51 +00:00
|
|
|
let uncleHash = uncle.blockHash
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
if uncleHash == blockHash:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Uncle has same hash as block")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
# ensure the uncle has not already been included.
|
|
|
|
if uncleHash in recentUncleHashes:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Duplicate uncle")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
# ensure that the uncle is not one of the canonical chain blocks.
|
|
|
|
if uncleHash in recentAncestorHashes:
|
2021-05-19 10:40:03 +00:00
|
|
|
return err("Uncle cannot be an ancestor")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
# ensure that the uncle was built off of one of the canonical chain
|
|
|
|
# blocks.
|
|
|
|
if (uncle.parentHash notin recentAncestorHashes) or
|
2021-05-19 10:40:03 +00:00
|
|
|
(uncle.parentHash == header.parentHash):
|
|
|
|
return err("Uncle's parent is not an ancestor")
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-18 07:37:59 +00:00
|
|
|
# check uncle against own parent
|
|
|
|
var parent: BlockHeader
|
|
|
|
if not chainDB.getBlockHeader(uncle.parentHash,parent):
|
|
|
|
return err("Uncle's parent has gone missing")
|
|
|
|
if uncle.timestamp <= parent.timestamp:
|
|
|
|
return err("Uncle's parent must me older")
|
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
# Now perform VM level validation of the uncle
|
2021-05-19 10:40:03 +00:00
|
|
|
if checkSealOK:
|
2021-05-21 11:33:38 +00:00
|
|
|
result = hashCache.validateSeal(uncle)
|
2021-05-19 10:40:03 +00:00
|
|
|
if result.isErr:
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
let uncleParent = chainDB.getBlockHeader(uncle.parentHash)
|
2021-05-19 10:40:03 +00:00
|
|
|
result = validateUncle(header, uncle, uncleParent)
|
|
|
|
if result.isErr:
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-30 13:30:39 +00:00
|
|
|
result = chainDB.validateGasLimitOrBaseFee(uncle, uncleParent)
|
|
|
|
if result.isErr:
|
|
|
|
return
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
result = ok()
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public function, extracted from executor
|
|
|
|
# ------------------------------------------------------------------------------
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
proc validateTransaction*(vmState: BaseVMState, tx: Transaction,
|
|
|
|
sender: EthAddress, fork: Fork): bool =
|
|
|
|
let balance = vmState.readOnlyStateDB.getBalance(sender)
|
|
|
|
let nonce = vmState.readOnlyStateDB.getNonce(sender)
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-30 13:30:39 +00:00
|
|
|
if tx.txType == TxEip2930 and fork < FkBerlin:
|
|
|
|
debug "invalid tx: Eip2930 Tx type detected before Berlin"
|
|
|
|
return
|
|
|
|
|
|
|
|
if tx.txType == TxEip1559 and fork < FkLondon:
|
|
|
|
debug "invalid tx: Eip1559 Tx type detected before London"
|
|
|
|
return
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if vmState.cumulativeGasUsed + tx.gasLimit > vmState.blockHeader.gasLimit:
|
|
|
|
debug "invalid tx: block header gasLimit reached",
|
|
|
|
maxLimit=vmState.blockHeader.gasLimit,
|
|
|
|
gasUsed=vmState.cumulativeGasUsed,
|
|
|
|
addition=tx.gasLimit
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-06-30 13:30:39 +00:00
|
|
|
# ensure that the user was willing to at least pay the base fee
|
|
|
|
let baseFee = vmState.blockHeader.baseFee.truncate(GasInt)
|
|
|
|
if tx.maxFee < baseFee:
|
|
|
|
debug "invalid tx: maxFee is smaller than baseFee",
|
|
|
|
maxFee=tx.maxFee,
|
|
|
|
baseFee=baseFee
|
|
|
|
return
|
|
|
|
|
|
|
|
# The total must be the larger of the two
|
|
|
|
if tx.maxFee < tx.maxPriorityFee:
|
|
|
|
debug "invalid tx: maxFee is smaller than maPriorityFee",
|
|
|
|
maxFee=tx.maxFee,
|
|
|
|
maxPriorityFee=tx.maxPriorityFee
|
|
|
|
return
|
|
|
|
|
2021-09-28 15:16:15 +00:00
|
|
|
# the signer must be able to afford the transaction
|
|
|
|
let gasCost = if tx.txType >= TxEip1559:
|
|
|
|
tx.gasLimit.u256 * tx.maxFee.u256
|
|
|
|
else:
|
|
|
|
tx.gasLimit.u256 * tx.gasPrice.u256
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if gasCost > balance:
|
|
|
|
debug "invalid tx: not enough cash for gas",
|
|
|
|
available=balance,
|
|
|
|
require=gasCost
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if tx.value > balance - gasCost:
|
|
|
|
debug "invalid tx: not enough cash to send",
|
|
|
|
available=balance,
|
|
|
|
availableMinusGas=balance-gasCost,
|
|
|
|
require=tx.value
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if tx.gasLimit < tx.intrinsicGas(fork):
|
|
|
|
debug "invalid tx: not enough gas to perform calculation",
|
|
|
|
available=tx.gasLimit,
|
|
|
|
require=tx.intrinsicGas(fork)
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
if tx.nonce != nonce:
|
|
|
|
debug "invalid tx: account nonce mismatch",
|
|
|
|
txNonce=tx.nonce,
|
|
|
|
accountNonce=nonce
|
|
|
|
return
|
2021-05-18 11:18:15 +00:00
|
|
|
|
|
|
|
result = true
|
|
|
|
|
2021-05-19 10:40:03 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Public functions, extracted from test_blockchain_json
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
proc validateHeaderAndKinship*(chainDB: BaseChainDB; header: BlockHeader;
|
|
|
|
uncles: seq[BlockHeader]; numTransactions: int; checkSealOK: bool;
|
|
|
|
hashCache: var EpochHashCache): Result[void,string] =
|
2021-05-19 10:40:03 +00:00
|
|
|
if header.isGenesis:
|
|
|
|
if header.extraData.len > 32:
|
|
|
|
return err("BlockHeader.extraData larger than 32 bytes")
|
|
|
|
return ok()
|
|
|
|
|
2021-06-29 07:41:01 +00:00
|
|
|
let parent = chainDB.getBlockHeader(header.parentHash)
|
2021-06-24 15:29:21 +00:00
|
|
|
result = chainDB.validateHeader(
|
2021-06-29 07:41:01 +00:00
|
|
|
header, parent, numTransactions, checkSealOK, hashCache)
|
2021-05-19 10:40:03 +00:00
|
|
|
if result.isErr:
|
|
|
|
return
|
|
|
|
|
|
|
|
if uncles.len > MAX_UNCLES:
|
|
|
|
return err("Number of uncles exceed limit.")
|
|
|
|
|
|
|
|
if not chainDB.exists(header.stateRoot):
|
|
|
|
return err("`state_root` was not found in the db.")
|
|
|
|
|
2021-05-21 11:33:38 +00:00
|
|
|
result = chainDB.validateUncles(header, uncles, checkSealOK, hashCache)
|
2021-05-19 10:40:03 +00:00
|
|
|
if result.isOk:
|
2021-06-29 07:41:01 +00:00
|
|
|
result = chainDB.validateGasLimitOrBaseFee(header, parent)
|
2021-05-19 10:40:03 +00:00
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
|
|
|
|
proc validateHeaderAndKinship*(chainDB: BaseChainDB;
|
|
|
|
header: BlockHeader; body: BlockBody; checkSealOK: bool;
|
|
|
|
hashCache: var EpochHashCache): Result[void,string] =
|
|
|
|
chainDB.validateHeaderAndKinship(
|
|
|
|
header, body.uncles, body.transactions.len, checkSealOK, hashCache)
|
|
|
|
|
|
|
|
|
|
|
|
proc validateHeaderAndKinship*(chainDB: BaseChainDB; ethBlock: EthBlock;
|
|
|
|
checkSealOK: bool; hashCache: var EpochHashCache): Result[void,string] =
|
|
|
|
chainDB.validateHeaderAndKinship(
|
|
|
|
ethBlock.header, ethBlock.uncles, ethBlock.txs.len, checkSealOK, hashCache)
|
|
|
|
|
2021-05-18 11:18:15 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# End
|
|
|
|
# ------------------------------------------------------------------------------
|