Skip to content

@ethereumjs/block v3.0.0-beta.1

Pre-release
Pre-release
Compare
Choose a tag to compare
@holgerd77 holgerd77 released this 22 Oct 09:48
· 4794 commits to master since this release
97345b5

ATTENTION: This is a pre-release and only meant to be used for testing purposes.

Do not use in production!

Feedback is extremely welcome, please use the beta.1 Releases feedback issue #923 or our Discord channel.


New Package Name

Attention! This new version is part of a series of EthereumJS releases all moving to a new scoped package name format. In this case the library is renamed as follows:

  • ethereumjs-block -> @ethereumjs/block

Please update your library references accordingly or install with:

npm i @ethereumjs/block

TypeScript/Library Import

This is the first TypeScript based release of the library, see PR #72.
The import structure has slightly changed along:

TypeScript

import { BlockHeader } from 'ethereumjs-block'
import { Block } from 'ethereumjs-block'

JavaScript/Node.js

const BlockHeader = require('ethereumjs-block').BlockHeader
const Block = require('ethereumjs-block').Block

The library now also comes with a type declaration file distributed along with the package published.

Major Refactoring - Breaking Changes

This release is a major refactoring of the block library to simplify and strengthen its code base. Refactoring work has been done along PR #72 (Promises) and PR #883 (refactoring of API and internal code structure).

New Constructor Params

The way to instantiate a new BlockHeader or Block object has been completely reworked and is now more explicit, less error prone and produces more TypeScript friendly and readable code.

The old direct constructor usage is now discouraged in favor of different dedicated static factory methods to create new objects.

Breaking: While the main constructors can still be called, signatures changed significantly and your old new Block(...), new BlockHeader(...) instantiations won't work any more and needs to be updated.

BlockHeader Class

There are three new factory methods to create a new BlockHeader:

  1. Pass in a Header-attribute named dictionary to BlockHeader.fromHeaderData(headerData: HeaderData = {}, opts: BlockOptions = {}):
const headerData = {
  number: 15,
  parentHash: '0x6bfee7294bf44572b7266358e627f3c35105e1c3851f3de09e6d646f955725a7',
  difficulty: 131072,
  gasLimit: 8000000,
  timestamp: 1562422144,
}
const header = BlockHeader.fromHeaderData(headerData, {})
  1. Create a BlockHeader from an RLP-serialized header Buffer with BlockHeader.fromRLPSerializedHeader(serialized: Buffer, opts: BlockOptions).
const serialized = Buffer.from(
  'f901f7a06bfee7294bf44572b7266358e627f3c35105e1c3851f3de09e6d646f955725a7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000f837a120080845d20ab8080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000',
  'hex',
)
const header = BlockHeader.fromRLPSerializedHeader(serialized, {})
  1. Create a BlockHeader from an array of Buffer values, you can do a first short roundtrip test with:
const valuesArray = header.raw()
BlockHeader.fromValuesArray(valuesArray, {})

Generally internal types representing block header values are now closer to their domain representation (number, difficulty, gasLimit) instead of having everthing represented as a Buffer.

Block Class

There are analogue new static factories for the Block class:

  • Block.fromBlockData(blockData: BlockData = {}, opts: BlockOptions = {})
  • Block.fromRLPSerializedBlock(serialized: Buffer, opts: BlockOptions = {})
  • Block.fromValuesArray(values: BlockBuffer, opts: BlockOptions = {})

Learn more about the full API in the docs.

Immutability

The returned block is now frozen and immutable. To work with a maliable block, copy it with const fakeBlock = Object.create(block).

Promise-based API

The API of this library is now completely promise-based and the old callback-style interface has been dropped.

This affects the following methods of the API now being defined as async and returning a Promise:

Header Class

  • BlockHeader.validate(blockchain: Blockchain, height?: BN): Promise<void>

Block Class

  • Block.genTxTrie(): Promise<void>
  • Block.validate(blockChain: Blockchain): Promise<void>
  • Block.validateUncles(blockchain: Blockchain): Promise<void>

Usage example:

try {
  await block.validate(blockchain)
  // Block validation has passed
} catch (err) {
  // handle errors appropriately
}

Header Validation Methods > Signature Changes

Breaking: The signatures of the following header validation methods have been updated to take a parentBlockHeader instead of a
parentBlock input parameter for consistency and removing a circling dependency with Block:

  • BlockHeader.canonicalDifficulty(parentBlockHeader: BlockHeader): BN
  • BlockHeader.validateDifficulty(parentBlockHeader: BlockHeader): boolean
  • BlockHeader.validateGasLimit(parentBlockHeader: BlockHeader): boolean

On the Block library new corresponding methods have been added which both operate on a block instance and expect a parentBlock as an input parameter.

New Default Hardfork

Breaking: The default HF on the library has been updated from petersburg to instanbul, see PR #906.
The HF setting is now automatically taken from the HF set for Common.DEAULT_HARDFORK, see PR #863.

Dual ES5 and ES2017 Builds

We significantly updated our internal tool and CI setup along the work on PR #913 with an update to ESLint from TSLint for code linting and formatting and the introduction of a new build setup.

Packages now target ES2017 for Node.js builds (the main entrypoint from package.json) and introduce a separate ES5 build distributed along using the browser directive as an entrypoint, see PR #921. This will result in performance benefits for Node.js consumers, see here for a releated discussion.

Other Changes

Features

  • Added Block.genesis() and BlockHeader.genesis() aliases to create a genesis block or header, PR #883
  • Added DAO hardfork support (check for extraData attribute if DAO HF is active), PR #843

Changes and Refactoring

  • Added Node 10, 12 support, dropped Node 7 support, PR #72
  • Passing in a blockchain is now optional on Block.validate(), PR #883
  • Breaking: Block.validateTransactions(stringError: true) now returns a string[], PR #883
  • Breaking: Decoupling of the Block.serialize() and Block.raw() methods, Block.serialize() now always returns the RLP-encoded block (signature change!), Block.raw() always returns the pure Buffer array, PR #883
  • Breaking: Block.toJSON() now always returns the labeled JSON representation, removal of the labeled function parameter, PR #883
  • Updated merkle-patricia-tree dependency to v4, PR #787
  • Updated ethereumjs-util dependency to v7, PR #748
  • Removal of the async dependency, PR #72

CI and Testing

  • Browser test run on CI, PR #72
  • Karma browser test run config modernization and simplification PR #72
  • Updated test source files to TypeScript, PR #72

Bug Fixes

  • Signature fix for pre-homestead blocks, PR #67