@ethereumjs/block
Advanced tools
Comparing version 3.4.0 to 3.5.0
"use strict"; | ||
/* eslint-disable no-dupe-class-members */ | ||
var __assign = (this && this.__assign) || function () { | ||
@@ -81,2 +80,3 @@ __assign = Object.assign || function(t) { | ||
var ethereumjs_util_1 = require("ethereumjs-util"); | ||
var common_1 = require("@ethereumjs/common"); | ||
var tx_1 = require("@ethereumjs/tx"); | ||
@@ -104,4 +104,9 @@ var header_1 = require("./header"); | ||
this._common = this.header._common; | ||
if (this._common.consensusType() === 'poa' && uncleHeaders.length > 0) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed'); | ||
if (uncleHeaders.length > 0) { | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfAuthority) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed'); | ||
} | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfStake) { | ||
throw new Error('Block initialization with uncleHeaders on a PoS network is not allowed'); | ||
} | ||
} | ||
@@ -144,11 +149,14 @@ var freeze = (_a = opts === null || opts === void 0 ? void 0 : opts.freeze) !== null && _a !== void 0 ? _a : true; | ||
var uncleHeaders = []; | ||
var uncleOpts = __assign(__assign({ hardforkByBlockNumber: true }, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }); | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber; | ||
} | ||
try { | ||
for (var _e = __values(uhsData !== null && uhsData !== void 0 ? uhsData : []), _f = _e.next(); !_f.done; _f = _e.next()) { | ||
var uhData = _f.value; | ||
var uh = header_1.BlockHeader.fromHeaderData(uhData, __assign(__assign({}, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites | ||
// the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined })); | ||
var uh = header_1.BlockHeader.fromHeaderData(uhData, uncleOpts); | ||
uncleHeaders.push(uh); | ||
@@ -211,10 +219,14 @@ } | ||
var uncleHeaders = []; | ||
var uncleOpts = __assign(__assign({ hardforkByBlockNumber: true }, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }); | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber; | ||
} | ||
try { | ||
for (var _f = __values(uhsData || []), _g = _f.next(); !_g.done; _g = _f.next()) { | ||
var uncleHeaderData = _g.value; | ||
uncleHeaders.push(header_1.BlockHeader.fromValuesArray(uncleHeaderData, __assign(__assign({}, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }))); | ||
uncleHeaders.push(header_1.BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts)); | ||
} | ||
@@ -424,3 +436,3 @@ } | ||
var raw = ethereumjs_util_1.rlp.encode(this.uncleHeaders.map(function (uh) { return uh.raw(); })); | ||
return ethereumjs_util_1.keccak256(raw).equals(this.header.uncleHash); | ||
return (0, ethereumjs_util_1.keccak256)(raw).equals(this.header.uncleHash); | ||
}; | ||
@@ -427,0 +439,0 @@ /** |
@@ -27,6 +27,6 @@ "use strict"; | ||
// check and convert gasPrice and value params | ||
txParams.gasPrice = helpers_1.numberToHex(txParams.gasPrice); | ||
txParams.value = helpers_1.numberToHex(txParams.value); | ||
txParams.gasPrice = (0, helpers_1.numberToHex)(txParams.gasPrice); | ||
txParams.value = (0, helpers_1.numberToHex)(txParams.value); | ||
// strict byte length checking | ||
txParams.to = txParams.to ? ethereumjs_util_1.setLengthLeft(ethereumjs_util_1.toBuffer(txParams.to), 20) : null; | ||
txParams.to = txParams.to ? (0, ethereumjs_util_1.setLengthLeft)((0, ethereumjs_util_1.toBuffer)(txParams.to), 20) : null; | ||
// v as raw signature value {0,1} | ||
@@ -49,3 +49,3 @@ // v is the recovery bit and can be either {0,1} or {27,28}. | ||
if (uncles === void 0) { uncles = []; } | ||
var header = header_from_rpc_1.default(blockParams, options); | ||
var header = (0, header_from_rpc_1.default)(blockParams, options); | ||
var transactions = []; | ||
@@ -70,3 +70,3 @@ if (blockParams.transactions) { | ||
} | ||
var uncleHeaders = uncles.map(function (uh) { return header_from_rpc_1.default(uh, options); }); | ||
var uncleHeaders = uncles.map(function (uh) { return (0, header_from_rpc_1.default)(uh, options); }); | ||
return index_1.Block.fromBlockData({ header: header, transactions: transactions, uncleHeaders: uncleHeaders }, options); | ||
@@ -73,0 +73,0 @@ } |
@@ -27,3 +27,3 @@ "use strict"; | ||
bloom: logsBloom, | ||
difficulty: helpers_1.numberToHex(difficulty), | ||
difficulty: (0, helpers_1.numberToHex)(difficulty), | ||
number: number, | ||
@@ -30,0 +30,0 @@ gasLimit: gasLimit, |
@@ -5,3 +5,3 @@ /// <reference types="node" /> | ||
import { Address, BN } from 'ethereumjs-util'; | ||
import { HeaderData, JsonHeader, BlockHeaderBuffer, Blockchain, BlockOptions } from './types'; | ||
import { Blockchain, BlockHeaderBuffer, BlockOptions, HeaderData, JsonHeader } from './types'; | ||
/** | ||
@@ -29,2 +29,3 @@ * An object that represents the block header. | ||
_errorPostfix: string; | ||
private cache; | ||
/** | ||
@@ -31,0 +32,0 @@ * Static constructor to create a block header from a header data dictionary |
@@ -13,2 +13,21 @@ "use strict"; | ||
}; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -66,8 +85,5 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BlockHeader = void 0; | ||
var common_1 = __importDefault(require("@ethereumjs/common")); | ||
var common_1 = __importStar(require("@ethereumjs/common")); | ||
var ethereumjs_util_1 = require("ethereumjs-util"); | ||
@@ -89,4 +105,7 @@ var clique_1 = require("./clique"); | ||
if (options === void 0) { options = {}; } | ||
var _a; | ||
var _a, _b; | ||
this._errorPostfix = ''; | ||
this.cache = { | ||
hash: undefined, | ||
}; | ||
if (options.common) { | ||
@@ -96,5 +115,5 @@ this._common = options.common.copy(); | ||
else { | ||
var chain = 'mainnet'; // default | ||
var chain = common_1.Chain.Mainnet; // default | ||
if (options.initWithGenesisHeader) { | ||
this._common = new common_1.default({ chain: chain, hardfork: 'chainstart' }); | ||
this._common = new common_1.default({ chain: chain, hardfork: common_1.Hardfork.Chainstart }); | ||
} | ||
@@ -106,5 +125,9 @@ else { | ||
} | ||
if (options.hardforkByBlockNumber) { | ||
this._common.setHardforkByBlockNumber(number.toNumber()); | ||
if (options.hardforkByBlockNumber !== undefined && options.hardforkByTD !== undefined) { | ||
throw new Error("The hardforkByBlockNumber and hardforkByTD options can't be used in conjunction"); | ||
} | ||
var hardforkByBlockNumber = (_a = options.hardforkByBlockNumber) !== null && _a !== void 0 ? _a : false; | ||
if (hardforkByBlockNumber || options.hardforkByTD) { | ||
this._common.setHardforkByBlockNumber(number.toNumber(), options.hardforkByTD); | ||
} | ||
if (this._common.isActivatedEIP(1559)) { | ||
@@ -123,18 +146,18 @@ if (baseFeePerGas === undefined) { | ||
if (gasLimit.eq(DEFAULT_GAS_LIMIT)) { | ||
gasLimit = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().gasLimit)); | ||
gasLimit = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().gasLimit)); | ||
} | ||
if (timestamp.isZero()) { | ||
timestamp = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().timestamp)); | ||
timestamp = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().timestamp)); | ||
} | ||
if (difficulty.isZero()) { | ||
difficulty = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().difficulty)); | ||
difficulty = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().difficulty)); | ||
} | ||
if (extraData.length === 0) { | ||
extraData = ethereumjs_util_1.toBuffer(this._common.genesis().extraData); | ||
extraData = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().extraData); | ||
} | ||
if (nonce.equals(ethereumjs_util_1.zeros(8))) { | ||
nonce = ethereumjs_util_1.toBuffer(this._common.genesis().nonce); | ||
if (nonce.equals((0, ethereumjs_util_1.zeros)(8))) { | ||
nonce = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().nonce); | ||
} | ||
if (stateRoot.equals(ethereumjs_util_1.zeros(32))) { | ||
stateRoot = ethereumjs_util_1.toBuffer(this._common.genesis().stateRoot); | ||
if (stateRoot.equals((0, ethereumjs_util_1.zeros)(32))) { | ||
stateRoot = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().stateRoot); | ||
} | ||
@@ -163,3 +186,4 @@ } | ||
// block option parameter, we instead set difficulty to this value. | ||
if (options.calcDifficultyFromHeader) { | ||
if (options.calcDifficultyFromHeader && | ||
this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) { | ||
this.difficulty = this.canonicalDifficulty(options.calcDifficultyFromHeader); | ||
@@ -178,3 +202,3 @@ } | ||
this._errorPostfix = "block number=" + this.number.toNumber() + " hash=" + this.hash().toString('hex'); | ||
var freeze = (_a = options === null || options === void 0 ? void 0 : options.freeze) !== null && _a !== void 0 ? _a : true; | ||
var freeze = (_b = options === null || options === void 0 ? void 0 : options.freeze) !== null && _b !== void 0 ? _b : true; | ||
if (freeze) { | ||
@@ -194,3 +218,3 @@ Object.freeze(this); | ||
var parentHash = headerData.parentHash, uncleHash = headerData.uncleHash, coinbase = headerData.coinbase, stateRoot = headerData.stateRoot, transactionsTrie = headerData.transactionsTrie, receiptTrie = headerData.receiptTrie, bloom = headerData.bloom, difficulty = headerData.difficulty, number = headerData.number, gasLimit = headerData.gasLimit, gasUsed = headerData.gasUsed, timestamp = headerData.timestamp, extraData = headerData.extraData, mixHash = headerData.mixHash, nonce = headerData.nonce, baseFeePerGas = headerData.baseFeePerGas; | ||
return new BlockHeader(parentHash ? ethereumjs_util_1.toBuffer(parentHash) : ethereumjs_util_1.zeros(32), uncleHash ? ethereumjs_util_1.toBuffer(uncleHash) : ethereumjs_util_1.KECCAK256_RLP_ARRAY, coinbase ? new ethereumjs_util_1.Address(ethereumjs_util_1.toBuffer(coinbase)) : ethereumjs_util_1.Address.zero(), stateRoot ? ethereumjs_util_1.toBuffer(stateRoot) : ethereumjs_util_1.zeros(32), transactionsTrie ? ethereumjs_util_1.toBuffer(transactionsTrie) : ethereumjs_util_1.KECCAK256_RLP, receiptTrie ? ethereumjs_util_1.toBuffer(receiptTrie) : ethereumjs_util_1.KECCAK256_RLP, bloom ? ethereumjs_util_1.toBuffer(bloom) : ethereumjs_util_1.zeros(256), difficulty ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(difficulty)) : new ethereumjs_util_1.BN(0), number ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(number)) : new ethereumjs_util_1.BN(0), gasLimit ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasLimit)) : DEFAULT_GAS_LIMIT, gasUsed ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasUsed)) : new ethereumjs_util_1.BN(0), timestamp ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(timestamp)) : new ethereumjs_util_1.BN(0), extraData ? ethereumjs_util_1.toBuffer(extraData) : Buffer.from([]), mixHash ? ethereumjs_util_1.toBuffer(mixHash) : ethereumjs_util_1.zeros(32), nonce ? ethereumjs_util_1.toBuffer(nonce) : ethereumjs_util_1.zeros(8), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(baseFeePerGas)) : undefined); | ||
return new BlockHeader(parentHash ? (0, ethereumjs_util_1.toBuffer)(parentHash) : (0, ethereumjs_util_1.zeros)(32), uncleHash ? (0, ethereumjs_util_1.toBuffer)(uncleHash) : ethereumjs_util_1.KECCAK256_RLP_ARRAY, coinbase ? new ethereumjs_util_1.Address((0, ethereumjs_util_1.toBuffer)(coinbase)) : ethereumjs_util_1.Address.zero(), stateRoot ? (0, ethereumjs_util_1.toBuffer)(stateRoot) : (0, ethereumjs_util_1.zeros)(32), transactionsTrie ? (0, ethereumjs_util_1.toBuffer)(transactionsTrie) : ethereumjs_util_1.KECCAK256_RLP, receiptTrie ? (0, ethereumjs_util_1.toBuffer)(receiptTrie) : ethereumjs_util_1.KECCAK256_RLP, bloom ? (0, ethereumjs_util_1.toBuffer)(bloom) : (0, ethereumjs_util_1.zeros)(256), difficulty ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(difficulty)) : new ethereumjs_util_1.BN(0), number ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(number)) : new ethereumjs_util_1.BN(0), gasLimit ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasLimit)) : DEFAULT_GAS_LIMIT, gasUsed ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasUsed)) : new ethereumjs_util_1.BN(0), timestamp ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(timestamp)) : new ethereumjs_util_1.BN(0), extraData ? (0, ethereumjs_util_1.toBuffer)(extraData) : Buffer.from([]), mixHash ? (0, ethereumjs_util_1.toBuffer)(mixHash) : (0, ethereumjs_util_1.zeros)(32), nonce ? (0, ethereumjs_util_1.toBuffer)(nonce) : (0, ethereumjs_util_1.zeros)(8), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(baseFeePerGas)) : undefined); | ||
}; | ||
@@ -226,3 +250,3 @@ /** | ||
} | ||
return new BlockHeader(ethereumjs_util_1.toBuffer(parentHash), ethereumjs_util_1.toBuffer(uncleHash), new ethereumjs_util_1.Address(ethereumjs_util_1.toBuffer(coinbase)), ethereumjs_util_1.toBuffer(stateRoot), ethereumjs_util_1.toBuffer(transactionsTrie), ethereumjs_util_1.toBuffer(receiptTrie), ethereumjs_util_1.toBuffer(bloom), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(difficulty)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(number)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasLimit)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasUsed)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(timestamp)), ethereumjs_util_1.toBuffer(extraData), ethereumjs_util_1.toBuffer(mixHash), ethereumjs_util_1.toBuffer(nonce), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(baseFeePerGas)) : undefined); | ||
return new BlockHeader((0, ethereumjs_util_1.toBuffer)(parentHash), (0, ethereumjs_util_1.toBuffer)(uncleHash), new ethereumjs_util_1.Address((0, ethereumjs_util_1.toBuffer)(coinbase)), (0, ethereumjs_util_1.toBuffer)(stateRoot), (0, ethereumjs_util_1.toBuffer)(transactionsTrie), (0, ethereumjs_util_1.toBuffer)(receiptTrie), (0, ethereumjs_util_1.toBuffer)(bloom), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(difficulty)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(number)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasLimit)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasUsed)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(timestamp)), (0, ethereumjs_util_1.toBuffer)(extraData), (0, ethereumjs_util_1.toBuffer)(mixHash), (0, ethereumjs_util_1.toBuffer)(nonce), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(baseFeePerGas)) : undefined); | ||
}; | ||
@@ -241,3 +265,3 @@ /** | ||
BlockHeader.prototype._validateHeaderFields = function () { | ||
var _a = this, parentHash = _a.parentHash, stateRoot = _a.stateRoot, transactionsTrie = _a.transactionsTrie, receiptTrie = _a.receiptTrie, mixHash = _a.mixHash, nonce = _a.nonce; | ||
var _a = this, parentHash = _a.parentHash, uncleHash = _a.uncleHash, stateRoot = _a.stateRoot, transactionsTrie = _a.transactionsTrie, receiptTrie = _a.receiptTrie, difficulty = _a.difficulty, extraData = _a.extraData, mixHash = _a.mixHash, nonce = _a.nonce; | ||
if (parentHash.length !== 32) { | ||
@@ -269,2 +293,30 @@ throw new Error("parentHash must be 32 bytes, received " + parentHash.length + " bytes"); | ||
} | ||
// Check for constant values for PoS blocks | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfStake) { | ||
var error = false; | ||
var errorMsg = ''; | ||
if (!uncleHash.equals(ethereumjs_util_1.KECCAK256_RLP_ARRAY)) { | ||
errorMsg += ", uncleHash: " + uncleHash.toString('hex') + " (expected: " + ethereumjs_util_1.KECCAK256_RLP_ARRAY.toString('hex') + ")"; | ||
error = true; | ||
} | ||
if (!difficulty.eq(new ethereumjs_util_1.BN(0))) { | ||
errorMsg += ", difficulty: " + difficulty + " (expected: 0)"; | ||
error = true; | ||
} | ||
if (!extraData.equals(Buffer.from([]))) { | ||
errorMsg += ", extraData: " + extraData.toString('hex') + " (expected: '')"; | ||
error = true; | ||
} | ||
if (!mixHash.equals((0, ethereumjs_util_1.zeros)(32))) { | ||
errorMsg += ", mixHash: " + mixHash.toString('hex') + " (expected: " + (0, ethereumjs_util_1.zeros)(32).toString('hex') + ")"; | ||
error = true; | ||
} | ||
if (!nonce.equals((0, ethereumjs_util_1.zeros)(8))) { | ||
errorMsg += ", nonce: " + nonce.toString('hex') + " (expected: " + (0, ethereumjs_util_1.zeros)(8).toString('hex') + ")"; | ||
error = true; | ||
} | ||
if (error) { | ||
throw new Error('Invalid PoS block' + errorMsg); | ||
} | ||
} | ||
}; | ||
@@ -277,6 +329,6 @@ /** | ||
BlockHeader.prototype.canonicalDifficulty = function (parentBlockHeader) { | ||
if (this._common.consensusType() !== 'pow') { | ||
if (this._common.consensusType() !== common_1.ConsensusType.ProofOfWork) { | ||
throw new Error('difficulty calculation is only supported on PoW chains'); | ||
} | ||
if (this._common.consensusAlgorithm() !== 'ethash') { | ||
if (this._common.consensusAlgorithm() !== common_1.ConsensusAlgorithm.Ethash) { | ||
throw new Error('difficulty calculation currently only supports the ethash algorithm'); | ||
@@ -382,3 +434,4 @@ } | ||
// to adopt to the new gas target centered logic | ||
if (this.number.eq(this._common.hardforkBlockBN('london'))) { | ||
var londonHardforkBlock = this._common.hardforkBlockBN('london'); | ||
if (londonHardforkBlock && this.number.eq(londonHardforkBlock)) { | ||
var elasticity = new ethereumjs_util_1.BN(this._common.param('gasConfig', 'elasticityMultiplier')); | ||
@@ -416,3 +469,3 @@ parentGasLimit = parentGasLimit.mul(elasticity); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var hardfork, msg, minLength, msg, signerLength, msg, msg, msg, msg, parentHeader, number, period, dif, isInitialEIP1559Block, initialBaseFee, expectedBaseFee; | ||
var hardfork, msg, minLength, msg, signerLength, msg, msg, msg, msg, parentHeader, number, period, dif, block, isInitialEIP1559Block, initialBaseFee, expectedBaseFee; | ||
return __generator(this, function (_a) { | ||
@@ -426,3 +479,3 @@ switch (_a.label) { | ||
// Consensus type dependent checks | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) { | ||
// PoW/Ethash | ||
@@ -434,3 +487,3 @@ if (this.extraData.length > this._common.paramByHardfork('vm', 'maxExtraDataSize', hardfork)) { | ||
} | ||
else { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Clique) { | ||
minLength = clique_1.CLIQUE_EXTRA_VANITY + clique_1.CLIQUE_EXTRA_SEAL; | ||
@@ -479,3 +532,3 @@ if (!this.cliqueIsEpochTransition()) { | ||
} | ||
if (this._common.consensusAlgorithm() === 'clique') { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Clique) { | ||
period = this._common.consensusConfig().period; | ||
@@ -509,3 +562,4 @@ // Timestamp diff between blocks is lower than PERIOD (clique) | ||
} | ||
isInitialEIP1559Block = this.number.eq(this._common.hardforkBlockBN('london')); | ||
block = this._common.hardforkBlockBN('london'); | ||
isInitialEIP1559Block = block && this.number.eq(block); | ||
if (isInitialEIP1559Block) { | ||
@@ -572,7 +626,7 @@ initialBaseFee = new ethereumjs_util_1.BN(this._common.param('gasConfig', 'initialBaseFee')); | ||
this.bloom, | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.difficulty), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.number), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.gasLimit), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.gasUsed), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.timestamp), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.difficulty), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.number), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.gasLimit), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.gasUsed), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.timestamp), | ||
this.extraData, | ||
@@ -583,3 +637,3 @@ this.mixHash, | ||
if (this._common.isActivatedEIP(1559)) { | ||
rawItems.push(ethereumjs_util_1.bnToUnpaddedBuffer(this.baseFeePerGas)); | ||
rawItems.push((0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.baseFeePerGas)); | ||
} | ||
@@ -592,3 +646,9 @@ return rawItems; | ||
BlockHeader.prototype.hash = function () { | ||
return ethereumjs_util_1.rlphash(this.raw()); | ||
if (Object.isFrozen(this)) { | ||
if (!this.cache.hash) { | ||
this.cache.hash = (0, ethereumjs_util_1.rlphash)(this.raw()); | ||
} | ||
return this.cache.hash; | ||
} | ||
return (0, ethereumjs_util_1.rlphash)(this.raw()); | ||
}; | ||
@@ -602,3 +662,3 @@ /** | ||
BlockHeader.prototype._requireClique = function (name) { | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() !== common_1.ConsensusAlgorithm.Clique) { | ||
throw new Error("BlockHeader." + name + "() call only supported for clique PoA networks"); | ||
@@ -614,3 +674,3 @@ } | ||
raw[12] = this.extraData.slice(0, this.extraData.length - clique_1.CLIQUE_EXTRA_SEAL); | ||
return ethereumjs_util_1.rlphash(raw); | ||
return (0, ethereumjs_util_1.rlphash)(raw); | ||
}; | ||
@@ -651,4 +711,4 @@ /** | ||
this._requireClique('cliqueSealBlock'); | ||
var signature = ethereumjs_util_1.ecsign(this.cliqueSigHash(), privateKey); | ||
var signatureB = Buffer.concat([signature.r, signature.s, ethereumjs_util_1.intToBuffer(signature.v - 27)]); | ||
var signature = (0, ethereumjs_util_1.ecsign)(this.cliqueSigHash(), privateKey); | ||
var signatureB = Buffer.concat([signature.r, signature.s, (0, ethereumjs_util_1.intToBuffer)(signature.v - 27)]); | ||
var extraDataWithoutSeal = this.extraData.slice(0, this.extraData.length - clique_1.CLIQUE_EXTRA_SEAL); | ||
@@ -708,3 +768,3 @@ var extraData = Buffer.concat([extraDataWithoutSeal, signatureB]); | ||
var v = new ethereumjs_util_1.BN(extraSeal.slice(64, 65)).addn(27); | ||
var pubKey = ethereumjs_util_1.ecrecover(this.cliqueSigHash(), v, r, s); | ||
var pubKey = (0, ethereumjs_util_1.ecrecover)(this.cliqueSigHash(), v, r, s); | ||
return ethereumjs_util_1.Address.fromPublicKey(pubKey); | ||
@@ -730,7 +790,7 @@ }; | ||
bloom: '0x' + this.bloom.toString('hex'), | ||
difficulty: ethereumjs_util_1.bnToHex(this.difficulty), | ||
number: ethereumjs_util_1.bnToHex(this.number), | ||
gasLimit: ethereumjs_util_1.bnToHex(this.gasLimit), | ||
gasUsed: ethereumjs_util_1.bnToHex(this.gasUsed), | ||
timestamp: ethereumjs_util_1.bnToHex(this.timestamp), | ||
difficulty: (0, ethereumjs_util_1.bnToHex)(this.difficulty), | ||
number: (0, ethereumjs_util_1.bnToHex)(this.number), | ||
gasLimit: (0, ethereumjs_util_1.bnToHex)(this.gasLimit), | ||
gasUsed: (0, ethereumjs_util_1.bnToHex)(this.gasUsed), | ||
timestamp: (0, ethereumjs_util_1.bnToHex)(this.timestamp), | ||
extraData: '0x' + this.extraData.toString('hex'), | ||
@@ -737,0 +797,0 @@ mixHash: '0x' + this.mixHash.toString('hex'), |
@@ -9,6 +9,6 @@ "use strict"; | ||
*/ | ||
exports.numberToHex = function (input) { | ||
var numberToHex = function (input) { | ||
if (!input) | ||
return undefined; | ||
if (!ethereumjs_util_1.isHexString(input)) { | ||
if (!(0, ethereumjs_util_1.isHexString)(input)) { | ||
var regex = new RegExp(/^\d+$/); // test to make sure input contains only digits | ||
@@ -23,2 +23,3 @@ if (!regex.test(input)) { | ||
}; | ||
exports.numberToHex = numberToHex; | ||
//# sourceMappingURL=helpers.js.map |
@@ -10,5 +10,6 @@ "use strict"; | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BlockHeader = exports.Block = void 0; | ||
var block_1 = require("./block"); | ||
@@ -15,0 +16,0 @@ Object.defineProperty(exports, "Block", { enumerable: true, get: function () { return block_1.Block; } }); |
@@ -32,2 +32,13 @@ /// <reference types="node" /> | ||
/** | ||
* Determine the HF by total difficulty (Merge HF) | ||
* | ||
* This option is a superset of `hardforkByBlockNumber` (so only use one of both options) | ||
* and determines the HF by both the block number and the TD. | ||
* | ||
* Since the TD is only a threshold the block number will in doubt take precedence (imagine | ||
* e.g. both Merge and Shanghai HF blocks set and the block number from the block provided | ||
* pointing to a Shanghai block: this will lead to set the HF as Shanghai and not the Merge). | ||
*/ | ||
hardforkByTD?: BNLike; | ||
/** | ||
* Turns the block header into the canonical genesis block header | ||
@@ -47,2 +58,5 @@ * | ||
* difficulty takes precedence over a provided static `difficulty` value. | ||
* | ||
* Note that this option has no effect on networks other than PoW/Ethash networks | ||
* (respectively also deactivates on the Merge HF switching to PoS/Casper). | ||
*/ | ||
@@ -53,2 +67,3 @@ calcDifficultyFromHeader?: BlockHeader; | ||
* strong additional security guarantees on the consistency of the block parameters. | ||
* It also enables block hash caching when the `hash()` method is called multiple times. | ||
* | ||
@@ -55,0 +70,0 @@ * If you need to deactivate the block freeze - e.g. because you want to subclass block and |
"use strict"; | ||
/* eslint-disable no-dupe-class-members */ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -7,2 +6,3 @@ exports.Block = void 0; | ||
const ethereumjs_util_1 = require("ethereumjs-util"); | ||
const common_1 = require("@ethereumjs/common"); | ||
const tx_1 = require("@ethereumjs/tx"); | ||
@@ -27,4 +27,9 @@ const header_1 = require("./header"); | ||
this._common = this.header._common; | ||
if (this._common.consensusType() === 'poa' && uncleHeaders.length > 0) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed'); | ||
if (uncleHeaders.length > 0) { | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfAuthority) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed'); | ||
} | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfStake) { | ||
throw new Error('Block initialization with uncleHeaders on a PoS network is not allowed'); | ||
} | ||
} | ||
@@ -55,9 +60,12 @@ const freeze = (_a = opts === null || opts === void 0 ? void 0 : opts.freeze) !== null && _a !== void 0 ? _a : true; | ||
const uncleHeaders = []; | ||
const uncleOpts = Object.assign(Object.assign({ hardforkByBlockNumber: true }, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }); | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber; | ||
} | ||
for (const uhData of uhsData !== null && uhsData !== void 0 ? uhsData : []) { | ||
const uh = header_1.BlockHeader.fromHeaderData(uhData, Object.assign(Object.assign({}, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites | ||
// the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined })); | ||
const uh = header_1.BlockHeader.fromHeaderData(uhData, uncleOpts); | ||
uncleHeaders.push(uh); | ||
@@ -101,8 +109,12 @@ } | ||
const uncleHeaders = []; | ||
const uncleOpts = Object.assign(Object.assign({ hardforkByBlockNumber: true }, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }); | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber; | ||
} | ||
for (const uncleHeaderData of uhsData || []) { | ||
uncleHeaders.push(header_1.BlockHeader.fromValuesArray(uncleHeaderData, Object.assign(Object.assign({}, opts), { | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined }))); | ||
uncleHeaders.push(header_1.BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts)); | ||
} | ||
@@ -246,3 +258,3 @@ return new Block(header, transactions, uncleHeaders, opts); | ||
const raw = ethereumjs_util_1.rlp.encode(this.uncleHeaders.map((uh) => uh.raw())); | ||
return ethereumjs_util_1.keccak256(raw).equals(this.header.uncleHash); | ||
return (0, ethereumjs_util_1.keccak256)(raw).equals(this.header.uncleHash); | ||
} | ||
@@ -249,0 +261,0 @@ /** |
@@ -16,6 +16,6 @@ "use strict"; | ||
// check and convert gasPrice and value params | ||
txParams.gasPrice = helpers_1.numberToHex(txParams.gasPrice); | ||
txParams.value = helpers_1.numberToHex(txParams.value); | ||
txParams.gasPrice = (0, helpers_1.numberToHex)(txParams.gasPrice); | ||
txParams.value = (0, helpers_1.numberToHex)(txParams.value); | ||
// strict byte length checking | ||
txParams.to = txParams.to ? ethereumjs_util_1.setLengthLeft(ethereumjs_util_1.toBuffer(txParams.to), 20) : null; | ||
txParams.to = txParams.to ? (0, ethereumjs_util_1.setLengthLeft)((0, ethereumjs_util_1.toBuffer)(txParams.to), 20) : null; | ||
// v as raw signature value {0,1} | ||
@@ -36,3 +36,3 @@ // v is the recovery bit and can be either {0,1} or {27,28}. | ||
function blockFromRpc(blockParams, uncles = [], options) { | ||
const header = header_from_rpc_1.default(blockParams, options); | ||
const header = (0, header_from_rpc_1.default)(blockParams, options); | ||
const transactions = []; | ||
@@ -47,3 +47,3 @@ if (blockParams.transactions) { | ||
} | ||
const uncleHeaders = uncles.map((uh) => header_from_rpc_1.default(uh, options)); | ||
const uncleHeaders = uncles.map((uh) => (0, header_from_rpc_1.default)(uh, options)); | ||
return index_1.Block.fromBlockData({ header, transactions, uncleHeaders }, options); | ||
@@ -50,0 +50,0 @@ } |
@@ -27,3 +27,3 @@ "use strict"; | ||
bloom: logsBloom, | ||
difficulty: helpers_1.numberToHex(difficulty), | ||
difficulty: (0, helpers_1.numberToHex)(difficulty), | ||
number, | ||
@@ -30,0 +30,0 @@ gasLimit, |
@@ -5,3 +5,3 @@ /// <reference types="node" /> | ||
import { Address, BN } from 'ethereumjs-util'; | ||
import { HeaderData, JsonHeader, BlockHeaderBuffer, Blockchain, BlockOptions } from './types'; | ||
import { Blockchain, BlockHeaderBuffer, BlockOptions, HeaderData, JsonHeader } from './types'; | ||
/** | ||
@@ -29,2 +29,3 @@ * An object that represents the block header. | ||
_errorPostfix: string; | ||
private cache; | ||
/** | ||
@@ -31,0 +32,0 @@ * Static constructor to create a block header from a header data dictionary |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BlockHeader = void 0; | ||
const common_1 = __importDefault(require("@ethereumjs/common")); | ||
const common_1 = __importStar(require("@ethereumjs/common")); | ||
const ethereumjs_util_1 = require("ethereumjs-util"); | ||
@@ -23,4 +39,7 @@ const clique_1 = require("./clique"); | ||
constructor(parentHash, uncleHash, coinbase, stateRoot, transactionsTrie, receiptTrie, bloom, difficulty, number, gasLimit, gasUsed, timestamp, extraData, mixHash, nonce, options = {}, baseFeePerGas) { | ||
var _a; | ||
var _a, _b; | ||
this._errorPostfix = ''; | ||
this.cache = { | ||
hash: undefined, | ||
}; | ||
if (options.common) { | ||
@@ -30,5 +49,5 @@ this._common = options.common.copy(); | ||
else { | ||
const chain = 'mainnet'; // default | ||
const chain = common_1.Chain.Mainnet; // default | ||
if (options.initWithGenesisHeader) { | ||
this._common = new common_1.default({ chain, hardfork: 'chainstart' }); | ||
this._common = new common_1.default({ chain, hardfork: common_1.Hardfork.Chainstart }); | ||
} | ||
@@ -40,5 +59,9 @@ else { | ||
} | ||
if (options.hardforkByBlockNumber) { | ||
this._common.setHardforkByBlockNumber(number.toNumber()); | ||
if (options.hardforkByBlockNumber !== undefined && options.hardforkByTD !== undefined) { | ||
throw new Error(`The hardforkByBlockNumber and hardforkByTD options can't be used in conjunction`); | ||
} | ||
const hardforkByBlockNumber = (_a = options.hardforkByBlockNumber) !== null && _a !== void 0 ? _a : false; | ||
if (hardforkByBlockNumber || options.hardforkByTD) { | ||
this._common.setHardforkByBlockNumber(number.toNumber(), options.hardforkByTD); | ||
} | ||
if (this._common.isActivatedEIP(1559)) { | ||
@@ -57,18 +80,18 @@ if (baseFeePerGas === undefined) { | ||
if (gasLimit.eq(DEFAULT_GAS_LIMIT)) { | ||
gasLimit = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().gasLimit)); | ||
gasLimit = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().gasLimit)); | ||
} | ||
if (timestamp.isZero()) { | ||
timestamp = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().timestamp)); | ||
timestamp = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().timestamp)); | ||
} | ||
if (difficulty.isZero()) { | ||
difficulty = new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(this._common.genesis().difficulty)); | ||
difficulty = new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(this._common.genesis().difficulty)); | ||
} | ||
if (extraData.length === 0) { | ||
extraData = ethereumjs_util_1.toBuffer(this._common.genesis().extraData); | ||
extraData = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().extraData); | ||
} | ||
if (nonce.equals(ethereumjs_util_1.zeros(8))) { | ||
nonce = ethereumjs_util_1.toBuffer(this._common.genesis().nonce); | ||
if (nonce.equals((0, ethereumjs_util_1.zeros)(8))) { | ||
nonce = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().nonce); | ||
} | ||
if (stateRoot.equals(ethereumjs_util_1.zeros(32))) { | ||
stateRoot = ethereumjs_util_1.toBuffer(this._common.genesis().stateRoot); | ||
if (stateRoot.equals((0, ethereumjs_util_1.zeros)(32))) { | ||
stateRoot = (0, ethereumjs_util_1.toBuffer)(this._common.genesis().stateRoot); | ||
} | ||
@@ -97,3 +120,4 @@ } | ||
// block option parameter, we instead set difficulty to this value. | ||
if (options.calcDifficultyFromHeader) { | ||
if (options.calcDifficultyFromHeader && | ||
this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) { | ||
this.difficulty = this.canonicalDifficulty(options.calcDifficultyFromHeader); | ||
@@ -112,3 +136,3 @@ } | ||
this._errorPostfix = `block number=${this.number.toNumber()} hash=${this.hash().toString('hex')}`; | ||
const freeze = (_a = options === null || options === void 0 ? void 0 : options.freeze) !== null && _a !== void 0 ? _a : true; | ||
const freeze = (_b = options === null || options === void 0 ? void 0 : options.freeze) !== null && _b !== void 0 ? _b : true; | ||
if (freeze) { | ||
@@ -126,3 +150,3 @@ Object.freeze(this); | ||
const { parentHash, uncleHash, coinbase, stateRoot, transactionsTrie, receiptTrie, bloom, difficulty, number, gasLimit, gasUsed, timestamp, extraData, mixHash, nonce, baseFeePerGas, } = headerData; | ||
return new BlockHeader(parentHash ? ethereumjs_util_1.toBuffer(parentHash) : ethereumjs_util_1.zeros(32), uncleHash ? ethereumjs_util_1.toBuffer(uncleHash) : ethereumjs_util_1.KECCAK256_RLP_ARRAY, coinbase ? new ethereumjs_util_1.Address(ethereumjs_util_1.toBuffer(coinbase)) : ethereumjs_util_1.Address.zero(), stateRoot ? ethereumjs_util_1.toBuffer(stateRoot) : ethereumjs_util_1.zeros(32), transactionsTrie ? ethereumjs_util_1.toBuffer(transactionsTrie) : ethereumjs_util_1.KECCAK256_RLP, receiptTrie ? ethereumjs_util_1.toBuffer(receiptTrie) : ethereumjs_util_1.KECCAK256_RLP, bloom ? ethereumjs_util_1.toBuffer(bloom) : ethereumjs_util_1.zeros(256), difficulty ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(difficulty)) : new ethereumjs_util_1.BN(0), number ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(number)) : new ethereumjs_util_1.BN(0), gasLimit ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasLimit)) : DEFAULT_GAS_LIMIT, gasUsed ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasUsed)) : new ethereumjs_util_1.BN(0), timestamp ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(timestamp)) : new ethereumjs_util_1.BN(0), extraData ? ethereumjs_util_1.toBuffer(extraData) : Buffer.from([]), mixHash ? ethereumjs_util_1.toBuffer(mixHash) : ethereumjs_util_1.zeros(32), nonce ? ethereumjs_util_1.toBuffer(nonce) : ethereumjs_util_1.zeros(8), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(baseFeePerGas)) : undefined); | ||
return new BlockHeader(parentHash ? (0, ethereumjs_util_1.toBuffer)(parentHash) : (0, ethereumjs_util_1.zeros)(32), uncleHash ? (0, ethereumjs_util_1.toBuffer)(uncleHash) : ethereumjs_util_1.KECCAK256_RLP_ARRAY, coinbase ? new ethereumjs_util_1.Address((0, ethereumjs_util_1.toBuffer)(coinbase)) : ethereumjs_util_1.Address.zero(), stateRoot ? (0, ethereumjs_util_1.toBuffer)(stateRoot) : (0, ethereumjs_util_1.zeros)(32), transactionsTrie ? (0, ethereumjs_util_1.toBuffer)(transactionsTrie) : ethereumjs_util_1.KECCAK256_RLP, receiptTrie ? (0, ethereumjs_util_1.toBuffer)(receiptTrie) : ethereumjs_util_1.KECCAK256_RLP, bloom ? (0, ethereumjs_util_1.toBuffer)(bloom) : (0, ethereumjs_util_1.zeros)(256), difficulty ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(difficulty)) : new ethereumjs_util_1.BN(0), number ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(number)) : new ethereumjs_util_1.BN(0), gasLimit ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasLimit)) : DEFAULT_GAS_LIMIT, gasUsed ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasUsed)) : new ethereumjs_util_1.BN(0), timestamp ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(timestamp)) : new ethereumjs_util_1.BN(0), extraData ? (0, ethereumjs_util_1.toBuffer)(extraData) : Buffer.from([]), mixHash ? (0, ethereumjs_util_1.toBuffer)(mixHash) : (0, ethereumjs_util_1.zeros)(32), nonce ? (0, ethereumjs_util_1.toBuffer)(nonce) : (0, ethereumjs_util_1.zeros)(8), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(baseFeePerGas)) : undefined); | ||
} | ||
@@ -156,3 +180,3 @@ /** | ||
} | ||
return new BlockHeader(ethereumjs_util_1.toBuffer(parentHash), ethereumjs_util_1.toBuffer(uncleHash), new ethereumjs_util_1.Address(ethereumjs_util_1.toBuffer(coinbase)), ethereumjs_util_1.toBuffer(stateRoot), ethereumjs_util_1.toBuffer(transactionsTrie), ethereumjs_util_1.toBuffer(receiptTrie), ethereumjs_util_1.toBuffer(bloom), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(difficulty)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(number)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasLimit)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(gasUsed)), new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(timestamp)), ethereumjs_util_1.toBuffer(extraData), ethereumjs_util_1.toBuffer(mixHash), ethereumjs_util_1.toBuffer(nonce), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN(ethereumjs_util_1.toBuffer(baseFeePerGas)) : undefined); | ||
return new BlockHeader((0, ethereumjs_util_1.toBuffer)(parentHash), (0, ethereumjs_util_1.toBuffer)(uncleHash), new ethereumjs_util_1.Address((0, ethereumjs_util_1.toBuffer)(coinbase)), (0, ethereumjs_util_1.toBuffer)(stateRoot), (0, ethereumjs_util_1.toBuffer)(transactionsTrie), (0, ethereumjs_util_1.toBuffer)(receiptTrie), (0, ethereumjs_util_1.toBuffer)(bloom), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(difficulty)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(number)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasLimit)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(gasUsed)), new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(timestamp)), (0, ethereumjs_util_1.toBuffer)(extraData), (0, ethereumjs_util_1.toBuffer)(mixHash), (0, ethereumjs_util_1.toBuffer)(nonce), opts, baseFeePerGas !== undefined ? new ethereumjs_util_1.BN((0, ethereumjs_util_1.toBuffer)(baseFeePerGas)) : undefined); | ||
} | ||
@@ -170,3 +194,3 @@ /** | ||
_validateHeaderFields() { | ||
const { parentHash, stateRoot, transactionsTrie, receiptTrie, mixHash, nonce } = this; | ||
const { parentHash, uncleHash, stateRoot, transactionsTrie, receiptTrie, difficulty, extraData, mixHash, nonce, } = this; | ||
if (parentHash.length !== 32) { | ||
@@ -198,2 +222,30 @@ throw new Error(`parentHash must be 32 bytes, received ${parentHash.length} bytes`); | ||
} | ||
// Check for constant values for PoS blocks | ||
if (this._common.consensusType() === common_1.ConsensusType.ProofOfStake) { | ||
let error = false; | ||
let errorMsg = ''; | ||
if (!uncleHash.equals(ethereumjs_util_1.KECCAK256_RLP_ARRAY)) { | ||
errorMsg += `, uncleHash: ${uncleHash.toString('hex')} (expected: ${ethereumjs_util_1.KECCAK256_RLP_ARRAY.toString('hex')})`; | ||
error = true; | ||
} | ||
if (!difficulty.eq(new ethereumjs_util_1.BN(0))) { | ||
errorMsg += `, difficulty: ${difficulty} (expected: 0)`; | ||
error = true; | ||
} | ||
if (!extraData.equals(Buffer.from([]))) { | ||
errorMsg += `, extraData: ${extraData.toString('hex')} (expected: '')`; | ||
error = true; | ||
} | ||
if (!mixHash.equals((0, ethereumjs_util_1.zeros)(32))) { | ||
errorMsg += `, mixHash: ${mixHash.toString('hex')} (expected: ${(0, ethereumjs_util_1.zeros)(32).toString('hex')})`; | ||
error = true; | ||
} | ||
if (!nonce.equals((0, ethereumjs_util_1.zeros)(8))) { | ||
errorMsg += `, nonce: ${nonce.toString('hex')} (expected: ${(0, ethereumjs_util_1.zeros)(8).toString('hex')})`; | ||
error = true; | ||
} | ||
if (error) { | ||
throw new Error('Invalid PoS block' + errorMsg); | ||
} | ||
} | ||
} | ||
@@ -206,6 +258,6 @@ /** | ||
canonicalDifficulty(parentBlockHeader) { | ||
if (this._common.consensusType() !== 'pow') { | ||
if (this._common.consensusType() !== common_1.ConsensusType.ProofOfWork) { | ||
throw new Error('difficulty calculation is only supported on PoW chains'); | ||
} | ||
if (this._common.consensusAlgorithm() !== 'ethash') { | ||
if (this._common.consensusAlgorithm() !== common_1.ConsensusAlgorithm.Ethash) { | ||
throw new Error('difficulty calculation currently only supports the ethash algorithm'); | ||
@@ -310,3 +362,4 @@ } | ||
// to adopt to the new gas target centered logic | ||
if (this.number.eq(this._common.hardforkBlockBN('london'))) { | ||
const londonHardforkBlock = this._common.hardforkBlockBN('london'); | ||
if (londonHardforkBlock && this.number.eq(londonHardforkBlock)) { | ||
const elasticity = new ethereumjs_util_1.BN(this._common.param('gasConfig', 'elasticityMultiplier')); | ||
@@ -348,3 +401,3 @@ parentGasLimit = parentGasLimit.mul(elasticity); | ||
// Consensus type dependent checks | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Ethash) { | ||
// PoW/Ethash | ||
@@ -356,3 +409,3 @@ if (this.extraData.length > this._common.paramByHardfork('vm', 'maxExtraDataSize', hardfork)) { | ||
} | ||
else { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Clique) { | ||
// PoA/Clique | ||
@@ -400,3 +453,3 @@ const minLength = clique_1.CLIQUE_EXTRA_VANITY + clique_1.CLIQUE_EXTRA_SEAL; | ||
} | ||
if (this._common.consensusAlgorithm() === 'clique') { | ||
if (this._common.consensusAlgorithm() === common_1.ConsensusAlgorithm.Clique) { | ||
const period = this._common.consensusConfig().period; | ||
@@ -430,3 +483,4 @@ // Timestamp diff between blocks is lower than PERIOD (clique) | ||
} | ||
const isInitialEIP1559Block = this.number.eq(this._common.hardforkBlockBN('london')); | ||
const block = this._common.hardforkBlockBN('london'); | ||
const isInitialEIP1559Block = block && this.number.eq(block); | ||
if (isInitialEIP1559Block) { | ||
@@ -490,7 +544,7 @@ const initialBaseFee = new ethereumjs_util_1.BN(this._common.param('gasConfig', 'initialBaseFee')); | ||
this.bloom, | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.difficulty), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.number), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.gasLimit), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.gasUsed), | ||
ethereumjs_util_1.bnToUnpaddedBuffer(this.timestamp), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.difficulty), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.number), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.gasLimit), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.gasUsed), | ||
(0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.timestamp), | ||
this.extraData, | ||
@@ -501,3 +555,3 @@ this.mixHash, | ||
if (this._common.isActivatedEIP(1559)) { | ||
rawItems.push(ethereumjs_util_1.bnToUnpaddedBuffer(this.baseFeePerGas)); | ||
rawItems.push((0, ethereumjs_util_1.bnToUnpaddedBuffer)(this.baseFeePerGas)); | ||
} | ||
@@ -510,3 +564,9 @@ return rawItems; | ||
hash() { | ||
return ethereumjs_util_1.rlphash(this.raw()); | ||
if (Object.isFrozen(this)) { | ||
if (!this.cache.hash) { | ||
this.cache.hash = (0, ethereumjs_util_1.rlphash)(this.raw()); | ||
} | ||
return this.cache.hash; | ||
} | ||
return (0, ethereumjs_util_1.rlphash)(this.raw()); | ||
} | ||
@@ -520,3 +580,3 @@ /** | ||
_requireClique(name) { | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() !== common_1.ConsensusAlgorithm.Clique) { | ||
throw new Error(`BlockHeader.${name}() call only supported for clique PoA networks`); | ||
@@ -532,3 +592,3 @@ } | ||
raw[12] = this.extraData.slice(0, this.extraData.length - clique_1.CLIQUE_EXTRA_SEAL); | ||
return ethereumjs_util_1.rlphash(raw); | ||
return (0, ethereumjs_util_1.rlphash)(raw); | ||
} | ||
@@ -569,4 +629,4 @@ /** | ||
this._requireClique('cliqueSealBlock'); | ||
const signature = ethereumjs_util_1.ecsign(this.cliqueSigHash(), privateKey); | ||
const signatureB = Buffer.concat([signature.r, signature.s, ethereumjs_util_1.intToBuffer(signature.v - 27)]); | ||
const signature = (0, ethereumjs_util_1.ecsign)(this.cliqueSigHash(), privateKey); | ||
const signatureB = Buffer.concat([signature.r, signature.s, (0, ethereumjs_util_1.intToBuffer)(signature.v - 27)]); | ||
const extraDataWithoutSeal = this.extraData.slice(0, this.extraData.length - clique_1.CLIQUE_EXTRA_SEAL); | ||
@@ -626,3 +686,3 @@ const extraData = Buffer.concat([extraDataWithoutSeal, signatureB]); | ||
const v = new ethereumjs_util_1.BN(extraSeal.slice(64, 65)).addn(27); | ||
const pubKey = ethereumjs_util_1.ecrecover(this.cliqueSigHash(), v, r, s); | ||
const pubKey = (0, ethereumjs_util_1.ecrecover)(this.cliqueSigHash(), v, r, s); | ||
return ethereumjs_util_1.Address.fromPublicKey(pubKey); | ||
@@ -648,7 +708,7 @@ } | ||
bloom: '0x' + this.bloom.toString('hex'), | ||
difficulty: ethereumjs_util_1.bnToHex(this.difficulty), | ||
number: ethereumjs_util_1.bnToHex(this.number), | ||
gasLimit: ethereumjs_util_1.bnToHex(this.gasLimit), | ||
gasUsed: ethereumjs_util_1.bnToHex(this.gasUsed), | ||
timestamp: ethereumjs_util_1.bnToHex(this.timestamp), | ||
difficulty: (0, ethereumjs_util_1.bnToHex)(this.difficulty), | ||
number: (0, ethereumjs_util_1.bnToHex)(this.number), | ||
gasLimit: (0, ethereumjs_util_1.bnToHex)(this.gasLimit), | ||
gasUsed: (0, ethereumjs_util_1.bnToHex)(this.gasUsed), | ||
timestamp: (0, ethereumjs_util_1.bnToHex)(this.timestamp), | ||
extraData: '0x' + this.extraData.toString('hex'), | ||
@@ -655,0 +715,0 @@ mixHash: '0x' + this.mixHash.toString('hex'), |
@@ -9,6 +9,6 @@ "use strict"; | ||
*/ | ||
exports.numberToHex = function (input) { | ||
const numberToHex = function (input) { | ||
if (!input) | ||
return undefined; | ||
if (!ethereumjs_util_1.isHexString(input)) { | ||
if (!(0, ethereumjs_util_1.isHexString)(input)) { | ||
const regex = new RegExp(/^\d+$/); // test to make sure input contains only digits | ||
@@ -23,2 +23,3 @@ if (!regex.test(input)) { | ||
}; | ||
exports.numberToHex = numberToHex; | ||
//# sourceMappingURL=helpers.js.map |
@@ -10,5 +10,6 @@ "use strict"; | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BlockHeader = exports.Block = void 0; | ||
var block_1 = require("./block"); | ||
@@ -15,0 +16,0 @@ Object.defineProperty(exports, "Block", { enumerable: true, get: function () { return block_1.Block; } }); |
@@ -32,2 +32,13 @@ /// <reference types="node" /> | ||
/** | ||
* Determine the HF by total difficulty (Merge HF) | ||
* | ||
* This option is a superset of `hardforkByBlockNumber` (so only use one of both options) | ||
* and determines the HF by both the block number and the TD. | ||
* | ||
* Since the TD is only a threshold the block number will in doubt take precedence (imagine | ||
* e.g. both Merge and Shanghai HF blocks set and the block number from the block provided | ||
* pointing to a Shanghai block: this will lead to set the HF as Shanghai and not the Merge). | ||
*/ | ||
hardforkByTD?: BNLike; | ||
/** | ||
* Turns the block header into the canonical genesis block header | ||
@@ -47,2 +58,5 @@ * | ||
* difficulty takes precedence over a provided static `difficulty` value. | ||
* | ||
* Note that this option has no effect on networks other than PoW/Ethash networks | ||
* (respectively also deactivates on the Merge HF switching to PoS/Casper). | ||
*/ | ||
@@ -53,2 +67,3 @@ calcDifficultyFromHeader?: BlockHeader; | ||
* strong additional security guarantees on the consistency of the block parameters. | ||
* It also enables block hash caching when the `hash()` method is called multiple times. | ||
* | ||
@@ -55,0 +70,0 @@ * If you need to deactivate the block freeze - e.g. because you want to subclass block and |
{ | ||
"name": "@ethereumjs/block", | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "Provides Block serialization and help functions", | ||
@@ -20,5 +20,7 @@ "license": "MPL-2.0", | ||
"scripts": { | ||
"build": "../../config/cli/ts-build.sh", | ||
"prepublishOnly": "npm run clean && npm run build", | ||
"clean": "rm -Rf ./dist && rm -Rf ./dist.browser", | ||
"build": "npm run build:node && npm run build:browser", | ||
"build:node": "../../config/cli/ts-build.sh node", | ||
"build:browser": "../../config/cli/ts-build.sh browser", | ||
"prepublishOnly": "../../config/cli/prepublish.sh", | ||
"clean": "../../config/cli/clean-package.sh", | ||
"coverage": "../../config/cli/coverage.sh", | ||
@@ -31,12 +33,12 @@ "docs:build": "typedoc --options typedoc.js", | ||
"lint:fix": "../../config/cli/lint-fix.sh", | ||
"tape": "tape -r ts-node/register", | ||
"test": "npm run test:node && npm run test:browser", | ||
"test:node": "tape -r ts-node/register test/*.spec.ts", | ||
"test:browser:build": "tsc && cp test/testdata/*.json test-build/test/testdata", | ||
"test:browser": "npm run test:browser:build && karma start karma.conf.js" | ||
"test:node": "npm run tape -- test/*.spec.ts", | ||
"test:browser": "karma start karma.conf.js" | ||
}, | ||
"dependencies": { | ||
"@ethereumjs/common": "^2.4.0", | ||
"merkle-patricia-tree": "^4.2.0", | ||
"@ethereumjs/tx": "^3.3.0", | ||
"ethereumjs-util": "^7.1.0" | ||
"@ethereumjs/common": "^2.5.0", | ||
"merkle-patricia-tree": "^4.2.1", | ||
"@ethereumjs/tx": "^3.3.1", | ||
"ethereumjs-util": "^7.1.1" | ||
}, | ||
@@ -46,16 +48,15 @@ "devDependencies": { | ||
"@types/node": "^11.13.4", | ||
"@types/tape": "^4.13.0", | ||
"browserify": "^16.5.1", | ||
"@types/tape": "^4.13.2", | ||
"eslint": "^6.8.0", | ||
"karma": "^6.3.2", | ||
"karma-browserify": "^8.0.0", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma-firefox-launcher": "^2.1.0", | ||
"karma-tap": "^4.2.0", | ||
"karma-typescript": "^5.5.1", | ||
"nyc": "^14.0.0", | ||
"prettier": "^2.0.5", | ||
"tape": "^4.10.1", | ||
"ts-node": "^8.8.2", | ||
"typedoc": "^0.20.34", | ||
"typescript": "^3.9.3" | ||
"tape": "^5.3.1", | ||
"typedoc": "^0.22.4", | ||
"ts-node": "^10.2.1", | ||
"typescript": "^4.4.2" | ||
}, | ||
@@ -62,0 +63,0 @@ "repository": { |
@@ -12,3 +12,3 @@ # @ethereumjs/block | ||
Note: this `README` reflects the state of the library from `v3.0.0` onwards. See `README` from the [standalone repository](https://github.com/ethereumjs/ethereumjs-block) for an introduction on the last preceeding release. | ||
Note: this `README` reflects the state of the library from `v3.0.0` onwards. See `README` from the [standalone repository](https://github.com/ethereumjs/ethereumjs-block) for an introduction on the last preceding release. | ||
@@ -29,3 +29,3 @@ # INSTALL | ||
For `BlockHeader` instantiation analogue factory methods exists, see API docs linked below. | ||
For `BlockHeader` instantiation analog factory methods exists, see API docs linked below. | ||
@@ -67,11 +67,18 @@ Instantiation Example: | ||
```typescript | ||
import { Block } from 'ethereumjs-block' | ||
import Common from '@ethereumjs/common' | ||
const common = new Common({ chain: 'mainnet', hardfork: 'london' }) | ||
import { BN } from 'ethereumjs-util' | ||
import { Block } from '@ethereumjs/block' | ||
import Common, { Chain, Hardfork } from '@ethereumjs/common' | ||
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) | ||
const block = Block.fromBlockData({ | ||
header: { | ||
//..., | ||
baseFeePerGas: new BN(10), | ||
gasLimit: new BN(100), | ||
gasUsed: new BN(60) | ||
} | ||
}, { common }) | ||
// Base fee will increase for next block since the | ||
// gas used is greater than half the gas limit | ||
block.header.calcNextBaseFee().toNumber() // 11 | ||
``` | ||
@@ -91,4 +98,4 @@ | ||
import { Block } from '@ethereumjs/block' | ||
import Common from '@ethereumjs/common' | ||
const common = new Common({ chain: 'mainnet' }) | ||
import Common, { Chain } from '@ethereumjs/common' | ||
const common = new Common({ chain: Chain.Mainnet }) | ||
console.log(common.consensusType()) // 'pow' | ||
@@ -109,4 +116,4 @@ console.log(common.consensusAlgorithm()) // 'ethash' | ||
import { Block } from '@ethereumjs/block' | ||
import Common from '@ethereumjs/common' | ||
const common = new Common({ chain: 'goerli' }) | ||
import Common, { Chain } from '@ethereumjs/common' | ||
const common = new Common({ chain: Chain.Goerli }) | ||
console.log(common.consensusType()) // 'poa' | ||
@@ -139,2 +146,19 @@ console.log(common.consensusAlgorithm()) // 'clique' | ||
### Casper/PoS (since v3.5.0) (experimental) | ||
Merge-friendly Casper/PoS blocks have been introduced along with the `v3.5.0` release. Proof-of-Stake compatible execution blocks come with their own set of header field simplifications and associated validation rules. The difficulty is set to `0` since not relevant anymore, just to name an example. For a full list of changes see [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675). | ||
You can instantiate a Merge/PoS block like this: | ||
```typescript | ||
import { Block } from '@ethereumjs/block' | ||
import Common, { Chain, Hardfork } from '@ethereumjs/common' | ||
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Merge, }) | ||
const block = Block.fromBlockData({ | ||
// Provide your block data here or use default values | ||
}, { common }) | ||
``` | ||
Note that all `Merge` respectively `Casper/PoS` related functionality is still considered `experimental`. | ||
# API | ||
@@ -166,5 +190,5 @@ | ||
[block-issues-link]: https://github.com/ethereumjs/ethereumjs-monorepo/issues?q=is%3Aopen+is%3Aissue+label%3A"package%3A+block" | ||
[block-actions-badge]: https://github.com/ethereumjs/ethereumjs-monorepo/workflows/Block%20Test/badge.svg | ||
[block-actions-link]: https://github.com/ethereumjs/ethereumjs-monorepo/actions?query=workflow%3A%22Block+Test%22 | ||
[block-actions-badge]: https://github.com/ethereumjs/ethereumjs-monorepo/workflows/Block/badge.svg | ||
[block-actions-link]: https://github.com/ethereumjs/ethereumjs-monorepo/actions?query=workflow%3A%22Block%22 | ||
[block-coverage-badge]: https://codecov.io/gh/ethereumjs/ethereumjs-monorepo/branch/master/graph/badge.svg?flag=block | ||
[block-coverage-link]: https://codecov.io/gh/ethereumjs/ethereumjs-monorepo/tree/master/packages/block |
@@ -1,6 +0,4 @@ | ||
/* eslint-disable no-dupe-class-members */ | ||
import { BaseTrie as Trie } from 'merkle-patricia-tree' | ||
import { BN, rlp, keccak256, KECCAK256_RLP } from 'ethereumjs-util' | ||
import Common from '@ethereumjs/common' | ||
import Common, { ConsensusType } from '@ethereumjs/common' | ||
import { | ||
@@ -51,11 +49,15 @@ TransactionFactory, | ||
const uncleHeaders = [] | ||
const uncleOpts: BlockOptions = { | ||
hardforkByBlockNumber: true, | ||
...opts, // This potentially overwrites hardforkByBlocknumber | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined, | ||
} | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber | ||
} | ||
for (const uhData of uhsData ?? []) { | ||
const uh = BlockHeader.fromHeaderData(uhData, { | ||
...opts, | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites | ||
// the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined, | ||
}) | ||
const uh = BlockHeader.fromHeaderData(uhData, uncleOpts) | ||
uncleHeaders.push(uh) | ||
@@ -112,12 +114,15 @@ } | ||
const uncleHeaders = [] | ||
const uncleOpts: BlockOptions = { | ||
hardforkByBlockNumber: true, | ||
...opts, // This potentially overwrites hardforkByBlocknumber | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined, | ||
} | ||
if (uncleOpts.hardforkByTD) { | ||
delete uncleOpts.hardforkByBlockNumber | ||
} | ||
for (const uncleHeaderData of uhsData || []) { | ||
uncleHeaders.push( | ||
BlockHeader.fromValuesArray(uncleHeaderData, { | ||
...opts, | ||
// Use header common in case of hardforkByBlockNumber being activated | ||
common: header._common, | ||
// Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value | ||
calcDifficultyFromHeader: undefined, | ||
}) | ||
) | ||
uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts)) | ||
} | ||
@@ -150,4 +155,9 @@ | ||
this._common = this.header._common | ||
if (this._common.consensusType() === 'poa' && uncleHeaders.length > 0) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed') | ||
if (uncleHeaders.length > 0) { | ||
if (this._common.consensusType() === ConsensusType.ProofOfAuthority) { | ||
throw new Error('Block initialization with uncleHeaders on a PoA network is not allowed') | ||
} | ||
if (this._common.consensusType() === ConsensusType.ProofOfStake) { | ||
throw new Error('Block initialization with uncleHeaders on a PoS network is not allowed') | ||
} | ||
} | ||
@@ -482,3 +492,3 @@ | ||
return block | ||
} catch (error) { | ||
} catch (error: any) { | ||
if (error.type === 'NotFoundError') { | ||
@@ -485,0 +495,0 @@ return undefined |
@@ -1,2 +0,2 @@ | ||
import Common from '@ethereumjs/common' | ||
import Common, { Chain, ConsensusAlgorithm, ConsensusType, Hardfork } from '@ethereumjs/common' | ||
import { | ||
@@ -17,3 +17,3 @@ Address, | ||
} from 'ethereumjs-util' | ||
import { HeaderData, JsonHeader, BlockHeaderBuffer, Blockchain, BlockOptions } from './types' | ||
import { Blockchain, BlockHeaderBuffer, BlockOptions, HeaderData, JsonHeader } from './types' | ||
import { | ||
@@ -26,2 +26,6 @@ CLIQUE_EXTRA_VANITY, | ||
interface HeaderCache { | ||
hash: Buffer | undefined | ||
} | ||
const DEFAULT_GAS_LIMIT = new BN(Buffer.from('ffffffffffffff', 'hex')) | ||
@@ -53,2 +57,6 @@ | ||
private cache: HeaderCache = { | ||
hash: undefined, | ||
} | ||
/** | ||
@@ -208,5 +216,5 @@ * Static constructor to create a block header from a header data dictionary | ||
} else { | ||
const chain = 'mainnet' // default | ||
const chain = Chain.Mainnet // default | ||
if (options.initWithGenesisHeader) { | ||
this._common = new Common({ chain, hardfork: 'chainstart' }) | ||
this._common = new Common({ chain, hardfork: Hardfork.Chainstart }) | ||
} else { | ||
@@ -218,6 +226,13 @@ // This initializes on the Common default hardfork | ||
if (options.hardforkByBlockNumber) { | ||
this._common.setHardforkByBlockNumber(number.toNumber()) | ||
if (options.hardforkByBlockNumber !== undefined && options.hardforkByTD !== undefined) { | ||
throw new Error( | ||
`The hardforkByBlockNumber and hardforkByTD options can't be used in conjunction` | ||
) | ||
} | ||
const hardforkByBlockNumber = options.hardforkByBlockNumber ?? false | ||
if (hardforkByBlockNumber || options.hardforkByTD) { | ||
this._common.setHardforkByBlockNumber(number.toNumber(), options.hardforkByTD) | ||
} | ||
if (this._common.isActivatedEIP(1559)) { | ||
@@ -278,3 +293,6 @@ if (baseFeePerGas === undefined) { | ||
// block option parameter, we instead set difficulty to this value. | ||
if (options.calcDifficultyFromHeader) { | ||
if ( | ||
options.calcDifficultyFromHeader && | ||
this._common.consensusAlgorithm() === ConsensusAlgorithm.Ethash | ||
) { | ||
this.difficulty = this.canonicalDifficulty(options.calcDifficultyFromHeader) | ||
@@ -309,3 +327,13 @@ } | ||
_validateHeaderFields() { | ||
const { parentHash, stateRoot, transactionsTrie, receiptTrie, mixHash, nonce } = this | ||
const { | ||
parentHash, | ||
uncleHash, | ||
stateRoot, | ||
transactionsTrie, | ||
receiptTrie, | ||
difficulty, | ||
extraData, | ||
mixHash, | ||
nonce, | ||
} = this | ||
@@ -340,2 +368,34 @@ if (parentHash.length !== 32) { | ||
} | ||
// Check for constant values for PoS blocks | ||
if (this._common.consensusType() === ConsensusType.ProofOfStake) { | ||
let error = false | ||
let errorMsg = '' | ||
if (!uncleHash.equals(KECCAK256_RLP_ARRAY)) { | ||
errorMsg += `, uncleHash: ${uncleHash.toString( | ||
'hex' | ||
)} (expected: ${KECCAK256_RLP_ARRAY.toString('hex')})` | ||
error = true | ||
} | ||
if (!difficulty.eq(new BN(0))) { | ||
errorMsg += `, difficulty: ${difficulty} (expected: 0)` | ||
error = true | ||
} | ||
if (!extraData.equals(Buffer.from([]))) { | ||
errorMsg += `, extraData: ${extraData.toString('hex')} (expected: '')` | ||
error = true | ||
} | ||
if (!mixHash.equals(zeros(32))) { | ||
errorMsg += `, mixHash: ${mixHash.toString('hex')} (expected: ${zeros(32).toString('hex')})` | ||
error = true | ||
} | ||
if (!nonce.equals(zeros(8))) { | ||
errorMsg += `, nonce: ${nonce.toString('hex')} (expected: ${zeros(8).toString('hex')})` | ||
error = true | ||
} | ||
if (error) { | ||
throw new Error('Invalid PoS block' + errorMsg) | ||
} | ||
} | ||
} | ||
@@ -349,6 +409,6 @@ | ||
canonicalDifficulty(parentBlockHeader: BlockHeader): BN { | ||
if (this._common.consensusType() !== 'pow') { | ||
if (this._common.consensusType() !== ConsensusType.ProofOfWork) { | ||
throw new Error('difficulty calculation is only supported on PoW chains') | ||
} | ||
if (this._common.consensusAlgorithm() !== 'ethash') { | ||
if (this._common.consensusAlgorithm() !== ConsensusAlgorithm.Ethash) { | ||
throw new Error('difficulty calculation currently only supports the ethash algorithm') | ||
@@ -471,3 +531,4 @@ } | ||
// to adopt to the new gas target centered logic | ||
if (this.number.eq(this._common.hardforkBlockBN('london'))) { | ||
const londonHardforkBlock = this._common.hardforkBlockBN('london') | ||
if (londonHardforkBlock && this.number.eq(londonHardforkBlock)) { | ||
const elasticity = new BN(this._common.param('gasConfig', 'elasticityMultiplier')) | ||
@@ -516,3 +577,3 @@ parentGasLimit = parentGasLimit.mul(elasticity) | ||
// Consensus type dependent checks | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() === ConsensusAlgorithm.Ethash) { | ||
// PoW/Ethash | ||
@@ -525,3 +586,4 @@ if ( | ||
} | ||
} else { | ||
} | ||
if (this._common.consensusAlgorithm() === ConsensusAlgorithm.Clique) { | ||
// PoA/Clique | ||
@@ -573,3 +635,3 @@ const minLength = CLIQUE_EXTRA_VANITY + CLIQUE_EXTRA_SEAL | ||
if (this._common.consensusAlgorithm() === 'clique') { | ||
if (this._common.consensusAlgorithm() === ConsensusAlgorithm.Clique) { | ||
const period = this._common.consensusConfig().period | ||
@@ -608,3 +670,4 @@ // Timestamp diff between blocks is lower than PERIOD (clique) | ||
} | ||
const isInitialEIP1559Block = this.number.eq(this._common.hardforkBlockBN('london')) | ||
const block = this._common.hardforkBlockBN('london') | ||
const isInitialEIP1559Block = block && this.number.eq(block) | ||
if (isInitialEIP1559Block) { | ||
@@ -694,2 +757,9 @@ const initialBaseFee = new BN(this._common.param('gasConfig', 'initialBaseFee')) | ||
hash(): Buffer { | ||
if (Object.isFrozen(this)) { | ||
if (!this.cache.hash) { | ||
this.cache.hash = rlphash(this.raw()) | ||
} | ||
return this.cache.hash | ||
} | ||
return rlphash(this.raw()) | ||
@@ -706,3 +776,3 @@ } | ||
private _requireClique(name: string) { | ||
if (this._common.consensusAlgorithm() !== 'clique') { | ||
if (this._common.consensusAlgorithm() !== ConsensusAlgorithm.Clique) { | ||
throw new Error(`BlockHeader.${name}() call only supported for clique PoA networks`) | ||
@@ -884,3 +954,3 @@ } | ||
return header | ||
} catch (error) { | ||
} catch (error: any) { | ||
if (error.type === 'NotFoundError') { | ||
@@ -905,3 +975,3 @@ return undefined | ||
const blockNumber = this.number | ||
const DAOActivationBlock = this._common.hardforkBlockBN('dao') | ||
const DAOActivationBlock = this._common.hardforkBlockBN('dao')! | ||
if (blockNumber.gte(DAOActivationBlock)) { | ||
@@ -908,0 +978,0 @@ const drift = blockNumber.sub(DAOActivationBlock) |
@@ -32,2 +32,13 @@ import { AddressLike, BNLike, BufferLike } from 'ethereumjs-util' | ||
/** | ||
* Determine the HF by total difficulty (Merge HF) | ||
* | ||
* This option is a superset of `hardforkByBlockNumber` (so only use one of both options) | ||
* and determines the HF by both the block number and the TD. | ||
* | ||
* Since the TD is only a threshold the block number will in doubt take precedence (imagine | ||
* e.g. both Merge and Shanghai HF blocks set and the block number from the block provided | ||
* pointing to a Shanghai block: this will lead to set the HF as Shanghai and not the Merge). | ||
*/ | ||
hardforkByTD?: BNLike | ||
/** | ||
* Turns the block header into the canonical genesis block header | ||
@@ -48,2 +59,5 @@ * | ||
* difficulty takes precedence over a provided static `difficulty` value. | ||
* | ||
* Note that this option has no effect on networks other than PoW/Ethash networks | ||
* (respectively also deactivates on the Merge HF switching to PoS/Casper). | ||
*/ | ||
@@ -54,2 +68,3 @@ calcDifficultyFromHeader?: BlockHeader | ||
* strong additional security guarantees on the consistency of the block parameters. | ||
* It also enables block hash caching when the `hash()` method is called multiple times. | ||
* | ||
@@ -56,0 +71,0 @@ * If you need to deactivate the block freeze - e.g. because you want to subclass block and |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15
5651
188
346157
59
Updated@ethereumjs/common@^2.5.0
Updated@ethereumjs/tx@^3.3.1
Updatedethereumjs-util@^7.1.1
Updatedmerkle-patricia-tree@^4.2.1