diff --git a/nimbus/constants.nim b/nimbus/constants.nim index 12d7ca928..6a254844e 100644 --- a/nimbus/constants.nim +++ b/nimbus/constants.nim @@ -45,6 +45,7 @@ const GENESIS_MIX_HASH* = ZERO_HASH32 GENESIS_EXTRA_DATA* = "" GAS_LIMIT_MINIMUM* = 5000 + GAS_LIMIT_MAXIMUM* = high(GasInt) BLANK_ROOT_HASH* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".toDigest EMPTY_SHA3* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".toDigest diff --git a/nimbus/utils/header.nim b/nimbus/utils/header.nim index ae466d543..0775ef209 100644 --- a/nimbus/utils/header.nim +++ b/nimbus/utils/header.nim @@ -18,12 +18,14 @@ proc hasUncles*(header: BlockHeader): bool = header.ommersHash != EMPTY_UNCLE_HA proc `$`*(header: BlockHeader): string = result = &"BlockHeader(timestamp: {header.timestamp} difficulty: {header.difficulty} blockNumber: {header.blockNumber} gasLimit: {header.gasLimit})" -proc gasLimitBounds*(parent: BlockHeader): (GasInt, GasInt) = +proc gasLimitBounds*(parent: BlockHeader): (Uint256, Uint256) = ## Compute the boundaries for the block gas limit based on the parent block. let - boundaryRange = parent.gasLimit div GAS_LIMIT_ADJUSTMENT_FACTOR - upperBound = parent.gasLimit + boundaryRange - lowerBound = max(GAS_LIMIT_MINIMUM, parent.gasLimit - boundaryRange) + gasLimit = parent.gasLimit.u256 + boundaryRange = (parent.gasLimit div GAS_LIMIT_ADJUSTMENT_FACTOR).u256 + upperBound = gasLimit + boundaryRange + lowerBound = max(GAS_LIMIT_MINIMUM.u256, gasLimit - boundaryRange) + return (lowerBound, upperBound) proc computeGasLimit*(parent: BlockHeader, gasLimitFloor: GasInt): GasInt = diff --git a/tests/test_blockchain_json.nim b/tests/test_blockchain_json.nim index 7cbdfdb1a..9caccbab6 100644 --- a/tests/test_blockchain_json.nim +++ b/tests/test_blockchain_json.nim @@ -307,6 +307,8 @@ func validateSeal(header: BlockHeader) = func validateGasLimit(gasLimit, parentGasLimit: GasInt) = if gasLimit < GAS_LIMIT_MINIMUM: raise newException(ValidationError, "Gas limit is below minimum") + if gasLimit > GAS_LIMIT_MAXIMUM: + raise newException(ValidationError, "Gas limit is above maximum") let diff = gasLimit - parentGasLimit if diff > (parentGasLimit div GAS_LIMIT_ADJUSTMENT_FACTOR): raise newException(ValidationError, "Gas limit difference to parent is too big") @@ -343,10 +345,10 @@ proc validateGasLimit(chainDB: BaseChainDB, header: BlockHeader) = let parentHeader = chainDB.getBlockHeader(header.parentHash) let (lowBound, highBound) = gasLimitBounds(parentHeader) - if header.gasLimit < lowBound: - raise newException(ValidationError, "The gas limit is too low") - elif header.gasLimit > highBound: - raise newException(ValidationError, "The gas limit is too high") + if header.gasLimit.u256 < lowBound: + raise newException(ValidationError, "The gas limit is too low") + elif header.gasLimit.u256 > highBound: + raise newException(ValidationError, "The gas limit is too high") proc validateUncles(chainDB: BaseChainDB, currBlock: PlainBlock, checkSeal: bool) = let hasUncles = currBlock.uncles.len > 0 @@ -407,37 +409,19 @@ proc validateBlock(chainDB: BaseChainDB, currBlock: PlainBlock, checkSeal: bool) if currBlock.isGenesis: if currBlock.header.extraData.len > 32: raise newException(ValidationError, "BlockHeader.extraData larger than 32 bytes") - else: - let parentHeader = chainDB.getBlockHeader(currBlock.header.parentHash) - validateHeader(currBlock.header, parentHeader, checkSeal) + + let parentHeader = chainDB.getBlockHeader(currBlock.header.parentHash) + validateHeader(currBlock.header, parentHeader, checkSeal) if currBlock.uncles.len > MAX_UNCLES: raise newException(ValidationError, "Number of uncles exceed limit.") -#[ -if not self.chaindb.exists(block.header.state_root): - raise newException(ValidationError, - "`state_root` was not found in the db.\n" - "- state_root: {0}".format( - block.header.state_root, - ) - ) - local_uncle_hash = keccak(rlp.encode(block.uncles)) - if local_uncle_hash != block.header.uncles_hash: - raise newException(ValidationError, - "`uncles_hash` and block `uncles` do not match.\n" - " - num_uncles : {0}\n" - " - block uncle_hash : {1}\n" - " - header uncle_hash: {2}".format( - len(block.uncles), - local_uncle_hash, - block.header.uncles_hash, - ) - ) -]# - #VM_class.validate_header(block.header, parent_block.header, check_seal=True) - # self.validate_uncles(block) - # self.validate_gaslimit(block.header) + if not chainDB.exists(currBlock.header.stateRoot): + raise newException(ValidationError, "`state_root` was not found in the db.") + + validateUncles(chainDB, currBlock, checkSeal) + validateGaslimit(chainDB, currBlock.header) + result = true proc importBlock(chainDB: BaseChainDB, preminedBlock: PlainBlock, fork: Fork, checkSeal: bool, validation = true): PlainBlock = @@ -447,8 +431,9 @@ proc importBlock(chainDB: BaseChainDB, preminedBlock: PlainBlock, fork: Fork, ch deepCopy(result, preminedBlock) var vmState = newBaseVMState(parentHeader.stateRoot, baseHeaderForImport, chainDB) + processBlock(vmState, result, fork) - result.header = vmState.blockHeader + result.header.stateRoot = vmState.blockHeader.stateRoot result.header.parentHash = parentHeader.hash if validation: @@ -468,7 +453,8 @@ proc applyFixtureBlockToChain(tb: TesterBlock, result = (preminedBlock, minedBlock, rlpEncodedMinedBlock) func shouldCheckSeal(tester: Tester): bool = - result = false + if tester.sealEngine.isSome: + result = tester.sealEngine.get() != NoProof proc runTester(tester: Tester, chainDB: BaseChainDB, testStatusIMPL: var TestStatus) = discard chainDB.persistHeaderToDb(tester.genesisBlockHeader)