@ethereumjs/blockchain v6.0.0-beta.1
Pre-releaseThis release is part of a larger breaking release round where all EthereumJS monorepo libraries (VM, Tx, Trie, other) get major version upgrades. This round of releases has been prepared for a long time and we are really pleased with and proud of the result, thanks to all team members and contributors who worked so hard and made this possible! 🙂 ❤️
We have gotten rid of a lot of technical debt and inconsistencies and removed unused functionality, renamed methods, improved on the API and on TypeScript typing, to name a few of the more local type of refactoring changes. There are also broader structural changes like a full transition to native JavaScript BigInt
values as well as various somewhat deep-reaching refactorings, both within a single package as well as some reaching beyond the scope of a single package. Also two completely new packages - @ethereumjs/evm
(in addition to the existing @ethereumjs/vm
package) and @ethereumjs/statemanager
- have been created, leading to a more modular Ethereum JavaScript VM.
We are very much confident that users of the libraries will greatly benefit from the changes being introduced. However - along the upgrade process - these releases require some extra attention and care since the changeset is both so big and deep reaching. We highly recommend to closely read the release notes, we have done our best to create a full picture on the changes with some special emphasis on delicate code and API parts and give some explicit guidance on how to upgrade and where problems might arise!
So, enjoy the releases (this is a first round of Beta releases, with final releases following a couple of weeks after if things go well)! 🎉
The EthereumJS Team
BigInt Introduction / ES2020 Build Target
With this round of breaking releases the whole EthereumJS library stack removes the BN.js library and switches to use native JavaScript BigInt values for large-number operations and interactions.
This makes the libraries more secure and robust (no more BN.js v4 vs v5 incompatibilities) and generally comes with substantial performance gains for the large-number-arithmetic-intense parts of the libraries (particularly the VM).
To allow for BigInt support our build target has been updated to ES2020. We feel that some still remaining browser compatibility issues on the edges (old Safari versions e.g.) are justified by the substantial gains this step brings along.
See #1671 and #1771 for the core BigInt
transition PRs.
Disabled esModuleInterop and allowSyntheticDefaultImports TypeScript Compiler Options
The above TypeScript options provide some semantic sugar like allowing to write an import like import React from "react"
instead of import * as React from "react"
, see esModuleInterop and allowSyntheticDefaultImports docs for some details.
While this is convenient, it deviates from the ESM specification and forces downstream users into using these options, which might not be desirable, see this TypeScript Semver docs section for some more detailed argumentation.
Along with the breaking releases we have therefore deactivated both of these options and you might therefore need to adapt some import statements accordingly. Note that you still can activate these options in your bundle and/or transpilation pipeline (but now you also have the option not to, which you didn't have before).
BigInt-Related and other API Changes
Different methods in the Blockchain library have been renamed for clarity or have a slightly different API due to the BigInt introduction, see PRs #1822 and #1877:
getLatestHeader()
->getCanonicalHeadHeader()
getLatestBlock()
->getCanonicalHeadBlock()
iterator(name: string, onBlock: OnBlock): Promise<void | number>
->iterator(name: string, onBlock: OnBlock): Promise<number>
The following getters and/or methods have been removed:
get meta()
getHead()
(usegetIteratorHead()
instead)setHead()
(usesetIteratorHead()
instead)
Consensus Encapsulation
Consensus-related functionality in the Blockchain
package has been reworked and taken out of the main Blockchain
class, see PR #1756.
There is now a dedicated consensus class for each type of supported consensus, Ethash
, Clique
and Casper
(PoS, this one is rather the do-nothing part of Casper
and letting the respective consensus/beacon client do the hard work! 🙂). Each consensus class adheres to a common interface Consensus
implementing the following five methods in a consensus-specific way:
genesisInit(genesisBlock: Block): Promise<void>
setup(): Promise<void>
validateConsensus(block: Block): Promise<void>
validateDifficulty(header: BlockHeader): Promise<void>
newBlock(block: Block, commonAncestor?: BlockHeader, ancientHeaders?: BlockHeader[]): Promise<void>
There is now a new Blockchain
option consensus
. This makes it very easy to pass in a modified version of an existing consensus implementation or do something totally different and write an own consensus class with consensus rules to follow.
Added Genesis Functionality
PRs #1916 and - as some follow-up work - #1924 rework the genesis code throughout the EthereumJS library stack, with benefits on the bundle size of the lower level libraries (like Block
or Transaction
).
In return the Blockchain
class has gotten new responsibilities on handling genesis state. Genesis state and block functionality previously in the @ethereumjs/common
class has been integrated here, see PR #1916.
A genesis state can now be set along Blockchain
creation by passing in a custom genesisBlock
and genesisState
. For mainnet
and the official test networks like sepolia
or goerli
genesis is already provided with the block data still coming from @ethereumjs/common
, with genesis state now being integrated into the Blockchain
library directly.
The genesis block from the initialized Blockchain
can be retrieved via the new Blockchain.genesisBlock
getter. For creating a genesis block from the params in @ethereumjs/common
, the new createGenesisBlock(stateRoot: Buffer): Block
method can be used.
Note that this is a very large refactoring with mainly the lower-level libraries benefitting. If you miss some functionality here let us know, we are happy to discuss!
Added Validation Methods
The Blockchain class has also gotten new validation methods previously located in the Block
library (where they required a Blockchain
to be passed in as a method parameter), see PR #1959.
The following methods have been taken out of the Block
package and moved into Blockchain
:
BlockHeader.validate(blockchain: Blockchain, height?: bigint): Promise<void>
->Blockchain.validateHeader(header: BlockHeader, height?: bigint)
BlockHeader.validateDifficulty()
,BlockHeader.validateCliqueDifficulty()
->Blockchain.consensus.validateDifficulty()
Block.validateUncles()
-> toBlockchain
, kept private (let us know if you need to call into the functionality)
New File Structue
The file structure of the package has been reworked and aligned with other libraries, see PR #1986. There is now a dedicated blockchain.ts
file for the main source code. The index.ts
is now re-exporting the Blockchain
class and Consensus
implementations as well as the BlockchainInterface
interface, the BlockchainOptions
dictionary and types from a dedicated types.ts
file.
Level DB Upgrade / Browser Compatibility
The internal Level DB code has been reworked to now be based and work with the latest Level v8.0.0 major Level DB release, see PR #1949. This allows to use ES6-style import
syntax to import the Level
instance and allows for better typing when working with Level DB.
Because the usage of level
and memory-level
there are now 3 different possible instances of abstract-level
, all with a consistent interface due to abstract-level
. These instances are classic-level
, browser-level
and memory-level
. This now makes it a lot easier to use the package in browsers without polyfills for level
. For some context it is worth to mention that starting with the v8 release, the level
package is just a proxy for these other packages and has no functionality itself.