Skip to content

Commit

Permalink
Merge branch 'master' into util/remove-isTruthy-isFalsy
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrocheleau authored Aug 31, 2022
2 parents 0f2f077 + 45e47e3 commit 84db1a1
Show file tree
Hide file tree
Showing 109 changed files with 603 additions and 734 deletions.
6 changes: 3 additions & 3 deletions packages/block/src/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ConsensusType } from '@ethereumjs/common'
import { RLP } from '@ethereumjs/rlp'
import { Trie } from '@ethereumjs/trie'
import { Capability, TransactionFactory } from '@ethereumjs/tx'
import { KECCAK256_RLP, arrToBufArr, bufArrToArr, bufferToHex, isTruthy } from '@ethereumjs/util'
import { KECCAK256_RLP, arrToBufArr, bufArrToArr, bufferToHex } from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak'

import { BlockHeader } from './header'
Expand Down Expand Up @@ -104,7 +104,7 @@ export class Block {

// parse transactions
const transactions = []
for (const txData of isTruthy(txsData) ? txsData : []) {
for (const txData of txsData ?? []) {
transactions.push(
TransactionFactory.fromBlockBodyData(txData, {
...opts,
Expand All @@ -130,7 +130,7 @@ export class Block {
if (opts?.hardforkByTTD !== undefined) {
uncleOpts.hardforkByBlockNumber = true
}
for (const uncleHeaderData of isTruthy(uhsData) ? uhsData : []) {
for (const uncleHeaderData of uhsData ?? []) {
uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts))
}

Expand Down
27 changes: 16 additions & 11 deletions packages/block/src/from-rpc.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { TransactionFactory } from '@ethereumjs/tx'
import { isTruthy, setLengthLeft, toBuffer } from '@ethereumjs/util'
import { setLengthLeft, toBuffer } from '@ethereumjs/util'

import { blockHeaderFromRpc } from './header-from-rpc'
import { numberToHex } from './helpers'

import { Block } from './index'

import type { BlockOptions } from './index'
import type { BlockOptions, JsonRpcBlock } from './index'
import type { TxData, TypedTransaction } from '@ethereumjs/tx'

function normalizeTxParams(_txParams: any) {
Expand All @@ -20,7 +20,10 @@ function normalizeTxParams(_txParams: any) {
txParams.value = numberToHex(txParams.value)

// strict byte length checking
txParams.to = isTruthy(txParams.to) ? setLengthLeft(toBuffer(txParams.to), 20) : null
txParams.to =
txParams.to !== null && txParams.to !== undefined
? setLengthLeft(toBuffer(txParams.to), 20)
: null

// v as raw signature value {0,1}
// v is the recovery bit and can be either {0,1} or {27,28}.
Expand All @@ -38,17 +41,19 @@ function normalizeTxParams(_txParams: any) {
* @param uncles - Optional list of Ethereum JSON RPC of uncles (eth_getUncleByBlockHashAndIndex)
* @param options - An object describing the blockchain
*/
export function blockFromRpc(blockParams: any, uncles: any[] = [], options?: BlockOptions) {
export function blockFromRpc(
blockParams: JsonRpcBlock,
uncles: any[] = [],
options?: BlockOptions
) {
const header = blockHeaderFromRpc(blockParams, options)

const transactions: TypedTransaction[] = []
if (isTruthy(blockParams.transactions)) {
const opts = { common: header._common }
for (const _txParams of blockParams.transactions) {
const txParams = normalizeTxParams(_txParams)
const tx = TransactionFactory.fromTxData(txParams as TxData, opts)
transactions.push(tx)
}
const opts = { common: header._common }
for (const _txParams of blockParams.transactions) {
const txParams = normalizeTxParams(_txParams)
const tx = TransactionFactory.fromTxData(txParams as TxData, opts)
transactions.push(tx)
}

const uncleHeaders = uncles.map((uh) => blockHeaderFromRpc(uh, options))
Expand Down
9 changes: 3 additions & 6 deletions packages/block/src/header-from-rpc.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import { isTruthy } from '@ethereumjs/util'

import { BlockHeader } from './header'
import { numberToHex } from './helpers'

import type { BlockOptions } from './types'
import type { BlockOptions, JsonRpcBlock } from './types'

/**
* Creates a new block header object from Ethereum JSON RPC.
*
* @param blockParams - Ethereum JSON RPC of block (eth_getBlockByNumber)
* @param options - An object describing the blockchain
*/
export function blockHeaderFromRpc(blockParams: any, options?: BlockOptions) {
export function blockHeaderFromRpc(blockParams: JsonRpcBlock, options?: BlockOptions) {
const {
parentHash,
sha3Uncles,
miner,
stateRoot,
transactionsRoot,
receiptRoot,
receiptsRoot,
logsBloom,
difficulty,
Expand All @@ -39,7 +36,7 @@ export function blockHeaderFromRpc(blockParams: any, options?: BlockOptions) {
coinbase: miner,
stateRoot,
transactionsTrie: transactionsRoot,
receiptTrie: isTruthy(receiptRoot) ? receiptRoot : receiptsRoot,
receiptTrie: receiptsRoot,
logsBloom,
difficulty: numberToHex(difficulty),
number,
Expand Down
24 changes: 15 additions & 9 deletions packages/block/src/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import {
bufferToHex,
ecrecover,
ecsign,
isFalsy,
isTruthy,
toType,
zeros,
} from '@ethereumjs/util'
Expand Down Expand Up @@ -160,9 +158,9 @@ export class BlockHeader {

const parentHash = toType(headerData.parentHash, TypeOutput.Buffer) ?? defaults.parentHash
const uncleHash = toType(headerData.uncleHash, TypeOutput.Buffer) ?? defaults.uncleHash
const coinbase = isTruthy(headerData.coinbase)
? new Address(toType(headerData.coinbase, TypeOutput.Buffer))
: defaults.coinbase
const coinbase = new Address(
toType(headerData.coinbase ?? defaults.coinbase, TypeOutput.Buffer)
)
const stateRoot = toType(headerData.stateRoot, TypeOutput.Buffer) ?? defaults.stateRoot
const transactionsTrie =
toType(headerData.transactionsTrie, TypeOutput.Buffer) ?? defaults.transactionsTrie
Expand Down Expand Up @@ -300,9 +298,13 @@ export class BlockHeader {
throw new Error(msg)
}
const londonHfBlock = this._common.hardforkBlock(Hardfork.London)
if (isTruthy(londonHfBlock) && this.number === londonHfBlock) {
if (
typeof londonHfBlock === 'bigint' &&
londonHfBlock !== BigInt(0) &&
this.number === londonHfBlock
) {
const initialBaseFee = this._common.param('gasConfig', 'initialBaseFee')
if (this.baseFeePerGas! !== initialBaseFee) {
if (this.baseFeePerGas !== initialBaseFee) {
const msg = this._errorMsg('Initial EIP1559 block does not have initial base fee')
throw new Error(msg)
}
Expand Down Expand Up @@ -404,7 +406,11 @@ export class BlockHeader {
// EIP-1559: assume double the parent gas limit on fork block
// to adopt to the new gas target centered logic
const londonHardforkBlock = this._common.hardforkBlock(Hardfork.London)
if (isTruthy(londonHardforkBlock) && this.number === londonHardforkBlock) {
if (
typeof londonHardforkBlock === 'bigint' &&
londonHardforkBlock !== BigInt(0) &&
this.number === londonHardforkBlock
) {
const elasticity = this._common.param('gasConfig', 'elasticityMultiplier')
parentGasLimit = parentGasLimit * elasticity
}
Expand Down Expand Up @@ -774,7 +780,7 @@ export class BlockHeader {
return
}
const DAOActivationBlock = this._common.hardforkBlock(Hardfork.Dao)
if (isFalsy(DAOActivationBlock) || this.number < DAOActivationBlock) {
if (DAOActivationBlock === null || this.number < DAOActivationBlock) {
return
}
const DAO_ExtraData = Buffer.from('64616f2d686172642d666f726b', 'hex')
Expand Down
4 changes: 2 additions & 2 deletions packages/block/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TypeOutput, isFalsy, isHexString, toType } from '@ethereumjs/util'
import { TypeOutput, isHexString, toType } from '@ethereumjs/util'

import type { BlockHeaderBuffer, HeaderData } from './types'

Expand All @@ -7,7 +7,7 @@ import type { BlockHeaderBuffer, HeaderData } from './types'
* @param {string} input string to check, convert, and return
*/
export const numberToHex = function (input?: string) {
if (isFalsy(input)) return undefined
if (input === undefined) return undefined
if (!isHexString(input)) {
const regex = new RegExp(/^\d+$/) // test to make sure input contains only digits
if (!regex.test(input)) {
Expand Down
28 changes: 28 additions & 0 deletions packages/block/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Common } from '@ethereumjs/common'
import type {
AccessListEIP2930TxData,
FeeMarketEIP1559TxData,
JsonRpcTx,
JsonTx,
TxData,
} from '@ethereumjs/tx'
Expand Down Expand Up @@ -150,3 +151,30 @@ export interface JsonHeader {
nonce?: string
baseFeePerGas?: string
}

/*
* Based on https://eth.wiki/json-rpc/API
*/
export interface JsonRpcBlock {
number: string // the block number. null when pending block.
hash: string // hash of the block. null when pending block.
parentHash: string // hash of the parent block.
mixHash?: string // bit hash which proves combined with the nonce that a sufficient amount of computation has been carried out on this block.
nonce: string // hash of the generated proof-of-work. null when pending block.
sha3Uncles: string // SHA3 of the uncles data in the block.
logsBloom: string // the bloom filter for the logs of the block. null when pending block.
transactionsRoot: string // the root of the transaction trie of the block.
stateRoot: string // the root of the final state trie of the block.
receiptsRoot: string // the root of the receipts trie of the block.
miner: string // the address of the beneficiary to whom the mining rewards were given.
difficulty: string // integer of the difficulty for this block.
totalDifficulty: string // integer of the total difficulty of the chain until this block.
extraData: string // the “extra data” field of this block.
size: string // integer the size of this block in bytes.
gasLimit: string // the maximum gas allowed in this block.
gasUsed: string // the total used gas by all transactions in this block.
timestamp: string // the unix timestamp for when the block was collated.
transactions: Array<JsonRpcTx | string> // Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter.
uncles: string[] // Array of uncle hashes
baseFeePerGas?: string // If EIP-1559 is enabled for this block, returns the base fee per gas
}
4 changes: 2 additions & 2 deletions packages/block/test/block.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import * as testDataPreLondon2 from './testdata/testdata_pre-london-2.json'
import * as testDataPreLondon from './testdata/testdata_pre-london.json'
import * as testnetMerge from './testdata/testnetMerge.json'

import type { BlockBuffer } from '../src'
import type { BlockBuffer, JsonRpcBlock } from '../src'
import type { NestedUint8Array } from '@ethereumjs/util'

tape('[Block]: block functions', function (t) {
Expand Down Expand Up @@ -176,7 +176,7 @@ tape('[Block]: block functions', function (t) {
const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.Chainstart })

try {
blockFromRpc(testDataFromRpcGoerli, [], { common })
blockFromRpc(testDataFromRpcGoerli as unknown as JsonRpcBlock, [], { common })
st.pass('does not throw')
} catch (error: any) {
st.fail('error thrown')
Expand Down
19 changes: 12 additions & 7 deletions packages/block/test/from-rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ import * as blockDataWithUncles from './testdata/testdata-from-rpc-with-uncles.j
import * as uncleBlockData from './testdata/testdata-from-rpc-with-uncles_uncle-block-data.json'
import * as blockData from './testdata/testdata-from-rpc.json'

import type { JsonRpcBlock } from '../src/types'
import type { Transaction } from '@ethereumjs/tx'

tape('[fromRPC]: block #2924874', function (t) {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Istanbul })

t.test('should create a block with transactions with valid signatures', function (st) {
const block = blockFromRpc(blockData, [], { common })
const block = blockFromRpc(blockData as unknown as JsonRpcBlock, [], { common })
const allValid = block.transactions.every((tx) => tx.verifySignature())
st.equal(allValid, true, 'all transaction signatures are valid')
st.end()
})

t.test('should create a block header with the correct hash', function (st) {
const block = blockHeaderFromRpc(blockData, { common })
const block = blockHeaderFromRpc(blockData as unknown as JsonRpcBlock, { common })
const hash = Buffer.from(blockData.hash.slice(2), 'hex')
st.ok(block.hash().equals(hash))
st.end()
Expand All @@ -45,7 +46,7 @@ tape('[fromRPC]:', function (t) {
const blockDataTransactionValueAsInteger = blockData
blockDataTransactionValueAsInteger.transactions[0].value = valueAsIntegerString
const blockFromTransactionValueAsInteger = blockFromRpc(
blockDataTransactionValueAsInteger,
blockDataTransactionValueAsInteger as unknown as JsonRpcBlock,
undefined,
{ common }
)
Expand All @@ -66,7 +67,7 @@ tape('[fromRPC]:', function (t) {
const blockDataTransactionGasPriceAsInteger = blockData
blockDataTransactionGasPriceAsInteger.transactions[0].gasPrice = gasPriceAsIntegerString
const blockFromTransactionGasPriceAsInteger = blockFromRpc(
blockDataTransactionGasPriceAsInteger,
blockDataTransactionGasPriceAsInteger as unknown as JsonRpcBlock,
undefined,
{ common }
)
Expand All @@ -83,9 +84,13 @@ tape('[fromRPC]:', function (t) {
'should create a block given json data that includes a difficulty parameter of type integer string',
function (st) {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London })
const blockDifficultyAsInteger = blockFromRpc(blockDataDifficultyAsInteger, undefined, {
common,
})
const blockDifficultyAsInteger = blockFromRpc(
blockDataDifficultyAsInteger as unknown as JsonRpcBlock,
undefined,
{
common,
}
)
st.equal(
blockDifficultyAsInteger.header.difficulty.toString(),
blockDataDifficultyAsInteger.difficulty
Expand Down
4 changes: 2 additions & 2 deletions packages/block/test/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Chain, Common, Hardfork } from '@ethereumjs/common'
import { RLP } from '@ethereumjs/rlp'
import { bufArrToArr, isTruthy } from '@ethereumjs/util'
import { bufArrToArr } from '@ethereumjs/util'
import { keccak256 } from 'ethereum-cryptography/keccak'

import { Block } from '../src'
Expand Down Expand Up @@ -33,7 +33,7 @@ function createBlock(

const londonHfBlock = common.hardforkBlock(Hardfork.London)
const baseFeePerGas =
isTruthy(londonHfBlock) && number > londonHfBlock
typeof londonHfBlock === 'bigint' && londonHfBlock !== BigInt(0) && number > londonHfBlock
? parentBlock.header.calcNextBaseFee()
: undefined

Expand Down
Loading

0 comments on commit 84db1a1

Please sign in to comment.