Skip to content

@ethereumjs/blockchain v6.0.0-beta.1

Pre-release
Pre-release
Compare
Choose a tag to compare
@holgerd77 holgerd77 released this 30 Jun 10:23
· 1405 commits to master since this release
c5260ba

This 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() (use getIteratorHead() instead)
  • setHead() (use setIteratorHead() 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() -> to Blockchain, 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.