From 81ae11d4d10bc526dafb796e87409ed85be68cec Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 24 Aug 2022 22:31:50 -0400 Subject: [PATCH 01/56] vm: remove isTruthy and isFalsy --- packages/vm/src/bloom/index.ts | 8 +++----- packages/vm/src/buildBlock.ts | 9 +++++---- packages/vm/src/eei/vmState.ts | 10 +++++----- packages/vm/src/runBlock.ts | 14 +++----------- packages/vm/src/vm.ts | 4 ++-- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/packages/vm/src/bloom/index.ts b/packages/vm/src/bloom/index.ts index 0bdc5fd60c..78b8d529b8 100644 --- a/packages/vm/src/bloom/index.ts +++ b/packages/vm/src/bloom/index.ts @@ -1,4 +1,4 @@ -import { isTruthy, zeros } from '@ethereumjs/util' +import { zeros } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' const BYTE_SIZE = 256 @@ -67,10 +67,8 @@ export class Bloom { * Bitwise or blooms together. */ or(bloom: Bloom) { - if (isTruthy(bloom)) { - for (let i = 0; i <= BYTE_SIZE; i++) { - this.bitvector[i] = this.bitvector[i] | bloom.bitvector[i] - } + for (let i = 0; i <= BYTE_SIZE; i++) { + this.bitvector[i] = this.bitvector[i] | bloom.bitvector[i] } } } diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 6365f43ada..bc58f2f194 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -2,7 +2,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { Address, TypeOutput, isTruthy, toBuffer, toType } from '@ethereumjs/util' +import { Address, TypeOutput, toBuffer, toType } from '@ethereumjs/util' import { Bloom } from './bloom' import { calculateMinerReward, encodeReceipt, rewardAccount } from './runBlock' @@ -104,9 +104,10 @@ export class BlockBuilder { private async rewardMiner() { const minerReward = this.vm._common.param('pow', 'minerReward') const reward = calculateMinerReward(minerReward, 0) - const coinbase = isTruthy(this.headerData.coinbase) - ? new Address(toBuffer(this.headerData.coinbase)) - : Address.zero() + const coinbase = + this.headerData.coinbase !== undefined + ? new Address(toBuffer(this.headerData.coinbase)) + : Address.zero() await rewardAccount(this.vm.eei, coinbase, reward) } diff --git a/packages/vm/src/eei/vmState.ts b/packages/vm/src/eei/vmState.ts index bdf14f4fba..3837a5fef6 100644 --- a/packages/vm/src/eei/vmState.ts +++ b/packages/vm/src/eei/vmState.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { ripemdPrecompileAddress } from '@ethereumjs/evm/dist/precompiles' -import { Account, Address, isTruthy, toBuffer } from '@ethereumjs/util' +import { Account, Address, toBuffer } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import type { EVMStateAccess } from '@ethereumjs/evm/dist/types' @@ -210,12 +210,12 @@ export class VmState implements EVMStateAccess { * Merges a storage map into the last item of the accessed storage stack */ private _accessedStorageMerge( - storageList: Map>[], + storageList: Map | undefined>[], storageMap: Map> ) { const mapTarget = storageList[storageList.length - 1] - if (isTruthy(mapTarget)) { + if (mapTarget !== undefined) { // Note: storageMap is always defined here per definition (TypeScript cannot infer this) for (const [addressString, slotSet] of storageMap) { const addressExists = mapTarget.get(addressString) @@ -255,10 +255,10 @@ export class VmState implements EVMStateAccess { const [balance, code, storage] = state const account = Account.fromAccountData({ balance }) await this.putAccount(addr, account) - if (isTruthy(code)) { + if (code !== undefined) { await this.putContractCode(addr, toBuffer(code)) } - if (isTruthy(storage)) { + if (storage !== undefined) { for (const [key, value] of storage) { await this.putContractStorage(addr, toBuffer(key), toBuffer(value)) } diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index 1177c02dcf..c0ebb76d87 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -2,15 +2,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { - Account, - Address, - bigIntToBuffer, - bufArrToArr, - intToBuffer, - isTruthy, - short, -} from '@ethereumjs/util' +import { Account, Address, bigIntToBuffer, bufArrToArr, intToBuffer, short } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { Bloom } from './bloom' @@ -53,8 +45,8 @@ export async function runBlock(this: VM, opts: RunBlockOpts): Promise { common: (eeiCopy as any)._common, evm: evmCopy, hardforkByBlockNumber: this._hardforkByBlockNumber ? true : undefined, - hardforkByTTD: isTruthy(this._hardforkByTTD) ? this._hardforkByTTD : undefined, + hardforkByTTD: this._hardforkByTTD, }) } From 4d32e3273bd94713c5ce6115116438774b5c24ef Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:06:12 -0400 Subject: [PATCH 02/56] vm: remove additional isTruthy/isFalsy from vm --- packages/vm/src/runTx.ts | 4 +-- .../tests/api/EIPs/eip-3074-authcall.spec.ts | 34 ++++--------------- .../vm/tests/api/istanbul/eip-1884.spec.ts | 4 +-- packages/vm/tests/util.ts | 18 ++++------ 4 files changed, 18 insertions(+), 42 deletions(-) diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 5333581099..3fbbb638cd 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -1,7 +1,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { Capability } from '@ethereumjs/tx' -import { Address, KECCAK256_NULL, isFalsy, short, toBuffer } from '@ethereumjs/util' +import { Address, KECCAK256_NULL, short, toBuffer } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { Bloom } from './bloom' @@ -31,7 +31,7 @@ const debugGas = createDebugLogger('vm:tx:gas') */ export async function runTx(this: VM, opts: RunTxOpts): Promise { // tx is required - if (isFalsy(opts.tx)) { + if (opts.tx === undefined) { throw new Error('invalid input, tx is required') } diff --git a/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts index 478e484545..debbe651d2 100644 --- a/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts @@ -7,7 +7,6 @@ import { bigIntToBuffer, bufferToBigInt, ecsign, - isTruthy, privateToAddress, setLengthLeft, toBuffer, @@ -171,33 +170,14 @@ function MSTORE(position: Buffer, value: Buffer) { * @returns - The bytecode to execute AUTHCALL */ function getAuthCallCode(data: AuthcallData) { - const ZEROS32 = zeros(32) - const gasLimitBuffer = setLengthLeft( - isTruthy(data.gasLimit) ? bigIntToBuffer(data.gasLimit) : ZEROS32, - 32 - ) + const gasLimitBuffer = setLengthLeft(bigIntToBuffer(data.gasLimit ?? 0n), 32) const addressBuffer = setLengthLeft(data.address.buf, 32) - const valueBuffer = setLengthLeft(isTruthy(data.value) ? bigIntToBuffer(data.value) : ZEROS32, 32) - const valueExtBuffer = setLengthLeft( - isTruthy(data.valueExt) ? bigIntToBuffer(data.valueExt) : ZEROS32, - 32 - ) - const argsOffsetBuffer = setLengthLeft( - isTruthy(data.argsOffset) ? bigIntToBuffer(data.argsOffset) : ZEROS32, - 32 - ) - const argsLengthBuffer = setLengthLeft( - isTruthy(data.argsLength) ? bigIntToBuffer(data.argsLength) : ZEROS32, - 32 - ) - const retOffsetBuffer = setLengthLeft( - isTruthy(data.retOffset) ? bigIntToBuffer(data.retOffset) : ZEROS32, - 32 - ) - const retLengthBuffer = setLengthLeft( - isTruthy(data.retLength) ? bigIntToBuffer(data.retLength) : ZEROS32, - 32 - ) + const valueBuffer = setLengthLeft(bigIntToBuffer(data.value ?? 0n), 32) + const valueExtBuffer = setLengthLeft(bigIntToBuffer(data.valueExt ?? 0n), 32) + const argsOffsetBuffer = setLengthLeft(bigIntToBuffer(data.argsOffset ?? 0n), 32) + const argsLengthBuffer = setLengthLeft(bigIntToBuffer(data.argsLength ?? 0n), 32) + const retOffsetBuffer = setLengthLeft(bigIntToBuffer(data.retOffset ?? 0n), 32) + const retLengthBuffer = setLengthLeft(bigIntToBuffer(data.retLength ?? 0n), 32) const PUSH32 = Buffer.from('7f', 'hex') const AUTHCALL = Buffer.from('f7', 'hex') const order = [ diff --git a/packages/vm/tests/api/istanbul/eip-1884.spec.ts b/packages/vm/tests/api/istanbul/eip-1884.spec.ts index 2d836e79c7..c0d2e7f296 100644 --- a/packages/vm/tests/api/istanbul/eip-1884.spec.ts +++ b/packages/vm/tests/api/istanbul/eip-1884.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { ERROR } from '@ethereumjs/evm/dist/exceptions' -import { Address, bufferToBigInt, isTruthy } from '@ethereumjs/util' +import { Address, bufferToBigInt } from '@ethereumjs/util' import * as tape from 'tape' import { VM } from '../../../src/vm' @@ -27,7 +27,7 @@ tape('Istanbul: EIP-1884', async (t) => { const common = new Common({ chain, hardfork }) const vm = await VM.create({ common }) - const balance = isTruthy(testCase.selfbalance) ? BigInt(testCase.selfbalance) : undefined + const balance = testCase.selfbalance !== undefined ? BigInt(testCase.selfbalance) : undefined const account = createAccount(BigInt(0), balance) await vm.stateManager.putAccount(addr, account) diff --git a/packages/vm/tests/util.ts b/packages/vm/tests/util.ts index c1f523cb53..5effb04bed 100644 --- a/packages/vm/tests/util.ts +++ b/packages/vm/tests/util.ts @@ -12,9 +12,7 @@ import { bigIntToBuffer, bufferToBigInt, bufferToHex, - isFalsy, isHexPrefixed, - isTruthy, setLengthLeft, stripHexPrefix, toBuffer, @@ -118,15 +116,15 @@ export function makeTx( opts?: TxOptions ): FeeMarketEIP1559Transaction | AccessListEIP2930Transaction | Transaction { let tx - if (isTruthy(txData.maxFeePerGas)) { + if (txData.maxFeePerGas !== undefined) { tx = FeeMarketEIP1559Transaction.fromTxData(txData, opts) - } else if (isTruthy(txData.accessLists)) { + } else if (txData.accessLists !== undefined) { tx = AccessListEIP2930Transaction.fromTxData(txData, opts) } else { tx = Transaction.fromTxData(txData, opts) } - if (isTruthy(txData.secretKey)) { + if (txData.secretKey !== undefined) { const privKey = toBuffer(txData.secretKey) return tx.sign(privKey) } @@ -157,7 +155,7 @@ export async function verifyPostConditions(state: any, testData: any, t: tape.Te const address = keyMap[key] delete keyMap[key] - if (isTruthy(testData)) { + if (testData !== undefined) { const promise = verifyAccountPostConditions(state, address, account, testData, t) queue.push(promise) } else { @@ -223,9 +221,7 @@ export function verifyAccountPostConditions( if (key === '0x') { key = '0x00' - acctData.storage['0x00'] = isTruthy(acctData.storage['0x00']) - ? acctData.storage['0x00'] - : acctData.storage['0x'] + acctData.storage['0x00'] = acctData.storage['0x00'] ?? acctData.storage['0x'] delete acctData.storage['0x'] } @@ -259,9 +255,9 @@ export function verifyAccountPostConditions( */ export function verifyGas(results: any, testData: any, t: tape.Test) { const coinbaseAddr = testData.env.currentCoinbase - const preBal = isTruthy(testData.pre[coinbaseAddr]) ? testData.pre[coinbaseAddr].balance : 0 + const preBal = testData.pre[coinbaseAddr] !== undefined ? testData.pre[coinbaseAddr].balance : 0 - if (isFalsy(testData.post[coinbaseAddr])) { + if (testData.post[coinbaseAddr] === undefined) { return } From fbe9e1039e0556cad160b2cea990ec3628c91949 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:29:09 -0400 Subject: [PATCH 03/56] statemanager: remove isFalsy and isTruthy --- packages/statemanager/src/cache.ts | 39 +++++++++++------------ packages/statemanager/src/stateManager.ts | 12 ++++--- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/statemanager/src/cache.ts b/packages/statemanager/src/cache.ts index 4005104e14..3633f82f28 100644 --- a/packages/statemanager/src/cache.ts +++ b/packages/statemanager/src/cache.ts @@ -1,4 +1,4 @@ -import { Account, isFalsy, isTruthy } from '@ethereumjs/util' +import { Account } from '@ethereumjs/util' import type { Address } from '@ethereumjs/util' @@ -60,7 +60,7 @@ export class Cache { const keyStr = key.buf.toString('hex') const it = this._cache.find(keyStr) - if (isTruthy(it.node)) { + if (it.node !== null) { const rlp = it.value.val const account = Account.fromRlpSerializedAccount(rlp) ;(account as any).virtual = it.value.virtual @@ -75,7 +75,7 @@ export class Cache { keyIsDeleted(key: Address): boolean { const keyStr = key.buf.toString('hex') const it = this._cache.find(keyStr) - if (isTruthy(it.node)) { + if (it.node !== null) { return it.value.deleted } return false @@ -111,26 +111,23 @@ export class Cache { const it = this._cache.begin let next = true while (next) { - if (isTruthy(it.value) && isTruthy(it.value.modified) && isFalsy(it.value.deleted)) { + if (it.value !== undefined && it.value.modified === true) { it.value.modified = false - const accountRlp = it.value.val const keyBuf = Buffer.from(it.key, 'hex') - await this._putCb(keyBuf, accountRlp) - next = it.hasNext - it.next() - } else if (isTruthy(it.value) && isTruthy(it.value.modified) && isTruthy(it.value.deleted)) { - it.value.modified = false - it.value.deleted = true - it.value.virtual = true - it.value.val = new Account().serialize() - const keyBuf = Buffer.from(it.key, 'hex') - await this._deleteCb(keyBuf) - next = it.hasNext - it.next() - } else { - next = it.hasNext - it.next() + if (it.value.deleted === false) { + const accountRlp = it.value.val + await this._putCb(keyBuf, accountRlp) + } else { + it.value.modified = false + it.value.deleted = true + it.value.virtual = true + it.value.val = new Account().serialize() + await this._deleteCb(keyBuf) + } } + + next = it.hasNext + it.next() } } @@ -190,7 +187,7 @@ export class Cache { const keyHex = key.buf.toString('hex') const it = this._cache.find(keyHex) const val = value.serialize() - if (isTruthy(it.node)) { + if (it.node !== null) { this._cache = it.update({ val, modified, deleted, virtual }) } else { this._cache = this._cache.insert(keyHex, { val, modified, deleted, virtual }) diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 93e5f3670a..aafab81fa3 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -6,8 +6,6 @@ import { KECCAK256_RLP, bigIntToHex, bufferToHex, - isFalsy, - isTruthy, setLengthLeft, short, toBuffer, @@ -189,7 +187,7 @@ export class DefaultStateManager extends BaseStateManager implements StateManage // from storage cache const addressHex = address.buf.toString('hex') let storageTrie = this._storageTries[addressHex] - if (isFalsy(storageTrie)) { + if (storageTrie === undefined || storageTrie === null) { // lookup from state storageTrie = await this._lookupStorageTrie(address) } @@ -264,7 +262,7 @@ export class DefaultStateManager extends BaseStateManager implements StateManage value = unpadBuffer(value) await this._modifyContractStorage(address, async (storageTrie, done) => { - if (isTruthy(value) && value.length) { + if (Buffer.isBuffer(value) && value.length) { // format input const encodedValue = Buffer.from(RLP.encode(Uint8Array.from(value))) if (this.DEBUG) { @@ -512,7 +510,11 @@ export class DefaultStateManager extends BaseStateManager implements StateManage */ async accountExists(address: Address): Promise { const account = this._cache.lookup(address) - if (account && isFalsy((account as any).virtual) && !this._cache.keyIsDeleted(address)) { + if ( + account && + ((account as any).virtual === undefined || (account as any).virtual === false) && + !this._cache.keyIsDeleted(address) + ) { return true } if (await this._trie.get(address.buf)) { From 0f900ed00c0078a2fe005f1db731dbc389fd68df Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:38:00 -0400 Subject: [PATCH 04/56] tx: remove isTruthy and isFalsy from tx --- packages/tx/src/baseTransaction.ts | 3 +-- packages/tx/test/base.spec.ts | 11 +++++------ packages/tx/test/index.ts | 13 ++++++------- packages/tx/test/transactionRunner.ts | 10 +++++----- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/packages/tx/src/baseTransaction.ts b/packages/tx/src/baseTransaction.ts index dd27f107c3..3a3bfd935c 100644 --- a/packages/tx/src/baseTransaction.ts +++ b/packages/tx/src/baseTransaction.ts @@ -7,7 +7,6 @@ import { bufferToBigInt, bufferToHex, ecsign, - isTruthy, publicToAddress, toBuffer, unpadBuffer, @@ -362,7 +361,7 @@ export abstract class BaseTransaction { */ protected _getCommon(common?: Common, chainId?: BigIntLike) { // Chain ID provided - if (isTruthy(chainId)) { + if (chainId !== undefined) { const chainIdBigInt = bufferToBigInt(toBuffer(chainId)) if (common) { if (common.chainId() !== chainIdBigInt) { diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index ebbdb81248..ed8a89e587 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -4,7 +4,6 @@ import { MAX_UINT64, SECP256K1_ORDER, bufferToBigInt, - isTruthy, privateToPublic, toBuffer, } from '@ethereumjs/util' @@ -277,7 +276,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { st.ok(tx.sign(Buffer.from(privateKey, 'hex')), `${txType.name}: should sign tx`) } @@ -319,7 +318,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey, sendersAddress } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) st.equal( signedTx.getSenderAddress().toString(), @@ -336,7 +335,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) const txPubKey = signedTx.getSenderPublicKey() const pubKeyFromPriv = privateToPublic(Buffer.from(privateKey, 'hex')) @@ -358,7 +357,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { let signedTx = tx.sign(Buffer.from(privateKey, 'hex')) signedTx = JSON.parse(JSON.stringify(signedTx)) // deep clone ;(signedTx as any).s = SECP256K1_ORDER + BigInt(1) @@ -376,7 +375,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) st.ok(signedTx.verifySignature(), `${txType.name}: should verify signing it`) } diff --git a/packages/tx/test/index.ts b/packages/tx/test/index.ts index e171eaa509..79080b05a4 100644 --- a/packages/tx/test/index.ts +++ b/packages/tx/test/index.ts @@ -1,20 +1,19 @@ -import { isTruthy } from '@ethereumjs/util' import * as minimist from 'minimist' const argv = minimist(process.argv.slice(2)) -if (isTruthy(argv.b)) { +if (argv.b === true) { require('./base.spec') -} else if (isTruthy(argv.l)) { +} else if (argv.l === true) { require('./legacy.spec') -} else if (isTruthy(argv.e)) { +} else if (argv.e === true) { require('./typedTxsAndEIP2930.spec') require('./eip1559.spec') -} else if (isTruthy(argv.t)) { +} else if (argv.t === true) { require('./transactionRunner') -} else if (isTruthy(argv.f)) { +} else if (argv.f === true) { require('./transactionFactory.spec') -} else if (isTruthy(argv.a)) { +} else if (argv.a === true) { // All manual API tests require('./base.spec') require('./legacy.spec') diff --git a/packages/tx/test/transactionRunner.ts b/packages/tx/test/transactionRunner.ts index bb309b08dd..c19bf9bf59 100644 --- a/packages/tx/test/transactionRunner.ts +++ b/packages/tx/test/transactionRunner.ts @@ -1,5 +1,5 @@ import { Common } from '@ethereumjs/common' -import { isTruthy, toBuffer } from '@ethereumjs/util' +import { toBuffer } from '@ethereumjs/util' import * as minimist from 'minimist' import * as tape from 'tape' @@ -40,12 +40,12 @@ const forkNameMap: ForkNamesMap = { Homestead: 'homestead', } -const EIPs: any = { +const EIPs: Record = { 'London+3860': [3860], } tape('TransactionTests', async (t) => { - const fileFilterRegex = isTruthy(file) ? new RegExp(file + '[^\\w]') : undefined + const fileFilterRegex = file !== undefined ? new RegExp(file + '[^\\w]') : undefined await getTests( ( _filename: string, @@ -59,14 +59,14 @@ tape('TransactionTests', async (t) => { continue } const forkTestData = testData.result[forkName] - const shouldBeInvalid = isTruthy(forkTestData.exception) + const shouldBeInvalid = forkTestData.exception !== undefined try { const rawTx = toBuffer(testData.txbytes) const hardfork = forkNameMap[forkName] const common = new Common({ chain: 1, hardfork }) const activateEIPs = EIPs[forkName] - if (isTruthy(activateEIPs)) { + if (activateEIPs !== undefined) { common.setEIPs(activateEIPs) } const tx = TransactionFactory.fromSerializedData(rawTx, { common }) From 109cf04ada0a1fee8a1fe215eafbe33ac55ee0b8 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:50:58 -0400 Subject: [PATCH 05/56] block: remove isTruthy and isFalsy from tx --- packages/block/src/block.ts | 8 ++++---- packages/block/src/header.ts | 14 ++++++-------- packages/block/src/helpers.ts | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 24647eea7b..8a7bce28d3 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -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' @@ -100,7 +100,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, @@ -120,10 +120,10 @@ export class Block { // Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value calcDifficultyFromHeader: undefined, } - if (isTruthy(uncleOpts.hardforkByTTD)) { + if (typeof uncleOpts.hardforkByTTD === 'bigint') { delete uncleOpts.hardforkByBlockNumber } - for (const uncleHeaderData of isTruthy(uhsData) ? uhsData : []) { + for (const uncleHeaderData of uhsData ?? []) { uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts)) } diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index e080564cb1..3fd725a645 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -14,8 +14,6 @@ import { bufferToHex, ecrecover, ecsign, - isFalsy, - isTruthy, toType, zeros, } from '@ethereumjs/util' @@ -206,9 +204,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 @@ -346,7 +344,7 @@ export class BlockHeader { throw new Error(msg) } const londonHfBlock = this._common.hardforkBlock(Hardfork.London) - if (isTruthy(londonHfBlock) && this.number === londonHfBlock) { + if (typeof londonHfBlock === 'bigint' && this.number === londonHfBlock) { const initialBaseFee = this._common.param('gasConfig', 'initialBaseFee') if (this.baseFeePerGas! !== initialBaseFee) { const msg = this._errorMsg('Initial EIP1559 block does not have initial base fee') @@ -450,7 +448,7 @@ 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' && this.number === londonHardforkBlock) { const elasticity = this._common.param('gasConfig', 'elasticityMultiplier') parentGasLimit = parentGasLimit * elasticity } @@ -820,7 +818,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') diff --git a/packages/block/src/helpers.ts b/packages/block/src/helpers.ts index ea3093055e..7b2393658a 100644 --- a/packages/block/src/helpers.ts +++ b/packages/block/src/helpers.ts @@ -1,11 +1,11 @@ -import { isFalsy, isHexString } from '@ethereumjs/util' +import { isHexString } from '@ethereumjs/util' /** * Returns a 0x-prefixed hex number string from a hex string or string integer. * @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)) { From ce5af34141278853e5ad59c3c880d5613ec8afe7 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:03:25 -0400 Subject: [PATCH 06/56] blockchain: remove isTruthy and isFalsy --- packages/blockchain/src/blockchain.ts | 22 +++++++++---------- packages/blockchain/src/db/manager.ts | 6 ++--- packages/blockchain/src/db/operation.ts | 4 +--- .../blockchain/src/genesisStates/index.ts | 8 +++---- packages/blockchain/test/util.ts | 4 ++-- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index 608a7444d2..6b7b329952 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -1,6 +1,5 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, ConsensusAlgorithm, ConsensusType, Hardfork } from '@ethereumjs/common' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import { CasperConsensus, CliqueConsensus, EthashConsensus } from './consensus' @@ -333,7 +332,7 @@ export class Blockchain implements BlockchainInterface { return await this.runWithLock(async () => { // if the head is not found return the headHeader const hash = this._heads[name] ?? this._headBlockHash - if (isFalsy(hash)) throw new Error('No head found.') + if (hash === undefined) throw new Error('No head found.') const block = await this._getBlock(hash) return block }) @@ -356,8 +355,7 @@ export class Blockchain implements BlockchainInterface { async getCanonicalHeadBlock(): Promise { return this.runWithLock(async () => { if (!this._headBlockHash) throw new Error('No head block set') - const block = this._getBlock(this._headBlockHash) - return block + return this._getBlock(this._headBlockHash) }) } @@ -548,7 +546,7 @@ export class Blockchain implements BlockchainInterface { return } const parentHeader = (await this.getBlock(header.parentHash)).header - if (isFalsy(parentHeader)) { + if (parentHeader === undefined) { throw new Error(`could not find parent header ${header.errorStr()}`) } @@ -573,7 +571,7 @@ export class Blockchain implements BlockchainInterface { header.validateGasLimit(parentHeader) - if (isTruthy(height)) { + if (height !== undefined) { const dif = height - parentHeader.number if (!(dif < BigInt(8) && dif > BigInt(1))) { @@ -654,7 +652,7 @@ export class Blockchain implements BlockchainInterface { let parentHash = block.header.parentHash for (let i = 0; i < getBlocks; i++) { const parentBlock = await this.getBlock(parentHash) - if (isFalsy(parentBlock)) { + if (parentBlock === undefined) { throw new Error(`could not find parent block ${block.errorStr()}`) } canonicalBlockMap.push(parentBlock) @@ -842,7 +840,7 @@ export class Blockchain implements BlockchainInterface { // check if block is in the canonical chain const canonicalHash = await this.safeNumberToHash(blockNumber) - const inCanonical = isTruthy(canonicalHash) && canonicalHash.equals(blockHash) + const inCanonical = canonicalHash !== false && canonicalHash.equals(blockHash) // delete the block, and if block is in the canonical chain, delete all // children as well @@ -926,7 +924,7 @@ export class Blockchain implements BlockchainInterface { return await this.runWithLock(async (): Promise => { const headHash = this._heads[name] ?? this.genesisBlock.hash() - if (isTruthy(maxBlocks) && maxBlocks < 0) { + if (typeof maxBlocks === 'number' && maxBlocks < 0) { throw 'If maxBlocks is provided, it has to be a non-negative number' } @@ -1030,7 +1028,7 @@ export class Blockchain implements BlockchainInterface { let hash: Buffer | false hash = await this.safeNumberToHash(blockNumber) - while (isTruthy(hash)) { + while (hash !== false) { ops.push(DBOp.del(DBTarget.NumberToHash, { blockNumber })) // reset stale iterator heads to current canonical head this can, for @@ -1084,7 +1082,7 @@ export class Blockchain implements BlockchainInterface { const loopCondition = async () => { staleHash = await this.safeNumberToHash(currentNumber) currentCanonicalHash = header.hash() - return isFalsy(staleHash) || !currentCanonicalHash.equals(staleHash) + return staleHash === false || !currentCanonicalHash.equals(staleHash) } while (await loopCondition()) { @@ -1164,7 +1162,7 @@ export class Blockchain implements BlockchainInterface { * @hidden */ private async _getHeader(hash: Buffer, number?: bigint) { - if (isFalsy(number)) { + if (number === undefined) { number = await this.dbManager.hashToNumber(hash) } return this.dbManager.getHeader(hash, number) diff --git a/packages/blockchain/src/db/manager.ts b/packages/blockchain/src/db/manager.ts index 1b1e65c6c0..48ab37de0b 100644 --- a/packages/blockchain/src/db/manager.ts +++ b/packages/blockchain/src/db/manager.ts @@ -1,6 +1,6 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { RLP } from '@ethereumjs/rlp' -import { arrToBufArr, bufferToBigInt, isFalsy, isTruthy } from '@ethereumjs/util' +import { arrToBufArr, bufferToBigInt } from '@ethereumjs/util' import { Cache } from './cache' import { DBOp, DBTarget } from './operation' @@ -186,8 +186,8 @@ export class DBManager { const dbKey = dbGetOperation.baseDBOp.key const dbOpts = dbGetOperation.baseDBOp - if (isTruthy(cacheString)) { - if (isFalsy(this._cache[cacheString])) { + if (cacheString !== undefined) { + if (this._cache[cacheString] === undefined) { throw new Error(`Invalid cache: ${cacheString}`) } diff --git a/packages/blockchain/src/db/operation.ts b/packages/blockchain/src/db/operation.ts index 14871b4ee5..53c70fef20 100644 --- a/packages/blockchain/src/db/operation.ts +++ b/packages/blockchain/src/db/operation.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { HEADS_KEY, HEAD_BLOCK_KEY, @@ -130,7 +128,7 @@ export class DBOp { } public updateCache(cacheMap: CacheMap) { - if (isTruthy(this.cacheString) && isTruthy(cacheMap[this.cacheString])) { + if (this.cacheString !== undefined && cacheMap[this.cacheString] !== undefined) { if (this.baseDBOp.type === 'put') { Buffer.isBuffer(this.baseDBOp.value) && cacheMap[this.cacheString].set(this.baseDBOp.key, this.baseDBOp.value) diff --git a/packages/blockchain/src/genesisStates/index.ts b/packages/blockchain/src/genesisStates/index.ts index 2e637899d7..9fb15880e7 100644 --- a/packages/blockchain/src/genesisStates/index.ts +++ b/packages/blockchain/src/genesisStates/index.ts @@ -1,6 +1,6 @@ import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { Account, isHexPrefixed, isTruthy, toBuffer, unpadBuffer } from '@ethereumjs/util' +import { Account, isHexPrefixed, toBuffer, unpadBuffer } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import type { PrefixedHexString } from '@ethereumjs/util' @@ -29,13 +29,13 @@ export async function genesisStateRoot(genesisState: GenesisState) { account.balance = BigInt(value) } else { const [balance, code, storage] = value as Partial - if (isTruthy(balance)) { + if (balance !== undefined) { account.balance = BigInt(balance) } - if (isTruthy(code)) { + if (code !== undefined) { account.codeHash = Buffer.from(keccak256(toBuffer(code))) } - if (isTruthy(storage)) { + if (storage !== undefined) { const storageTrie = new Trie() for (const [k, val] of storage) { const storageKey = isHexPrefixed(k) ? toBuffer(k) : Buffer.from(k, 'hex') diff --git a/packages/blockchain/test/util.ts b/packages/blockchain/test/util.ts index d096f5de7e..716e657e79 100644 --- a/packages/blockchain/test/util.ts +++ b/packages/blockchain/test/util.ts @@ -1,7 +1,7 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { bufArrToArr, isTruthy, toBuffer } from '@ethereumjs/util' +import { bufArrToArr, toBuffer } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import { MemoryLevel } from 'memory-level' @@ -212,7 +212,7 @@ function createBlock( const londonHfBlock = common.hardforkBlock(Hardfork.London) const baseFeePerGas = - isTruthy(londonHfBlock) && number > londonHfBlock + typeof londonHfBlock === 'bigint' && number > londonHfBlock ? parentBlock.header.calcNextBaseFee() : undefined From 95a686ea6906cbb0d9609a772340a55bd16ca28b Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Wed, 24 Aug 2022 22:31:50 -0400 Subject: [PATCH 07/56] vm: remove isTruthy and isFalsy --- packages/vm/src/bloom/index.ts | 8 +++----- packages/vm/src/buildBlock.ts | 9 +++++---- packages/vm/src/eei/vmState.ts | 10 +++++----- packages/vm/src/runBlock.ts | 14 +++----------- packages/vm/src/vm.ts | 4 ++-- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/packages/vm/src/bloom/index.ts b/packages/vm/src/bloom/index.ts index 0bdc5fd60c..78b8d529b8 100644 --- a/packages/vm/src/bloom/index.ts +++ b/packages/vm/src/bloom/index.ts @@ -1,4 +1,4 @@ -import { isTruthy, zeros } from '@ethereumjs/util' +import { zeros } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' const BYTE_SIZE = 256 @@ -67,10 +67,8 @@ export class Bloom { * Bitwise or blooms together. */ or(bloom: Bloom) { - if (isTruthy(bloom)) { - for (let i = 0; i <= BYTE_SIZE; i++) { - this.bitvector[i] = this.bitvector[i] | bloom.bitvector[i] - } + for (let i = 0; i <= BYTE_SIZE; i++) { + this.bitvector[i] = this.bitvector[i] | bloom.bitvector[i] } } } diff --git a/packages/vm/src/buildBlock.ts b/packages/vm/src/buildBlock.ts index 0249657ce5..612c7f3054 100644 --- a/packages/vm/src/buildBlock.ts +++ b/packages/vm/src/buildBlock.ts @@ -2,7 +2,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { Address, TypeOutput, isTruthy, toBuffer, toType } from '@ethereumjs/util' +import { Address, TypeOutput, toBuffer, toType } from '@ethereumjs/util' import { Bloom } from './bloom' import { calculateMinerReward, encodeReceipt, rewardAccount } from './runBlock' @@ -104,9 +104,10 @@ export class BlockBuilder { private async rewardMiner() { const minerReward = this.vm._common.param('pow', 'minerReward') const reward = calculateMinerReward(minerReward, 0) - const coinbase = isTruthy(this.headerData.coinbase) - ? new Address(toBuffer(this.headerData.coinbase)) - : Address.zero() + const coinbase = + this.headerData.coinbase !== undefined + ? new Address(toBuffer(this.headerData.coinbase)) + : Address.zero() await rewardAccount(this.vm.eei, coinbase, reward) } diff --git a/packages/vm/src/eei/vmState.ts b/packages/vm/src/eei/vmState.ts index bdf14f4fba..3837a5fef6 100644 --- a/packages/vm/src/eei/vmState.ts +++ b/packages/vm/src/eei/vmState.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { ripemdPrecompileAddress } from '@ethereumjs/evm/dist/precompiles' -import { Account, Address, isTruthy, toBuffer } from '@ethereumjs/util' +import { Account, Address, toBuffer } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import type { EVMStateAccess } from '@ethereumjs/evm/dist/types' @@ -210,12 +210,12 @@ export class VmState implements EVMStateAccess { * Merges a storage map into the last item of the accessed storage stack */ private _accessedStorageMerge( - storageList: Map>[], + storageList: Map | undefined>[], storageMap: Map> ) { const mapTarget = storageList[storageList.length - 1] - if (isTruthy(mapTarget)) { + if (mapTarget !== undefined) { // Note: storageMap is always defined here per definition (TypeScript cannot infer this) for (const [addressString, slotSet] of storageMap) { const addressExists = mapTarget.get(addressString) @@ -255,10 +255,10 @@ export class VmState implements EVMStateAccess { const [balance, code, storage] = state const account = Account.fromAccountData({ balance }) await this.putAccount(addr, account) - if (isTruthy(code)) { + if (code !== undefined) { await this.putContractCode(addr, toBuffer(code)) } - if (isTruthy(storage)) { + if (storage !== undefined) { for (const [key, value] of storage) { await this.putContractStorage(addr, toBuffer(key), toBuffer(value)) } diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index db9cc40487..2e36a3d252 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -2,15 +2,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { - Account, - Address, - bigIntToBuffer, - bufArrToArr, - intToBuffer, - isTruthy, - short, -} from '@ethereumjs/util' +import { Account, Address, bigIntToBuffer, bufArrToArr, intToBuffer, short } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { Bloom } from './bloom' @@ -53,8 +45,8 @@ export async function runBlock(this: VM, opts: RunBlockOpts): Promise { common: (eeiCopy as any)._common, evm: evmCopy, hardforkByBlockNumber: this._hardforkByBlockNumber ? true : undefined, - hardforkByTTD: isTruthy(this._hardforkByTTD) ? this._hardforkByTTD : undefined, + hardforkByTTD: this._hardforkByTTD, }) } From ce9ead1a90accef5230a1507ebc6d4fbfd0cd375 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:06:12 -0400 Subject: [PATCH 08/56] vm: remove additional isTruthy/isFalsy from vm --- packages/vm/src/runTx.ts | 4 +-- .../tests/api/EIPs/eip-3074-authcall.spec.ts | 34 ++++--------------- .../vm/tests/api/istanbul/eip-1884.spec.ts | 4 +-- packages/vm/tests/util.ts | 18 ++++------ 4 files changed, 18 insertions(+), 42 deletions(-) diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 5333581099..3fbbb638cd 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -1,7 +1,7 @@ import { Block } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { Capability } from '@ethereumjs/tx' -import { Address, KECCAK256_NULL, isFalsy, short, toBuffer } from '@ethereumjs/util' +import { Address, KECCAK256_NULL, short, toBuffer } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { Bloom } from './bloom' @@ -31,7 +31,7 @@ const debugGas = createDebugLogger('vm:tx:gas') */ export async function runTx(this: VM, opts: RunTxOpts): Promise { // tx is required - if (isFalsy(opts.tx)) { + if (opts.tx === undefined) { throw new Error('invalid input, tx is required') } diff --git a/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts b/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts index 478e484545..debbe651d2 100644 --- a/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts +++ b/packages/vm/tests/api/EIPs/eip-3074-authcall.spec.ts @@ -7,7 +7,6 @@ import { bigIntToBuffer, bufferToBigInt, ecsign, - isTruthy, privateToAddress, setLengthLeft, toBuffer, @@ -171,33 +170,14 @@ function MSTORE(position: Buffer, value: Buffer) { * @returns - The bytecode to execute AUTHCALL */ function getAuthCallCode(data: AuthcallData) { - const ZEROS32 = zeros(32) - const gasLimitBuffer = setLengthLeft( - isTruthy(data.gasLimit) ? bigIntToBuffer(data.gasLimit) : ZEROS32, - 32 - ) + const gasLimitBuffer = setLengthLeft(bigIntToBuffer(data.gasLimit ?? 0n), 32) const addressBuffer = setLengthLeft(data.address.buf, 32) - const valueBuffer = setLengthLeft(isTruthy(data.value) ? bigIntToBuffer(data.value) : ZEROS32, 32) - const valueExtBuffer = setLengthLeft( - isTruthy(data.valueExt) ? bigIntToBuffer(data.valueExt) : ZEROS32, - 32 - ) - const argsOffsetBuffer = setLengthLeft( - isTruthy(data.argsOffset) ? bigIntToBuffer(data.argsOffset) : ZEROS32, - 32 - ) - const argsLengthBuffer = setLengthLeft( - isTruthy(data.argsLength) ? bigIntToBuffer(data.argsLength) : ZEROS32, - 32 - ) - const retOffsetBuffer = setLengthLeft( - isTruthy(data.retOffset) ? bigIntToBuffer(data.retOffset) : ZEROS32, - 32 - ) - const retLengthBuffer = setLengthLeft( - isTruthy(data.retLength) ? bigIntToBuffer(data.retLength) : ZEROS32, - 32 - ) + const valueBuffer = setLengthLeft(bigIntToBuffer(data.value ?? 0n), 32) + const valueExtBuffer = setLengthLeft(bigIntToBuffer(data.valueExt ?? 0n), 32) + const argsOffsetBuffer = setLengthLeft(bigIntToBuffer(data.argsOffset ?? 0n), 32) + const argsLengthBuffer = setLengthLeft(bigIntToBuffer(data.argsLength ?? 0n), 32) + const retOffsetBuffer = setLengthLeft(bigIntToBuffer(data.retOffset ?? 0n), 32) + const retLengthBuffer = setLengthLeft(bigIntToBuffer(data.retLength ?? 0n), 32) const PUSH32 = Buffer.from('7f', 'hex') const AUTHCALL = Buffer.from('f7', 'hex') const order = [ diff --git a/packages/vm/tests/api/istanbul/eip-1884.spec.ts b/packages/vm/tests/api/istanbul/eip-1884.spec.ts index 2d836e79c7..c0d2e7f296 100644 --- a/packages/vm/tests/api/istanbul/eip-1884.spec.ts +++ b/packages/vm/tests/api/istanbul/eip-1884.spec.ts @@ -1,6 +1,6 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { ERROR } from '@ethereumjs/evm/dist/exceptions' -import { Address, bufferToBigInt, isTruthy } from '@ethereumjs/util' +import { Address, bufferToBigInt } from '@ethereumjs/util' import * as tape from 'tape' import { VM } from '../../../src/vm' @@ -27,7 +27,7 @@ tape('Istanbul: EIP-1884', async (t) => { const common = new Common({ chain, hardfork }) const vm = await VM.create({ common }) - const balance = isTruthy(testCase.selfbalance) ? BigInt(testCase.selfbalance) : undefined + const balance = testCase.selfbalance !== undefined ? BigInt(testCase.selfbalance) : undefined const account = createAccount(BigInt(0), balance) await vm.stateManager.putAccount(addr, account) diff --git a/packages/vm/tests/util.ts b/packages/vm/tests/util.ts index c1f523cb53..5effb04bed 100644 --- a/packages/vm/tests/util.ts +++ b/packages/vm/tests/util.ts @@ -12,9 +12,7 @@ import { bigIntToBuffer, bufferToBigInt, bufferToHex, - isFalsy, isHexPrefixed, - isTruthy, setLengthLeft, stripHexPrefix, toBuffer, @@ -118,15 +116,15 @@ export function makeTx( opts?: TxOptions ): FeeMarketEIP1559Transaction | AccessListEIP2930Transaction | Transaction { let tx - if (isTruthy(txData.maxFeePerGas)) { + if (txData.maxFeePerGas !== undefined) { tx = FeeMarketEIP1559Transaction.fromTxData(txData, opts) - } else if (isTruthy(txData.accessLists)) { + } else if (txData.accessLists !== undefined) { tx = AccessListEIP2930Transaction.fromTxData(txData, opts) } else { tx = Transaction.fromTxData(txData, opts) } - if (isTruthy(txData.secretKey)) { + if (txData.secretKey !== undefined) { const privKey = toBuffer(txData.secretKey) return tx.sign(privKey) } @@ -157,7 +155,7 @@ export async function verifyPostConditions(state: any, testData: any, t: tape.Te const address = keyMap[key] delete keyMap[key] - if (isTruthy(testData)) { + if (testData !== undefined) { const promise = verifyAccountPostConditions(state, address, account, testData, t) queue.push(promise) } else { @@ -223,9 +221,7 @@ export function verifyAccountPostConditions( if (key === '0x') { key = '0x00' - acctData.storage['0x00'] = isTruthy(acctData.storage['0x00']) - ? acctData.storage['0x00'] - : acctData.storage['0x'] + acctData.storage['0x00'] = acctData.storage['0x00'] ?? acctData.storage['0x'] delete acctData.storage['0x'] } @@ -259,9 +255,9 @@ export function verifyAccountPostConditions( */ export function verifyGas(results: any, testData: any, t: tape.Test) { const coinbaseAddr = testData.env.currentCoinbase - const preBal = isTruthy(testData.pre[coinbaseAddr]) ? testData.pre[coinbaseAddr].balance : 0 + const preBal = testData.pre[coinbaseAddr] !== undefined ? testData.pre[coinbaseAddr].balance : 0 - if (isFalsy(testData.post[coinbaseAddr])) { + if (testData.post[coinbaseAddr] === undefined) { return } From 9514ce71e06663e9b8a61776e994f03f44bbbc3c Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:29:09 -0400 Subject: [PATCH 09/56] statemanager: remove isFalsy and isTruthy --- packages/statemanager/src/cache.ts | 39 +++++++++++------------ packages/statemanager/src/stateManager.ts | 12 ++++--- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/packages/statemanager/src/cache.ts b/packages/statemanager/src/cache.ts index 4005104e14..3633f82f28 100644 --- a/packages/statemanager/src/cache.ts +++ b/packages/statemanager/src/cache.ts @@ -1,4 +1,4 @@ -import { Account, isFalsy, isTruthy } from '@ethereumjs/util' +import { Account } from '@ethereumjs/util' import type { Address } from '@ethereumjs/util' @@ -60,7 +60,7 @@ export class Cache { const keyStr = key.buf.toString('hex') const it = this._cache.find(keyStr) - if (isTruthy(it.node)) { + if (it.node !== null) { const rlp = it.value.val const account = Account.fromRlpSerializedAccount(rlp) ;(account as any).virtual = it.value.virtual @@ -75,7 +75,7 @@ export class Cache { keyIsDeleted(key: Address): boolean { const keyStr = key.buf.toString('hex') const it = this._cache.find(keyStr) - if (isTruthy(it.node)) { + if (it.node !== null) { return it.value.deleted } return false @@ -111,26 +111,23 @@ export class Cache { const it = this._cache.begin let next = true while (next) { - if (isTruthy(it.value) && isTruthy(it.value.modified) && isFalsy(it.value.deleted)) { + if (it.value !== undefined && it.value.modified === true) { it.value.modified = false - const accountRlp = it.value.val const keyBuf = Buffer.from(it.key, 'hex') - await this._putCb(keyBuf, accountRlp) - next = it.hasNext - it.next() - } else if (isTruthy(it.value) && isTruthy(it.value.modified) && isTruthy(it.value.deleted)) { - it.value.modified = false - it.value.deleted = true - it.value.virtual = true - it.value.val = new Account().serialize() - const keyBuf = Buffer.from(it.key, 'hex') - await this._deleteCb(keyBuf) - next = it.hasNext - it.next() - } else { - next = it.hasNext - it.next() + if (it.value.deleted === false) { + const accountRlp = it.value.val + await this._putCb(keyBuf, accountRlp) + } else { + it.value.modified = false + it.value.deleted = true + it.value.virtual = true + it.value.val = new Account().serialize() + await this._deleteCb(keyBuf) + } } + + next = it.hasNext + it.next() } } @@ -190,7 +187,7 @@ export class Cache { const keyHex = key.buf.toString('hex') const it = this._cache.find(keyHex) const val = value.serialize() - if (isTruthy(it.node)) { + if (it.node !== null) { this._cache = it.update({ val, modified, deleted, virtual }) } else { this._cache = this._cache.insert(keyHex, { val, modified, deleted, virtual }) diff --git a/packages/statemanager/src/stateManager.ts b/packages/statemanager/src/stateManager.ts index 93e5f3670a..aafab81fa3 100644 --- a/packages/statemanager/src/stateManager.ts +++ b/packages/statemanager/src/stateManager.ts @@ -6,8 +6,6 @@ import { KECCAK256_RLP, bigIntToHex, bufferToHex, - isFalsy, - isTruthy, setLengthLeft, short, toBuffer, @@ -189,7 +187,7 @@ export class DefaultStateManager extends BaseStateManager implements StateManage // from storage cache const addressHex = address.buf.toString('hex') let storageTrie = this._storageTries[addressHex] - if (isFalsy(storageTrie)) { + if (storageTrie === undefined || storageTrie === null) { // lookup from state storageTrie = await this._lookupStorageTrie(address) } @@ -264,7 +262,7 @@ export class DefaultStateManager extends BaseStateManager implements StateManage value = unpadBuffer(value) await this._modifyContractStorage(address, async (storageTrie, done) => { - if (isTruthy(value) && value.length) { + if (Buffer.isBuffer(value) && value.length) { // format input const encodedValue = Buffer.from(RLP.encode(Uint8Array.from(value))) if (this.DEBUG) { @@ -512,7 +510,11 @@ export class DefaultStateManager extends BaseStateManager implements StateManage */ async accountExists(address: Address): Promise { const account = this._cache.lookup(address) - if (account && isFalsy((account as any).virtual) && !this._cache.keyIsDeleted(address)) { + if ( + account && + ((account as any).virtual === undefined || (account as any).virtual === false) && + !this._cache.keyIsDeleted(address) + ) { return true } if (await this._trie.get(address.buf)) { From c26d6d68e4b2a88c1d390a85ae59c04fbe34094f Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:38:00 -0400 Subject: [PATCH 10/56] tx: remove isTruthy and isFalsy from tx --- packages/tx/src/baseTransaction.ts | 3 +-- packages/tx/test/base.spec.ts | 11 +++++------ packages/tx/test/index.ts | 13 ++++++------- packages/tx/test/transactionRunner.ts | 10 +++++----- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/packages/tx/src/baseTransaction.ts b/packages/tx/src/baseTransaction.ts index dd27f107c3..3a3bfd935c 100644 --- a/packages/tx/src/baseTransaction.ts +++ b/packages/tx/src/baseTransaction.ts @@ -7,7 +7,6 @@ import { bufferToBigInt, bufferToHex, ecsign, - isTruthy, publicToAddress, toBuffer, unpadBuffer, @@ -362,7 +361,7 @@ export abstract class BaseTransaction { */ protected _getCommon(common?: Common, chainId?: BigIntLike) { // Chain ID provided - if (isTruthy(chainId)) { + if (chainId !== undefined) { const chainIdBigInt = bufferToBigInt(toBuffer(chainId)) if (common) { if (common.chainId() !== chainIdBigInt) { diff --git a/packages/tx/test/base.spec.ts b/packages/tx/test/base.spec.ts index ebbdb81248..ed8a89e587 100644 --- a/packages/tx/test/base.spec.ts +++ b/packages/tx/test/base.spec.ts @@ -4,7 +4,6 @@ import { MAX_UINT64, SECP256K1_ORDER, bufferToBigInt, - isTruthy, privateToPublic, toBuffer, } from '@ethereumjs/util' @@ -277,7 +276,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { st.ok(tx.sign(Buffer.from(privateKey, 'hex')), `${txType.name}: should sign tx`) } @@ -319,7 +318,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey, sendersAddress } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) st.equal( signedTx.getSenderAddress().toString(), @@ -336,7 +335,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) const txPubKey = signedTx.getSenderPublicKey() const pubKeyFromPriv = privateToPublic(Buffer.from(privateKey, 'hex')) @@ -358,7 +357,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { let signedTx = tx.sign(Buffer.from(privateKey, 'hex')) signedTx = JSON.parse(JSON.stringify(signedTx)) // deep clone ;(signedTx as any).s = SECP256K1_ORDER + BigInt(1) @@ -376,7 +375,7 @@ tape('[BaseTransaction]', function (t) { for (const txType of txTypes) { for (const [i, tx] of txType.txs.entries()) { const { privateKey } = txType.fixtures[i] - if (isTruthy(privateKey)) { + if (privateKey !== undefined) { const signedTx = tx.sign(Buffer.from(privateKey, 'hex')) st.ok(signedTx.verifySignature(), `${txType.name}: should verify signing it`) } diff --git a/packages/tx/test/index.ts b/packages/tx/test/index.ts index e171eaa509..79080b05a4 100644 --- a/packages/tx/test/index.ts +++ b/packages/tx/test/index.ts @@ -1,20 +1,19 @@ -import { isTruthy } from '@ethereumjs/util' import * as minimist from 'minimist' const argv = minimist(process.argv.slice(2)) -if (isTruthy(argv.b)) { +if (argv.b === true) { require('./base.spec') -} else if (isTruthy(argv.l)) { +} else if (argv.l === true) { require('./legacy.spec') -} else if (isTruthy(argv.e)) { +} else if (argv.e === true) { require('./typedTxsAndEIP2930.spec') require('./eip1559.spec') -} else if (isTruthy(argv.t)) { +} else if (argv.t === true) { require('./transactionRunner') -} else if (isTruthy(argv.f)) { +} else if (argv.f === true) { require('./transactionFactory.spec') -} else if (isTruthy(argv.a)) { +} else if (argv.a === true) { // All manual API tests require('./base.spec') require('./legacy.spec') diff --git a/packages/tx/test/transactionRunner.ts b/packages/tx/test/transactionRunner.ts index bb309b08dd..c19bf9bf59 100644 --- a/packages/tx/test/transactionRunner.ts +++ b/packages/tx/test/transactionRunner.ts @@ -1,5 +1,5 @@ import { Common } from '@ethereumjs/common' -import { isTruthy, toBuffer } from '@ethereumjs/util' +import { toBuffer } from '@ethereumjs/util' import * as minimist from 'minimist' import * as tape from 'tape' @@ -40,12 +40,12 @@ const forkNameMap: ForkNamesMap = { Homestead: 'homestead', } -const EIPs: any = { +const EIPs: Record = { 'London+3860': [3860], } tape('TransactionTests', async (t) => { - const fileFilterRegex = isTruthy(file) ? new RegExp(file + '[^\\w]') : undefined + const fileFilterRegex = file !== undefined ? new RegExp(file + '[^\\w]') : undefined await getTests( ( _filename: string, @@ -59,14 +59,14 @@ tape('TransactionTests', async (t) => { continue } const forkTestData = testData.result[forkName] - const shouldBeInvalid = isTruthy(forkTestData.exception) + const shouldBeInvalid = forkTestData.exception !== undefined try { const rawTx = toBuffer(testData.txbytes) const hardfork = forkNameMap[forkName] const common = new Common({ chain: 1, hardfork }) const activateEIPs = EIPs[forkName] - if (isTruthy(activateEIPs)) { + if (activateEIPs !== undefined) { common.setEIPs(activateEIPs) } const tx = TransactionFactory.fromSerializedData(rawTx, { common }) From 484ba8c8b96eafd65fcb59602d9261c47703e7e6 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 01:50:58 -0400 Subject: [PATCH 11/56] block: remove isTruthy and isFalsy from tx --- packages/block/src/block.ts | 8 ++++---- packages/block/src/header.ts | 14 ++++++-------- packages/block/src/helpers.ts | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/block/src/block.ts b/packages/block/src/block.ts index 24647eea7b..8a7bce28d3 100644 --- a/packages/block/src/block.ts +++ b/packages/block/src/block.ts @@ -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' @@ -100,7 +100,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, @@ -120,10 +120,10 @@ export class Block { // Disable this option here (all other options carried over), since this overwrites the provided Difficulty to an incorrect value calcDifficultyFromHeader: undefined, } - if (isTruthy(uncleOpts.hardforkByTTD)) { + if (typeof uncleOpts.hardforkByTTD === 'bigint') { delete uncleOpts.hardforkByBlockNumber } - for (const uncleHeaderData of isTruthy(uhsData) ? uhsData : []) { + for (const uncleHeaderData of uhsData ?? []) { uncleHeaders.push(BlockHeader.fromValuesArray(uncleHeaderData, uncleOpts)) } diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index e080564cb1..3fd725a645 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -14,8 +14,6 @@ import { bufferToHex, ecrecover, ecsign, - isFalsy, - isTruthy, toType, zeros, } from '@ethereumjs/util' @@ -206,9 +204,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 @@ -346,7 +344,7 @@ export class BlockHeader { throw new Error(msg) } const londonHfBlock = this._common.hardforkBlock(Hardfork.London) - if (isTruthy(londonHfBlock) && this.number === londonHfBlock) { + if (typeof londonHfBlock === 'bigint' && this.number === londonHfBlock) { const initialBaseFee = this._common.param('gasConfig', 'initialBaseFee') if (this.baseFeePerGas! !== initialBaseFee) { const msg = this._errorMsg('Initial EIP1559 block does not have initial base fee') @@ -450,7 +448,7 @@ 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' && this.number === londonHardforkBlock) { const elasticity = this._common.param('gasConfig', 'elasticityMultiplier') parentGasLimit = parentGasLimit * elasticity } @@ -820,7 +818,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') diff --git a/packages/block/src/helpers.ts b/packages/block/src/helpers.ts index ea3093055e..7b2393658a 100644 --- a/packages/block/src/helpers.ts +++ b/packages/block/src/helpers.ts @@ -1,11 +1,11 @@ -import { isFalsy, isHexString } from '@ethereumjs/util' +import { isHexString } from '@ethereumjs/util' /** * Returns a 0x-prefixed hex number string from a hex string or string integer. * @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)) { From f4b4e1fef0cb4af7c9fe0d17b5b0dbdf47b10aeb Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:03:25 -0400 Subject: [PATCH 12/56] blockchain: remove isTruthy and isFalsy --- packages/blockchain/src/blockchain.ts | 22 +++++++++---------- packages/blockchain/src/db/manager.ts | 6 ++--- packages/blockchain/src/db/operation.ts | 4 +--- .../blockchain/src/genesisStates/index.ts | 8 +++---- packages/blockchain/test/util.ts | 4 ++-- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index 608a7444d2..6b7b329952 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -1,6 +1,5 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, ConsensusAlgorithm, ConsensusType, Hardfork } from '@ethereumjs/common' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import { CasperConsensus, CliqueConsensus, EthashConsensus } from './consensus' @@ -333,7 +332,7 @@ export class Blockchain implements BlockchainInterface { return await this.runWithLock(async () => { // if the head is not found return the headHeader const hash = this._heads[name] ?? this._headBlockHash - if (isFalsy(hash)) throw new Error('No head found.') + if (hash === undefined) throw new Error('No head found.') const block = await this._getBlock(hash) return block }) @@ -356,8 +355,7 @@ export class Blockchain implements BlockchainInterface { async getCanonicalHeadBlock(): Promise { return this.runWithLock(async () => { if (!this._headBlockHash) throw new Error('No head block set') - const block = this._getBlock(this._headBlockHash) - return block + return this._getBlock(this._headBlockHash) }) } @@ -548,7 +546,7 @@ export class Blockchain implements BlockchainInterface { return } const parentHeader = (await this.getBlock(header.parentHash)).header - if (isFalsy(parentHeader)) { + if (parentHeader === undefined) { throw new Error(`could not find parent header ${header.errorStr()}`) } @@ -573,7 +571,7 @@ export class Blockchain implements BlockchainInterface { header.validateGasLimit(parentHeader) - if (isTruthy(height)) { + if (height !== undefined) { const dif = height - parentHeader.number if (!(dif < BigInt(8) && dif > BigInt(1))) { @@ -654,7 +652,7 @@ export class Blockchain implements BlockchainInterface { let parentHash = block.header.parentHash for (let i = 0; i < getBlocks; i++) { const parentBlock = await this.getBlock(parentHash) - if (isFalsy(parentBlock)) { + if (parentBlock === undefined) { throw new Error(`could not find parent block ${block.errorStr()}`) } canonicalBlockMap.push(parentBlock) @@ -842,7 +840,7 @@ export class Blockchain implements BlockchainInterface { // check if block is in the canonical chain const canonicalHash = await this.safeNumberToHash(blockNumber) - const inCanonical = isTruthy(canonicalHash) && canonicalHash.equals(blockHash) + const inCanonical = canonicalHash !== false && canonicalHash.equals(blockHash) // delete the block, and if block is in the canonical chain, delete all // children as well @@ -926,7 +924,7 @@ export class Blockchain implements BlockchainInterface { return await this.runWithLock(async (): Promise => { const headHash = this._heads[name] ?? this.genesisBlock.hash() - if (isTruthy(maxBlocks) && maxBlocks < 0) { + if (typeof maxBlocks === 'number' && maxBlocks < 0) { throw 'If maxBlocks is provided, it has to be a non-negative number' } @@ -1030,7 +1028,7 @@ export class Blockchain implements BlockchainInterface { let hash: Buffer | false hash = await this.safeNumberToHash(blockNumber) - while (isTruthy(hash)) { + while (hash !== false) { ops.push(DBOp.del(DBTarget.NumberToHash, { blockNumber })) // reset stale iterator heads to current canonical head this can, for @@ -1084,7 +1082,7 @@ export class Blockchain implements BlockchainInterface { const loopCondition = async () => { staleHash = await this.safeNumberToHash(currentNumber) currentCanonicalHash = header.hash() - return isFalsy(staleHash) || !currentCanonicalHash.equals(staleHash) + return staleHash === false || !currentCanonicalHash.equals(staleHash) } while (await loopCondition()) { @@ -1164,7 +1162,7 @@ export class Blockchain implements BlockchainInterface { * @hidden */ private async _getHeader(hash: Buffer, number?: bigint) { - if (isFalsy(number)) { + if (number === undefined) { number = await this.dbManager.hashToNumber(hash) } return this.dbManager.getHeader(hash, number) diff --git a/packages/blockchain/src/db/manager.ts b/packages/blockchain/src/db/manager.ts index 1b1e65c6c0..48ab37de0b 100644 --- a/packages/blockchain/src/db/manager.ts +++ b/packages/blockchain/src/db/manager.ts @@ -1,6 +1,6 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { RLP } from '@ethereumjs/rlp' -import { arrToBufArr, bufferToBigInt, isFalsy, isTruthy } from '@ethereumjs/util' +import { arrToBufArr, bufferToBigInt } from '@ethereumjs/util' import { Cache } from './cache' import { DBOp, DBTarget } from './operation' @@ -186,8 +186,8 @@ export class DBManager { const dbKey = dbGetOperation.baseDBOp.key const dbOpts = dbGetOperation.baseDBOp - if (isTruthy(cacheString)) { - if (isFalsy(this._cache[cacheString])) { + if (cacheString !== undefined) { + if (this._cache[cacheString] === undefined) { throw new Error(`Invalid cache: ${cacheString}`) } diff --git a/packages/blockchain/src/db/operation.ts b/packages/blockchain/src/db/operation.ts index 14871b4ee5..53c70fef20 100644 --- a/packages/blockchain/src/db/operation.ts +++ b/packages/blockchain/src/db/operation.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { HEADS_KEY, HEAD_BLOCK_KEY, @@ -130,7 +128,7 @@ export class DBOp { } public updateCache(cacheMap: CacheMap) { - if (isTruthy(this.cacheString) && isTruthy(cacheMap[this.cacheString])) { + if (this.cacheString !== undefined && cacheMap[this.cacheString] !== undefined) { if (this.baseDBOp.type === 'put') { Buffer.isBuffer(this.baseDBOp.value) && cacheMap[this.cacheString].set(this.baseDBOp.key, this.baseDBOp.value) diff --git a/packages/blockchain/src/genesisStates/index.ts b/packages/blockchain/src/genesisStates/index.ts index 2e637899d7..9fb15880e7 100644 --- a/packages/blockchain/src/genesisStates/index.ts +++ b/packages/blockchain/src/genesisStates/index.ts @@ -1,6 +1,6 @@ import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' -import { Account, isHexPrefixed, isTruthy, toBuffer, unpadBuffer } from '@ethereumjs/util' +import { Account, isHexPrefixed, toBuffer, unpadBuffer } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import type { PrefixedHexString } from '@ethereumjs/util' @@ -29,13 +29,13 @@ export async function genesisStateRoot(genesisState: GenesisState) { account.balance = BigInt(value) } else { const [balance, code, storage] = value as Partial - if (isTruthy(balance)) { + if (balance !== undefined) { account.balance = BigInt(balance) } - if (isTruthy(code)) { + if (code !== undefined) { account.codeHash = Buffer.from(keccak256(toBuffer(code))) } - if (isTruthy(storage)) { + if (storage !== undefined) { const storageTrie = new Trie() for (const [k, val] of storage) { const storageKey = isHexPrefixed(k) ? toBuffer(k) : Buffer.from(k, 'hex') diff --git a/packages/blockchain/test/util.ts b/packages/blockchain/test/util.ts index d096f5de7e..716e657e79 100644 --- a/packages/blockchain/test/util.ts +++ b/packages/blockchain/test/util.ts @@ -1,7 +1,7 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' -import { bufArrToArr, isTruthy, toBuffer } from '@ethereumjs/util' +import { bufArrToArr, toBuffer } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import { MemoryLevel } from 'memory-level' @@ -212,7 +212,7 @@ function createBlock( const londonHfBlock = common.hardforkBlock(Hardfork.London) const baseFeePerGas = - isTruthy(londonHfBlock) && number > londonHfBlock + typeof londonHfBlock === 'bigint' && number > londonHfBlock ? parentBlock.header.calcNextBaseFee() : undefined From bb15cffe2c44650d2fbe829c51b892dd3791c1e1 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:23:39 -0400 Subject: [PATCH 13/56] trie: remove isTruthy and isFalsy --- packages/trie/src/trie/trie.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/trie/src/trie/trie.ts b/packages/trie/src/trie/trie.ts index aff90e3887..6419f4360a 100644 --- a/packages/trie/src/trie/trie.ts +++ b/packages/trie/src/trie/trie.ts @@ -97,9 +97,9 @@ export class Trie { /** * Gets and/or Sets the current root of the `trie` */ - root(value?: Buffer): Buffer { + root(value?: Buffer | null): Buffer { if (value !== undefined) { - if (isFalsy(value)) { + if (value === null) { value = this.EMPTY_TRIE_ROOT } @@ -137,7 +137,7 @@ export class Trie { */ async get(key: Buffer, throwIfMissing = false): Promise { const { node, remaining } = await this.findPath(this.appliedKey(key), throwIfMissing) - let value = null + let value: Buffer | null = null if (node && remaining.length === 0) { value = node.value() } @@ -157,7 +157,7 @@ export class Trie { } // If value is empty, delete - if (isFalsy(value) || value.toString() === '') { + if (value === null || value.length === 0) { return await this.del(key) } @@ -426,9 +426,9 @@ export class Trie { stack: TrieNode[] ) => { // branchNode is the node ON the branch node not THE branch node - if (isFalsy(parentNode) || parentNode instanceof BranchNode) { + if (parentNode === null || parentNode === undefined || parentNode instanceof BranchNode) { // branch->? - if (isTruthy(parentNode)) { + if (parentNode !== null && parentNode !== undefined) { stack.push(parentNode) } @@ -460,9 +460,9 @@ export class Trie { stack.push(parentNode) } else { const branchNodeKey = branchNode.key() - // branch node is an leaf or extension and parent node is an exstention + // branch node is an leaf or extension and parent node is an extension // add two keys together - // dont push the parent node + // don't push the parent node branchNodeKey.unshift(branchKey) key = key.concat(branchNodeKey) parentKey = parentKey.concat(branchNodeKey) @@ -475,8 +475,8 @@ export class Trie { return key } - let lastNode = stack.pop() as TrieNode - if (isFalsy(lastNode)) throw new Error('missing last node') + let lastNode = stack.pop() + if (lastNode === undefined) throw new Error('missing last node') let parentNode = stack.pop() const opStack: BatchDBOp[] = [] @@ -634,6 +634,7 @@ export class Trie { for (const op of ops) { if (op.type === 'put') { if (isFalsy(op.value)) { + console.log('falsy op value', op.value) throw new Error('Invalid batch db operation') } await this.put(op.key, op.value) From a3825e57043cb96593a6d9093f65e26f7f55460f Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:37:30 -0400 Subject: [PATCH 14/56] block: fix londonHfBlock check --- packages/block/src/header.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index 3fd725a645..88c4b1571c 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -344,9 +344,13 @@ export class BlockHeader { throw new Error(msg) } const londonHfBlock = this._common.hardforkBlock(Hardfork.London) - if (typeof londonHfBlock === 'bigint' && this.number === londonHfBlock) { + if ( + typeof londonHfBlock === 'bigint' && + londonHfBlock !== 0n && + 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) } From 38245ba9adfeb67048fe7c3ad41bd2910d4747f8 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:47:12 -0400 Subject: [PATCH 15/56] chore: replace -n with BigInt(0) for consistency --- packages/block/src/header.ts | 2 +- packages/evm/src/opcodes/gas.ts | 2 +- .../vm/tests/api/EIPs/eip-3074-authcall.spec.ts | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index 88c4b1571c..aa3572119b 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -346,7 +346,7 @@ export class BlockHeader { const londonHfBlock = this._common.hardforkBlock(Hardfork.London) if ( typeof londonHfBlock === 'bigint' && - londonHfBlock !== 0n && + londonHfBlock !== BigInt(0) && this.number === londonHfBlock ) { const initialBaseFee = this._common.param('gasConfig', 'initialBaseFee') diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index 6dcf57a346..e2f5305fb9 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -493,7 +493,7 @@ export const dynamicGasHandlers: Map Date: Thu, 25 Aug 2022 02:48:43 -0400 Subject: [PATCH 16/56] utils: remove isTruthy and isFalsy usage --- packages/util/src/account.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/util/src/account.ts b/packages/util/src/account.ts index cfa7262266..0c811af408 100644 --- a/packages/util/src/account.ts +++ b/packages/util/src/account.ts @@ -15,7 +15,6 @@ import { import { KECCAK256_NULL, KECCAK256_RLP } from './constants' import { assertIsBuffer, assertIsHexString, assertIsString } from './helpers' import { stripHexPrefix } from './internal' -import { isTruthy } from './types' import type { BigIntLike, BufferLike } from './types' @@ -38,10 +37,10 @@ export class Account { const { nonce, balance, storageRoot, codeHash } = accountData return new Account( - isTruthy(nonce) ? bufferToBigInt(toBuffer(nonce)) : undefined, - isTruthy(balance) ? bufferToBigInt(toBuffer(balance)) : undefined, - isTruthy(storageRoot) ? toBuffer(storageRoot) : undefined, - isTruthy(codeHash) ? toBuffer(codeHash) : undefined + nonce !== undefined ? bufferToBigInt(toBuffer(nonce)) : undefined, + balance !== undefined ? bufferToBigInt(toBuffer(balance)) : undefined, + storageRoot !== undefined ? toBuffer(storageRoot) : undefined, + codeHash !== undefined ? toBuffer(codeHash) : undefined ) } @@ -158,7 +157,7 @@ export const toChecksumAddress = function ( const address = stripHexPrefix(hexAddress).toLowerCase() let prefix = '' - if (isTruthy(eip1191ChainId)) { + if (eip1191ChainId !== undefined) { const chainId = bufferToBigInt(toBuffer(eip1191ChainId)) prefix = chainId.toString() + '0x' } From 4effbdeba4a2e6ad17e930fe7542ac351f32e4f7 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:58:37 -0400 Subject: [PATCH 17/56] block: remaining isTruthys --- packages/block/src/from-rpc.ts | 9 ++++++--- packages/block/src/header-from-rpc.ts | 4 +--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/block/src/from-rpc.ts b/packages/block/src/from-rpc.ts index e6fc4841a7..e6ba69edde 100644 --- a/packages/block/src/from-rpc.ts +++ b/packages/block/src/from-rpc.ts @@ -1,5 +1,5 @@ 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' @@ -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}. @@ -42,7 +45,7 @@ export function blockFromRpc(blockParams: any, uncles: any[] = [], options?: Blo const header = blockHeaderFromRpc(blockParams, options) const transactions: TypedTransaction[] = [] - if (isTruthy(blockParams.transactions)) { + if (blockParams.transactions !== undefined) { const opts = { common: header._common } for (const _txParams of blockParams.transactions) { const txParams = normalizeTxParams(_txParams) diff --git a/packages/block/src/header-from-rpc.ts b/packages/block/src/header-from-rpc.ts index 00bb2b6b3b..88d40e4367 100644 --- a/packages/block/src/header-from-rpc.ts +++ b/packages/block/src/header-from-rpc.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { BlockHeader } from './header' import { numberToHex } from './helpers' @@ -39,7 +37,7 @@ export function blockHeaderFromRpc(blockParams: any, options?: BlockOptions) { coinbase: miner, stateRoot, transactionsTrie: transactionsRoot, - receiptTrie: isTruthy(receiptRoot) ? receiptRoot : receiptsRoot, + receiptTrie: receiptRoot !== undefined && receiptRoot !== null ? receiptRoot : receiptsRoot, logsBloom, difficulty: numberToHex(difficulty), number, From 6c9023e54ac3a9e3056bc2799ae92e54136cf343 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 02:58:54 -0400 Subject: [PATCH 18/56] ethash: remove isTruthy and isFalsy usage --- packages/ethash/src/index.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/ethash/src/index.ts b/packages/ethash/src/index.ts index c2af9a911d..6fabc2d65d 100644 --- a/packages/ethash/src/index.ts +++ b/packages/ethash/src/index.ts @@ -5,8 +5,6 @@ import { bigIntToBuffer, bufArrToArr, bufferToBigInt, - isFalsy, - isTruthy, setLengthLeft, zeros, } from '@ethereumjs/util' @@ -122,7 +120,7 @@ export class Miner { while (iterations !== 0 && !this.stopMining) { // The promise/setTimeout construction is necessary to ensure we jump out of the event loop // Without this, for high-difficulty blocks JS never jumps out of the Promise - const solution = await new Promise((resolve) => { + const solution: Solution | null = await new Promise((resolve) => { setTimeout(() => { const nonce = setLengthLeft(bigIntToBuffer(this.currentNonce), 8) @@ -146,8 +144,8 @@ export class Miner { }, 0) }) - if (isTruthy(solution)) { - return solution + if (solution !== null) { + return solution } } } @@ -216,11 +214,12 @@ export class Ethash { } run(val: Buffer, nonce: Buffer, fullSize?: number) { - if (isFalsy(fullSize) && isTruthy(this.fullSize)) { - fullSize = this.fullSize - } - if (isFalsy(fullSize)) { - throw new Error('fullSize needed') + if (fullSize === undefined) { + if (this.fullSize === undefined) { + throw new Error('fullSize needed') + } else { + fullSize = this.fullSize + } } const n = Math.floor(fullSize / params.HASH_BYTES) const w = Math.floor(params.MIX_BYTES / params.WORD_BYTES) From 2cf4a9812d2fced9303aa763b7cd647f8a62a066 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 03:35:25 -0400 Subject: [PATCH 19/56] devp2p: remove isTruthy and isFalsy usage --- .../devp2p/examples/peer-communication-les.ts | 15 +++---- .../devp2p/examples/peer-communication.ts | 16 +++---- packages/devp2p/examples/simple.ts | 7 +-- packages/devp2p/src/dns/dns.ts | 5 +-- packages/devp2p/src/dpt/kbucket.ts | 4 +- packages/devp2p/src/dpt/server.ts | 7 ++- packages/devp2p/src/protocol/eth.ts | 19 +++----- packages/devp2p/src/protocol/les.ts | 34 ++++++--------- packages/devp2p/src/protocol/protocol.ts | 9 ++-- packages/devp2p/src/protocol/snap.ts | 3 +- packages/devp2p/src/rlpx/ecies.ts | 12 +++--- packages/devp2p/src/rlpx/peer.ts | 43 +++++++------------ packages/devp2p/src/rlpx/rlpx.ts | 16 +++---- packages/devp2p/src/util.ts | 6 +-- packages/devp2p/test/integration/util.ts | 13 +++--- 15 files changed, 82 insertions(+), 127 deletions(-) diff --git a/packages/devp2p/examples/peer-communication-les.ts b/packages/devp2p/examples/peer-communication-les.ts index 36b4ed7eeb..350e17e52a 100644 --- a/packages/devp2p/examples/peer-communication-les.ts +++ b/packages/devp2p/examples/peer-communication-les.ts @@ -2,7 +2,6 @@ import { randomBytes } from 'crypto' import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { TypedTransaction } from '@ethereumjs/tx' -import { isTruthy } from '@ethereumjs/util' import chalk from 'chalk' import ms from 'ms' @@ -65,9 +64,7 @@ const rlpx = new devp2p.RLPx(PRIVATE_KEY, { remoteClientIdFilter: REMOTE_CLIENTID_FILTER, }) -rlpx.on('error', (err) => - console.error(chalk.red(`RLPx error: ${isTruthy(err.stack) ? err.stack : err}`)) -) +rlpx.on('error', (err) => console.error(chalk.red(`RLPx error: ${err.stack ?? err}`))) rlpx.on('peer:added', (peer) => { const addr = getPeerAddr(peer) @@ -150,7 +147,7 @@ rlpx.on('peer:added', (peer) => { }) rlpx.on('peer:removed', (peer, reasonCode, disconnectWe) => { - const who = isTruthy(disconnectWe) ? 'we disconnect' : 'peer disconnect' + const who = disconnectWe === true ? 'we disconnect' : 'peer disconnect' const total = rlpx.getPeers().length console.log( chalk.yellow( @@ -172,9 +169,7 @@ rlpx.on('peer:error', (peer, err) => { return } - console.error( - chalk.red(`Peer error (${getPeerAddr(peer)}): ${isTruthy(err.stack) ? err.stack : err}`) - ) + console.error(chalk.red(`Peer error (${getPeerAddr(peer)}): ${err.stack ?? err}`)) }) // uncomment, if you want accept incoming connections @@ -183,7 +178,7 @@ rlpx.on('peer:error', (peer, err) => { for (const bootnode of BOOTNODES) { dpt.bootstrap(bootnode).catch((err) => { - console.error(chalk.bold.red(`DPT bootstrap error: ${isTruthy(err.stack) ? err.stack : err}`)) + console.error(chalk.bold.red(`DPT bootstrap error: ${err.stack ?? err}`)) }) } @@ -198,7 +193,7 @@ dpt.addPeer({ address: '127.0.0.1', udpPort: 30303, tcpPort: 30303 }) udpPort: peer.tcpPort }) }) - .catch((err) => console.log(`error on connection to local node: ${isTruthy(err.stack) ? err.stack : err}`)) */ + .catch((err) => console.log(`error on connection to local node: ${err.stack ?? err}`)) */ function onNewBlock(block: Block, peer: Peer) { const blockHashHex = block.hash().toString('hex') diff --git a/packages/devp2p/examples/peer-communication.ts b/packages/devp2p/examples/peer-communication.ts index 154aeeb75d..3fd39e4bf3 100644 --- a/packages/devp2p/examples/peer-communication.ts +++ b/packages/devp2p/examples/peer-communication.ts @@ -3,7 +3,7 @@ import { Block, BlockHeader } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { TransactionFactory, TypedTransaction } from '@ethereumjs/tx' -import { arrToBufArr, isTruthy } from '@ethereumjs/util' +import { arrToBufArr } from '@ethereumjs/util' import chalk from 'chalk' import LRUCache from 'lru-cache' import ms from 'ms' @@ -69,9 +69,7 @@ const rlpx = new devp2p.RLPx(PRIVATE_KEY, { remoteClientIdFilter: REMOTE_CLIENTID_FILTER, }) -rlpx.on('error', (err) => - console.error(chalk.red(`RLPx error: ${isTruthy(err.stack) ? err.stack : err}`)) -) +rlpx.on('error', (err) => console.error(chalk.red(`RLPx error: ${err.stack ?? err}`))) rlpx.on('peer:added', (peer) => { const addr = getPeerAddr(peer) @@ -289,7 +287,7 @@ rlpx.on('peer:added', (peer) => { }) rlpx.on('peer:removed', (peer, reasonCode, disconnectWe) => { - const who = isTruthy(disconnectWe) ? 'we disconnect' : 'peer disconnect' + const who = disconnectWe === true ? 'we disconnect' : 'peer disconnect' const total = rlpx.getPeers().length console.log( chalk.yellow( @@ -311,9 +309,7 @@ rlpx.on('peer:error', (peer, err) => { return } - console.error( - chalk.red(`Peer error (${getPeerAddr(peer)}): ${isTruthy(err.stack) ? err.stack : err}`) - ) + console.error(chalk.red(`Peer error (${getPeerAddr(peer)}): ${err.stack ?? err}`)) }) // uncomment, if you want accept incoming connections @@ -322,7 +318,7 @@ rlpx.on('peer:error', (peer, err) => { for (const bootnode of BOOTNODES) { dpt.bootstrap(bootnode).catch((err) => { - console.error(chalk.bold.red(`DPT bootstrap error: ${isTruthy(err.stack) ? err.stack : err}`)) + console.error(chalk.bold.red(`DPT bootstrap error: ${err.stack ?? err}`)) }) } @@ -337,7 +333,7 @@ dpt.addPeer({ address: '127.0.0.1', udpPort: 30303, tcpPort: 30303 }) udpPort: peer.tcpPort }) }) - .catch((err) => console.log(`error on connection to local node: ${isTruthy(err.stack) ? err.stack : err}`)) + .catch((err) => console.log(`error on connection to local node: ${err.stack ?? err}`)) */ const txCache = new LRUCache({ max: 1000 }) diff --git a/packages/devp2p/examples/simple.ts b/packages/devp2p/examples/simple.ts index f0939e3177..6105551209 100644 --- a/packages/devp2p/examples/simple.ts +++ b/packages/devp2p/examples/simple.ts @@ -1,5 +1,4 @@ import { Chain, Common } from '@ethereumjs/common' -import { isTruthy } from '@ethereumjs/util' import chalk from 'chalk' import { DPT } from '../src/index' @@ -25,7 +24,7 @@ const dpt = new DPT(Buffer.from(PRIVATE_KEY, 'hex'), { }) /* eslint-disable no-console */ -dpt.on('error', (err) => console.error(chalk.red(isTruthy(err.stack) ? err.stack : err))) +dpt.on('error', (err) => console.error(chalk.red(err.stack ?? err))) dpt.on('peer:added', (peer) => { const info = `(${peer.id.toString('hex')},${peer.address},${peer.udpPort},${peer.tcpPort})` @@ -42,7 +41,5 @@ dpt.on('peer:removed', (peer) => { // dpt.bind(30303, '0.0.0.0') for (const bootnode of BOOTNODES) { - dpt - .bootstrap(bootnode) - .catch((err) => console.error(chalk.bold.red(isTruthy(err.stack) ? err.stack : err))) + dpt.bootstrap(bootnode).catch((err) => console.error(chalk.bold.red(err.stack ?? err))) } diff --git a/packages/devp2p/src/dns/dns.ts b/packages/devp2p/src/dns/dns.ts index fae4992e6b..e3fc319f6d 100644 --- a/packages/devp2p/src/dns/dns.ts +++ b/packages/devp2p/src/dns/dns.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { ENR } from './enr' @@ -37,7 +36,7 @@ export class DNS { constructor(options: DNSOptions = {}) { this._DNSTreeCache = {} - if (isTruthy(options.dnsServerAddress)) { + if (options.dnsServerAddress !== undefined) { dns.setServers([options.dnsServerAddress]) } } @@ -198,7 +197,7 @@ export class DNS { * @return {boolean} */ private _isNewPeer(peer: PeerInfo | null, peers: PeerInfo[]): boolean { - if (isFalsy(peer) || isFalsy(peer.address)) return false + if (peer === null || peer.address === undefined) return false for (const existingPeer of peers) { if (peer.address === existingPeer.address) { diff --git a/packages/devp2p/src/dpt/kbucket.ts b/packages/devp2p/src/dpt/kbucket.ts index ac360024d6..c9a99e262e 100644 --- a/packages/devp2p/src/dpt/kbucket.ts +++ b/packages/devp2p/src/dpt/kbucket.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { EventEmitter } from 'events' import _KBucket = require('k-bucket') @@ -49,7 +48,8 @@ export class KBucket extends EventEmitter { const keys = [] if (Buffer.isBuffer(obj.id)) keys.push(obj.id.toString('hex')) - if (isTruthy(obj.address) && isTruthy(obj.tcpPort)) keys.push(`${obj.address}:${obj.tcpPort}`) + if (obj.address !== undefined && typeof obj.tcpPort === 'number') + keys.push(`${obj.address}:${obj.tcpPort}`) return keys } diff --git a/packages/devp2p/src/dpt/server.ts b/packages/devp2p/src/dpt/server.ts index 9b95b9950c..4ebc28d055 100644 --- a/packages/devp2p/src/dpt/server.ts +++ b/packages/devp2p/src/dpt/server.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import * as dgram from 'dgram' import { EventEmitter } from 'events' @@ -164,7 +163,7 @@ export class Server extends EventEmitter { } }, this._timeout) } - if (this._socket && isTruthy(peer.udpPort)) + if (this._socket && typeof peer.udpPort === 'number') this._socket.send(msg, 0, msg.length, peer.udpPort, peer.address) return msg.slice(0, 32) // message id } @@ -204,12 +203,12 @@ export class Server extends EventEmitter { case 'pong': { let rkey = info.data.hash.toString('hex') const rkeyParity = this._parityRequestMap.get(rkey) - if (isTruthy(rkeyParity)) { + if (rkeyParity !== undefined) { rkey = rkeyParity this._parityRequestMap.delete(rkeyParity) } const request = this._requests.get(rkey) - if (isTruthy(request)) { + if (request !== undefined) { this._requests.delete(rkey) request.deferred.resolve({ id: peerId, diff --git a/packages/devp2p/src/protocol/eth.ts b/packages/devp2p/src/protocol/eth.ts index ca899636aa..51e7fd26dd 100644 --- a/packages/devp2p/src/protocol/eth.ts +++ b/packages/devp2p/src/protocol/eth.ts @@ -5,7 +5,6 @@ import { bufArrToArr, bufferToBigInt, bufferToHex, - isTruthy, } from '@ethereumjs/util' import * as snappy from 'snappyjs' @@ -32,7 +31,7 @@ export class ETH extends Protocol { // Set forkHash and nextForkBlock if (this._version >= 64) { const c = this._peer._common - this._hardfork = isTruthy(c.hardfork()) ? c.hardfork() : this._hardfork + this._hardfork = c.hardfork() ?? this._hardfork // Set latestBlock minimally to start block of fork to have some more // accurate basis if no latestBlock is provided along status send this._latestBlock = c.hardforkBlock(this._hardfork) ?? BigInt(0) @@ -68,7 +67,7 @@ export class ETH extends Protocol { ) this._peerStatus = payload as ETH.StatusMsg const peerStatusMsg = `${ - isTruthy(this._peerStatus) ? this._getStatusString(this._peerStatus) : '' + this._peerStatus !== undefined ? this._getStatusString(this._peerStatus) : '' }` this.debug(messageName, `${debugMsg}: ${peerStatusMsg}`) this._handleStatus() @@ -219,7 +218,7 @@ export class ETH extends Protocol { )}` if (this._version >= 64) { sStr += `, ForkHash: ${ - isTruthy(status[5]) ? '0x' + (status[5][0] as Buffer).toString('hex') : '-' + status[5] !== undefined ? '0x' + (status[5][0] as Buffer).toString('hex') : '-' }` sStr += `, ForkNext: ${ (status[5][1] as Buffer).length > 0 ? buffer2int(status[5][1] as Buffer) : '-' @@ -268,11 +267,7 @@ export class ETH extends Protocol { let payload = Buffer.from(RLP.encode(bufArrToArr(this._status))) // Use snappy compression if peer supports DevP2P >=v5 - if ( - isTruthy(this._peer._hello) && - isTruthy(this._peer._hello.protocolVersion) && - this._peer._hello.protocolVersion >= 5 - ) { + if (this._peer._hello !== null && this._peer._hello.protocolVersion >= 5) { payload = snappy.compress(payload) } @@ -324,11 +319,7 @@ export class ETH extends Protocol { payload = Buffer.from(RLP.encode(bufArrToArr(payload))) // Use snappy compression if peer supports DevP2P >=v5 - if ( - isTruthy(this._peer._hello) && - isTruthy(this._peer._hello.protocolVersion) && - this._peer._hello?.protocolVersion >= 5 - ) { + if (this._peer._hello !== null && this._peer._hello?.protocolVersion >= 5) { payload = snappy.compress(payload) } diff --git a/packages/devp2p/src/protocol/les.ts b/packages/devp2p/src/protocol/les.ts index 683f6ae2b9..fbff85a5bf 100644 --- a/packages/devp2p/src/protocol/les.ts +++ b/packages/devp2p/src/protocol/les.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { arrToBufArr, bigIntToBuffer, bufArrToArr, isFalsy, isTruthy } from '@ethereumjs/util' +import { arrToBufArr, bigIntToBuffer, bufArrToArr } from '@ethereumjs/util' import ms = require('ms') import * as snappy from 'snappyjs' @@ -136,20 +136,20 @@ export class LES extends Protocol { )}, ` sStr += `HeadH:${status['headHash'].toString('hex')}, HeadN:${buffer2int(status['headNum'])}, ` sStr += `GenH:${status['genesisHash'].toString('hex')}` - if (isTruthy(status['serveHeaders'])) sStr += `, serveHeaders active` - if (isTruthy(status['serveChainSince'])) + if (status['serveHeaders'] !== undefined) sStr += `, serveHeaders active` + if (status['serveChainSince'] !== undefined) sStr += `, ServeCS: ${buffer2int(status['serveChainSince'])}` - if (isTruthy(status['serveStateSince'])) + if (status['serveStateSince'] !== undefined) sStr += `, ServeSS: ${buffer2int(status['serveStateSince'])}` - if (isTruthy(status['txRelay'])) sStr += `, txRelay active` - if (isTruthy(status['flowControl/BL)'])) sStr += `, flowControl/BL set` - if (isTruthy(status['flowControl/MRR)'])) sStr += `, flowControl/MRR set` - if (isTruthy(status['flowControl/MRC)'])) sStr += `, flowControl/MRC set` - if (isTruthy(status['forkID'])) + if (status['txRelay'] !== undefined) sStr += `, txRelay active` + if (status['flowControl/BL)'] !== undefined) sStr += `, flowControl/BL set` + if (status['flowControl/MRR)'] !== undefined) sStr += `, flowControl/MRR set` + if (status['flowControl/MRC)'] !== undefined) sStr += `, flowControl/MRC set` + if (status['forkID'] !== undefined) sStr += `, forkID: [crc32: ${status['forkID'][0].toString('hex')}, nextFork: ${buffer2int( status['forkID'][1] )}]` - if (isTruthy(status['recentTxLookup'])) + if (status['recentTxLookup'] !== undefined) sStr += `, recentTxLookup: ${buffer2int(status['recentTxLookup'])}` sStr += `]` return sStr @@ -158,7 +158,7 @@ export class LES extends Protocol { sendStatus(status: LES.Status) { if (this._status !== null) return - if (isFalsy(status.announceType)) { + if (status.announceType === undefined) { status['announceType'] = int2buffer(DEFAULT_ANNOUNCE_TYPE) } status['protocolVersion'] = int2buffer(this._version) @@ -181,11 +181,7 @@ export class LES extends Protocol { let payload = Buffer.from(RLP.encode(bufArrToArr(statusList))) // Use snappy compression if peer supports DevP2P >=v5 - if ( - isTruthy(this._peer._hello) && - isTruthy(this._peer._hello.protocolVersion) && - this._peer._hello?.protocolVersion >= 5 - ) { + if (this._peer._hello !== null && this._peer._hello?.protocolVersion >= 5) { payload = snappy.compress(payload) } @@ -248,11 +244,7 @@ export class LES extends Protocol { payload = Buffer.from(RLP.encode(payload)) // Use snappy compression if peer supports DevP2P >=v5 - if ( - isTruthy(this._peer._hello) && - isTruthy(this._peer._hello.protocolVersion) && - this._peer._hello?.protocolVersion >= 5 - ) { + if (this._peer._hello !== null && this._peer._hello.protocolVersion >= 5) { payload = snappy.compress(payload) } diff --git a/packages/devp2p/src/protocol/protocol.ts b/packages/devp2p/src/protocol/protocol.ts index 0d27c81d4e..9cfc811069 100644 --- a/packages/devp2p/src/protocol/protocol.ts +++ b/packages/devp2p/src/protocol/protocol.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { EventEmitter } from 'events' import ms = require('ms') @@ -72,7 +71,7 @@ export class Protocol extends EventEmitter { // Remote Peer IP logger const ip = this._peer._socket.remoteAddress - if (isTruthy(ip)) { + if (ip !== undefined) { this.msgDebuggers[ip] = devp2pDebug.extend(ip) } } @@ -85,7 +84,7 @@ export class Protocol extends EventEmitter { */ _addFirstPeerDebugger() { const ip = this._peer._socket.remoteAddress - if (isTruthy(ip)) { + if (ip !== undefined) { this.msgDebuggers[ip] = devp2pDebug.extend('FIRST_PEER') this._peer._addFirstPeerDebugger() this._firstPeer = ip @@ -100,11 +99,11 @@ export class Protocol extends EventEmitter { */ protected debug(messageName: string, msg: string) { this._debug(msg) - if (isTruthy(this.msgDebuggers[messageName])) { + if (this.msgDebuggers[messageName] !== undefined) { this.msgDebuggers[messageName](msg) } const ip = this._peer._socket.remoteAddress - if (isTruthy(ip) && isTruthy(this.msgDebuggers[ip])) { + if (ip !== undefined && this.msgDebuggers[ip] !== undefined) { this.msgDebuggers[ip](msg) } } diff --git a/packages/devp2p/src/protocol/snap.ts b/packages/devp2p/src/protocol/snap.ts index 0208267d29..c496b10f80 100644 --- a/packages/devp2p/src/protocol/snap.ts +++ b/packages/devp2p/src/protocol/snap.ts @@ -1,5 +1,4 @@ import { RLP, utils } from '@ethereumjs/rlp' -import { isTruthy } from '@ethereumjs/util' import * as snappy from 'snappyjs' import { formatLogData } from '../util' @@ -76,7 +75,7 @@ export class SNAP extends Protocol { // Use snappy compression if peer supports DevP2P >=v5 const protocolVersion = this._peer._hello?.protocolVersion - if (isTruthy(protocolVersion) && protocolVersion >= 5) { + if (protocolVersion !== undefined && protocolVersion >= 5) { payload = snappy.compress(payload) } diff --git a/packages/devp2p/src/rlpx/ecies.ts b/packages/devp2p/src/rlpx/ecies.ts index 9ea15ebf11..d6ffd6d921 100644 --- a/packages/devp2p/src/rlpx/ecies.ts +++ b/packages/devp2p/src/rlpx/ecies.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { bufArrToArr, isFalsy, isTruthy } from '@ethereumjs/util' +import { bufArrToArr } from '@ethereumjs/util' import * as crypto from 'crypto' import { debug as createDebugLogger } from 'debug' import { getPublicKey } from 'ethereum-cryptography/secp256k1' @@ -78,7 +78,7 @@ export class ECIES { constructor(privateKey: Buffer, id: Buffer, remoteId: Buffer) { this._privateKey = privateKey this._publicKey = id2pk(id) - this._remotePublicKey = isTruthy(remoteId) ? id2pk(remoteId) : null + this._remotePublicKey = remoteId !== null ? id2pk(remoteId) : null this._nonce = crypto.randomBytes(32) this._ephemeralPrivateKey = genPrivateKey() @@ -167,7 +167,7 @@ export class ECIES { this._ingressMac.update(Buffer.concat([xor(macSecret, this._nonce), remoteData])) this._egressMac = new MAC(macSecret) - if (isFalsy(this._initMsg)) return + if (this._initMsg === null || this._initMsg === undefined) return this._egressMac.update(Buffer.concat([xor(macSecret, this._remoteNonce), this._initMsg])) } @@ -246,16 +246,16 @@ export class ECIES { const x = ecdhX(this._remotePublicKey, this._privateKey) - if (isFalsy(this._remoteNonce)) { + if (this._remoteNonce === null) { return } this._remoteEphemeralPublicKey = Buffer.from( ecdsaRecover(signature, recoveryId, xor(x, this._remoteNonce), false) ) - if (isFalsy(this._remoteEphemeralPublicKey)) return + if (this._remoteEphemeralPublicKey === null) return this._ephemeralSharedSecret = ecdhX(this._remoteEphemeralPublicKey, this._ephemeralPrivateKey) - if (heid !== null && isTruthy(this._remoteEphemeralPublicKey)) { + if (heid !== null && this._remoteEphemeralPublicKey !== null) { assertEq( keccak256(pk2id(this._remoteEphemeralPublicKey)), heid, diff --git a/packages/devp2p/src/rlpx/peer.ts b/packages/devp2p/src/rlpx/peer.ts index f485ec3bf2..1bca1155ba 100644 --- a/packages/devp2p/src/rlpx/peer.ts +++ b/packages/devp2p/src/rlpx/peer.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { arrToBufArr, bufArrToArr, isFalsy, isTruthy } from '@ethereumjs/util' +import { arrToBufArr, bufArrToArr } from '@ethereumjs/util' import BufferList = require('bl') import { debug as createDebugLogger } from 'debug' import { EventEmitter } from 'events' @@ -88,7 +88,7 @@ export class Peer extends EventEmitter { _id: Buffer _remoteClientIdFilter: any _remoteId: Buffer - _EIP8: Buffer + _EIP8: Buffer | boolean _eciesSession: ECIES _state: string _weHello: HelloMsg | null @@ -101,7 +101,7 @@ export class Peer extends EventEmitter { _closed: boolean _connected: boolean _disconnectReason?: DISCONNECT_REASONS - _disconnectWe: any + _disconnectWe: null | boolean _pingTimeout: number _logger: Debugger @@ -139,9 +139,10 @@ export class Peer extends EventEmitter { this._socket.on('data', this._onSocketData.bind(this)) this._socket.on('error', (err: Error) => this.emit('error', err)) this._socket.once('close', this._onSocketClose.bind(this)) - this._logger = isTruthy(this._socket.remoteAddress) - ? devp2pDebug.extend(this._socket.remoteAddress).extend(DEBUG_BASE_NAME) - : devp2pDebug.extend(DEBUG_BASE_NAME) + this._logger = + this._socket.remoteAddress !== undefined + ? devp2pDebug.extend(this._socket.remoteAddress).extend(DEBUG_BASE_NAME) + : devp2pDebug.extend(DEBUG_BASE_NAME) this._connected = false this._closed = false this._disconnectWe = null @@ -166,7 +167,7 @@ export class Peer extends EventEmitter { this._logger( `Send auth (EIP8: ${this._EIP8}) to ${this._socket.remoteAddress}:${this._socket.remotePort}` ) - if (isTruthy(this._EIP8)) { + if (this._EIP8 === true) { const authEIP8 = this._eciesSession.createAuthEIP8() if (!authEIP8) return this._socket.write(authEIP8) @@ -284,11 +285,7 @@ export class Peer extends EventEmitter { const debugMsg = `Send PING to ${this._socket.remoteAddress}:${this._socket.remotePort}` this.debug('PING', debugMsg) let data = Buffer.from(RLP.encode([])) - if ( - isTruthy(this._hello) && - isTruthy(this._hello.protocolVersion) && - this._hello.protocolVersion >= 5 - ) { + if (this._hello !== null && this._hello.protocolVersion >= 5) { data = snappy.compress(data) } @@ -308,11 +305,7 @@ export class Peer extends EventEmitter { this.debug('PONG', debugMsg) let data = Buffer.from(RLP.encode([])) - if ( - isTruthy(this._hello) && - isTruthy(this._hello.protocolVersion) && - this._hello.protocolVersion >= 5 - ) { + if (this._hello !== null && this._hello.protocolVersion >= 5) { data = snappy.compress(data) } this._sendMessage(PREFIXES.PONG, data) @@ -397,7 +390,7 @@ export class Peer extends EventEmitter { return this.disconnect(DISCONNECT_REASONS.INVALID_IDENTITY) } - if (isTruthy(this._remoteClientIdFilter)) { + if (this._remoteClientIdFilter !== undefined) { for (const filterStr of this._remoteClientIdFilter) { if (this._hello.clientId.toLowerCase().includes(filterStr.toLowerCase())) { return this.disconnect(DISCONNECT_REASONS.USELESS_PEER) @@ -409,7 +402,7 @@ export class Peer extends EventEmitter { for (const item of this._hello.capabilities) { for (const obj of this._capabilities!) { if (obj.name !== item.name || obj.version !== item.version) continue - if (isTruthy(shared[obj.name]) && shared[obj.name].version > obj.version) continue + if (shared[obj.name] !== undefined && shared[obj.name].version > obj.version) continue shared[obj.name] = obj } } @@ -509,7 +502,7 @@ export class Peer extends EventEmitter { const parseData = this._socketData.slice(0, bytesCount) this._logger(`Received header ${this._socket.remoteAddress}:${this._socket.remotePort}`) const size = this._eciesSession.parseHeader(parseData) - if (isFalsy(size)) { + if (size === undefined) { this._logger('invalid header size!') return } @@ -569,11 +562,7 @@ export class Peer extends EventEmitter { // Use snappy uncompression if peer supports DevP2P >=v5 let compressed = false const origPayload = payload - if ( - isTruthy(this._hello) && - isTruthy(this._hello.protocolVersion) && - this._hello?.protocolVersion >= 5 - ) { + if (this._hello !== null && this._hello?.protocolVersion >= 5) { payload = snappy.uncompress(payload) compressed = true } @@ -702,7 +691,7 @@ export class Peer extends EventEmitter { */ _addFirstPeerDebugger() { const ip = this._socket.remoteAddress - if (isTruthy(ip)) { + if (ip !== undefined) { this._logger = devp2pDebug.extend(ip).extend(`FIRST_PEER`).extend(DEBUG_BASE_NAME) } } @@ -715,7 +704,7 @@ export class Peer extends EventEmitter { * @param disconnectReason Capitalized disconnect reason (e.g. 'TIMEOUT') */ private debug(messageName: string, msg: string, disconnectReason?: string) { - if (isTruthy(disconnectReason)) { + if (disconnectReason !== undefined) { this._logger.extend(messageName).extend(disconnectReason)(msg) } else { this._logger.extend(messageName)(msg) diff --git a/packages/devp2p/src/rlpx/rlpx.ts b/packages/devp2p/src/rlpx/rlpx.ts index 6188967475..7a5eae9136 100644 --- a/packages/devp2p/src/rlpx/rlpx.ts +++ b/packages/devp2p/src/rlpx/rlpx.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { getPublicKey } from 'ethereum-cryptography/secp256k1' import { EventEmitter } from 'events' @@ -79,7 +78,7 @@ export class RLPx extends EventEmitter { this._dpt = options.dpt ?? null if (this._dpt !== null) { this._dpt.on('peer:new', (peer: PeerInfo) => { - if (isFalsy(peer.tcpPort)) { + if (peer.tcpPort === null || peer.tcpPort === undefined) { this._dpt!.banPeer(peer, ms('5m')) this._debug(`banning peer with missing tcp port: ${peer.address}`) return @@ -108,9 +107,10 @@ export class RLPx extends EventEmitter { this._server.on('error', (err) => this.emit('error', err)) this._server.on('connection', (socket) => this._onConnect(socket, null)) const serverAddress = this._server.address() - this._debug = isTruthy(serverAddress) - ? devp2pDebug.extend(DEBUG_BASE_NAME).extend(serverAddress as string) - : devp2pDebug.extend(DEBUG_BASE_NAME) + this._debug = + serverAddress !== null + ? devp2pDebug.extend(DEBUG_BASE_NAME).extend(serverAddress as string) + : devp2pDebug.extend(DEBUG_BASE_NAME) this._peers = new Map() this._peersQueue = [] this._peersLRU = new LRUCache({ max: 25000 }) @@ -139,7 +139,7 @@ export class RLPx extends EventEmitter { } async connect(peer: PeerInfo) { - if (isFalsy(peer.tcpPort) || isFalsy(peer.address)) return + if (peer.tcpPort === undefined || peer.tcpPort === null || peer.address === undefined) return this._isAliveCheck() if (!Buffer.isBuffer(peer.id)) throw new TypeError('Expected peer.id as Buffer') @@ -249,14 +249,14 @@ export class RLPx extends EventEmitter { }) peer.once('close', (reason, disconnectWe) => { - if (isTruthy(disconnectWe)) { + if (disconnectWe === true) { this._debug( `disconnect from ${socket.remoteAddress}:${socket.remotePort}, reason: ${DISCONNECT_REASONS[reason]}`, `disconnect` ) } - if (isFalsy(disconnectWe) && reason === DISCONNECT_REASONS.TOO_MANY_PEERS) { + if (disconnectWe !== true && reason === DISCONNECT_REASONS.TOO_MANY_PEERS) { // hack if (this._getOpenQueueSlots() > 0) { this._peersQueue.push({ diff --git a/packages/devp2p/src/util.ts b/packages/devp2p/src/util.ts index 4f6a419c6c..de3f94761d 100644 --- a/packages/devp2p/src/util.ts +++ b/packages/devp2p/src/util.ts @@ -1,5 +1,5 @@ import { RLP } from '@ethereumjs/rlp' -import { arrToBufArr, isTruthy } from '@ethereumjs/util' +import { arrToBufArr } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { keccak256 as _keccak256 } from 'ethereum-cryptography/keccak' import { utils } from 'ethereum-cryptography/secp256k1' @@ -76,7 +76,7 @@ export function assertEq( if (expected.equals(actual)) return fullMsg = `${msg}: ${expected.toString('hex')} / ${actual.toString('hex')}` const debugMsg = `[ERROR] ${fullMsg}` - if (isTruthy(messageName)) { + if (messageName !== undefined) { debug(messageName, debugMsg) } else { debug(debugMsg) @@ -86,7 +86,7 @@ export function assertEq( if (expected === actual) return fullMsg = `${msg}: ${expected} / ${actual}` - if (isTruthy(messageName)) { + if (messageName !== undefined) { debug(messageName, fullMsg) } else { debug(fullMsg) diff --git a/packages/devp2p/test/integration/util.ts b/packages/devp2p/test/integration/util.ts index bcab807d71..5d4ea3b86b 100644 --- a/packages/devp2p/test/integration/util.ts +++ b/packages/devp2p/test/integration/util.ts @@ -1,5 +1,4 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { isTruthy } from '@ethereumjs/util' import { DPT, ETH, RLPx, genPrivateKey } from '../../src' import * as testdata from '../testdata.json' @@ -127,13 +126,13 @@ export function twoPeerMsgExchange( protocol.sendStatus(opts.status0) // (1 ->) protocol.once('status', () => { - if (isTruthy(opts.onOnceStatus0)) opts.onOnceStatus0(rlpxs, protocol) + if (opts.onOnceStatus0 !== undefined) opts.onOnceStatus0(rlpxs, protocol) }) // (-> 2) protocol.on('message', async (code: any, payload: any) => { - if (isTruthy(opts.onOnMsg0)) opts.onOnMsg0(rlpxs, protocol, code, payload) + if (opts.onOnMsg0 !== undefined) opts.onOnMsg0(rlpxs, protocol, code, payload) }) peer.on('error', (err: Error) => { - if (isTruthy(opts.onPeerError0)) { + if (opts.onPeerError0 !== undefined) { opts.onPeerError0(err, rlpxs) } else { t.fail(`Unexpected peer 0 error: ${err}`) @@ -152,10 +151,10 @@ export function twoPeerMsgExchange( protocol.sendStatus(opts.status1) // (2 ->) break } - if (isTruthy(opts.onOnMsg1)) opts.onOnMsg1(rlpxs, protocol, code, payload) + if (opts.onOnMsg1 !== undefined) opts.onOnMsg1(rlpxs, protocol, code, payload) }) peer.on('error', (err: any) => { - if (isTruthy(opts.onPeerError1)) { + if (opts.onPeerError1 !== undefined) { opts.onPeerError1(err, rlpxs) } else { t.fail(`Unexpected peer 1 error: ${err}`) @@ -244,7 +243,7 @@ export function twoPeerMsgExchange3( opts.receiveMessage(rlpxs, protocol, code, payload) }) peer.on('error', (err: any) => { - if (isTruthy(opts.onPeerError1)) { + if (opts.onPeerError1 !== false) { opts.onPeerError1(err, rlpxs) } else { t.fail(`Unexpected peer 1 error: ${err}`) From 46f345fc2d4a9cd81fa52cf89abdd782f8e3e15c Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:03:50 -0400 Subject: [PATCH 20/56] block: null coalescing instead of ternary --- packages/block/src/header-from-rpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block/src/header-from-rpc.ts b/packages/block/src/header-from-rpc.ts index 88d40e4367..0012cd3061 100644 --- a/packages/block/src/header-from-rpc.ts +++ b/packages/block/src/header-from-rpc.ts @@ -37,7 +37,7 @@ export function blockHeaderFromRpc(blockParams: any, options?: BlockOptions) { coinbase: miner, stateRoot, transactionsTrie: transactionsRoot, - receiptTrie: receiptRoot !== undefined && receiptRoot !== null ? receiptRoot : receiptsRoot, + receiptTrie: receiptRoot ?? receiptsRoot, logsBloom, difficulty: numberToHex(difficulty), number, From 1f4b9ecc998d3cdfdaf9d3e42d9f2261d0dbde03 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:05:05 -0400 Subject: [PATCH 21/56] block: check for BigInt(0) --- packages/block/src/header.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block/src/header.ts b/packages/block/src/header.ts index aa3572119b..196c8d83e5 100644 --- a/packages/block/src/header.ts +++ b/packages/block/src/header.ts @@ -452,7 +452,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 (typeof londonHardforkBlock === 'bigint' && this.number === londonHardforkBlock) { + if ( + typeof londonHardforkBlock === 'bigint' && + londonHardforkBlock !== BigInt(0) && + this.number === londonHardforkBlock + ) { const elasticity = this._common.param('gasConfig', 'elasticityMultiplier') parentGasLimit = parentGasLimit * elasticity } From 02258074f06ddfa30b7c460bb18c7722c79bb069 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:18:34 -0400 Subject: [PATCH 22/56] trie: to fixup --- packages/trie/benchmarks/engines/level.ts | 5 ++--- packages/trie/recipes/level-legacy.ts | 5 ++--- packages/trie/recipes/level.ts | 5 ++--- packages/trie/src/trie/trie.ts | 7 +++---- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/trie/benchmarks/engines/level.ts b/packages/trie/benchmarks/engines/level.ts index fb4a8fcacc..4f5a66a1a0 100644 --- a/packages/trie/benchmarks/engines/level.ts +++ b/packages/trie/benchmarks/engines/level.ts @@ -1,5 +1,4 @@ // eslint-disable-next-line implicit-dependencies/no-implicit -import { isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import type { BatchDBOp, DB } from '../../src/types' @@ -29,11 +28,11 @@ export class LevelDB implements DB { * @inheritDoc */ async get(key: Buffer): Promise { - let value = null + let value: Buffer | null = null try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error: any) { - if (isTruthy(error.notFound)) { + if (error.notFound !== undefined) { // not found, returning null } else { throw error diff --git a/packages/trie/recipes/level-legacy.ts b/packages/trie/recipes/level-legacy.ts index 515b315301..bcd2d22e24 100644 --- a/packages/trie/recipes/level-legacy.ts +++ b/packages/trie/recipes/level-legacy.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import level from 'level-mem' import type { BatchDBOp, DB } from '@ethereumjs/trie' @@ -14,11 +13,11 @@ export class LevelDB implements DB { } async get(key: Buffer): Promise { - let value = null + let value: Buffer | null = null try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error: any) { - if (isTruthy(error.notFound)) { + if (error.notFound !== undefined) { // not found, returning null } else { throw error diff --git a/packages/trie/recipes/level.ts b/packages/trie/recipes/level.ts index 7b26011365..e0b04f7bd5 100644 --- a/packages/trie/recipes/level.ts +++ b/packages/trie/recipes/level.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import type { BatchDBOp, DB } from '@ethereumjs/trie' @@ -16,11 +15,11 @@ export class LevelDB implements DB { } async get(key: Buffer): Promise { - let value = null + let value: Buffer | null = null try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error: any) { - if (isTruthy(error.notFound)) { + if (error.notFound !== undefined) { // not found, returning null } else { throw error diff --git a/packages/trie/src/trie/trie.ts b/packages/trie/src/trie/trie.ts index 591ee198ec..3e457e7de8 100644 --- a/packages/trie/src/trie/trie.ts +++ b/packages/trie/src/trie/trie.ts @@ -1,4 +1,4 @@ -import { RLP_EMPTY_STRING, isFalsy, isTruthy } from '@ethereumjs/util' +import { RLP_EMPTY_STRING } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak' import { CheckpointDB, MapDB } from '../db' @@ -633,8 +633,7 @@ export class Trie { async batch(ops: BatchDBOp[]): Promise { for (const op of ops) { if (op.type === 'put') { - if (isFalsy(op.value)) { - console.log('falsy op value', op.value) + if (op.value === null || op.value === undefined) { throw new Error('Invalid batch db operation') } await this.put(op.key, op.value) @@ -658,7 +657,7 @@ export class Trie { } as PutBatch }) - if (this.root() === this.EMPTY_TRIE_ROOT && isTruthy(opStack[0])) { + if (this.root() === this.EMPTY_TRIE_ROOT && opStack[0] !== undefined && opStack[0] !== null) { this.root(opStack[0].key) } From d9baab3ec3bfaf66727b3fc5c75b37e90c4319a4 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:18:54 -0400 Subject: [PATCH 23/56] block: to fixup --- packages/block/test/util.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block/test/util.ts b/packages/block/test/util.ts index e3f7fcb23e..7f4f0c9b91 100644 --- a/packages/block/test/util.ts +++ b/packages/block/test/util.ts @@ -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' @@ -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 From c157bd4d596e6ab8e421fd1b7501b0f7de8cd65a Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:30:15 -0400 Subject: [PATCH 24/56] evm: remove isTruthy/isFalsy --- packages/evm/src/evm.ts | 12 +++++------- packages/evm/src/interpreter.ts | 13 +++---------- packages/evm/src/opcodes/codes.ts | 3 +-- packages/evm/src/precompiles/01-ecrecover.ts | 3 +-- packages/evm/src/precompiles/02-sha256.ts | 4 ++-- packages/evm/src/precompiles/03-ripemd160.ts | 4 ++-- packages/evm/src/precompiles/04-identity.ts | 4 +--- packages/evm/src/precompiles/05-modexp.ts | 10 ++-------- packages/evm/src/precompiles/06-ecadd.ts | 4 +--- packages/evm/src/precompiles/07-ecmul.ts | 4 +--- packages/evm/src/precompiles/08-ecpairing.ts | 4 +--- packages/evm/src/precompiles/09-blake2f.ts | 4 +--- packages/evm/src/precompiles/0a-bls12-g1add.ts | 4 +--- packages/evm/src/precompiles/0b-bls12-g1mul.ts | 4 +--- packages/evm/src/precompiles/0c-bls12-g1multiexp.ts | 4 +--- packages/evm/src/precompiles/0d-bls12-g2add.ts | 4 +--- packages/evm/src/precompiles/0e-bls12-g2mul.ts | 4 +--- packages/evm/src/precompiles/0f-bls12-g2multiexp.ts | 4 +--- packages/evm/src/precompiles/10-bls12-pairing.ts | 4 +--- .../evm/src/precompiles/11-bls12-map-fp-to-g1.ts | 4 +--- .../evm/src/precompiles/12-bls12-map-fp2-to-g2.ts | 4 +--- packages/evm/src/precompiles/index.ts | 6 +++--- packages/evm/tests/utils.ts | 4 ++-- 23 files changed, 35 insertions(+), 80 deletions(-) diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index fb03e36ba2..b7c14ae785 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -6,8 +6,6 @@ import { bigIntToBuffer, generateAddress, generateAddress2, - isFalsy, - isTruthy, short, zeros, } from '@ethereumjs/util' @@ -372,7 +370,7 @@ export class EVM implements EVMInterface { debug(`Exit early on no code`) } } - if (isTruthy(errorMessage)) { + if (errorMessage !== undefined) { exit = true if (this.DEBUG) { debug(`Exit early on value transfer overflowed`) @@ -484,13 +482,13 @@ export class EVM implements EVMInterface { } let exit = false - if (isFalsy(message.code) || message.code.length === 0) { + if (message.code === undefined || message.code.length === 0) { exit = true if (this.DEBUG) { debug(`Exit early on no code`) } } - if (isTruthy(errorMessage)) { + if (errorMessage !== undefined) { exit = true if (this.DEBUG) { debug(`Exit early on value transfer overflowed`) @@ -596,8 +594,8 @@ export class EVM implements EVMInterface { // Save code if a new contract was created if ( !result.exceptionError && - isTruthy(result.returnValue) && - result.returnValue.toString() !== '' + result.returnValue !== undefined && + result.returnValue.length !== 0 ) { await this.eei.putContractCode(message.to, result.returnValue) if (this.DEBUG) { diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 7ae1f3aaf0..6a3e11d7a0 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -1,12 +1,5 @@ import { ConsensusAlgorithm } from '@ethereumjs/common' -import { - MAX_UINT64, - bigIntToHex, - bufferToBigInt, - intToHex, - isFalsy, - isTruthy, -} from '@ethereumjs/util' +import { MAX_UINT64, bigIntToHex, bufferToBigInt, intToHex } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import { EOF } from './eof' @@ -834,7 +827,7 @@ export class Interpreter { // Set return value if ( - isTruthy(results.execResult.returnValue) && + results.execResult.returnValue !== undefined && (!results.execResult.exceptionError || results.execResult.exceptionError.error === ERROR.REVERT) ) { @@ -951,7 +944,7 @@ export class Interpreter { async _selfDestruct(toAddress: Address): Promise { // only add to refund if this is the first selfdestruct for the address - if (isFalsy(this._result.selfdestruct[this._env.address.buf.toString('hex')])) { + if (this._result.selfdestruct[this._env.address.buf.toString('hex')] === undefined) { this.refundGas(this._common.param('gasPrices', 'selfdestructRefund')) } diff --git a/packages/evm/src/opcodes/codes.ts b/packages/evm/src/opcodes/codes.ts index 5fff036a87..ec1c318f83 100644 --- a/packages/evm/src/opcodes/codes.ts +++ b/packages/evm/src/opcodes/codes.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isTruthy } from '@ethereumjs/util' import { handlers } from './functions' import { dynamicGasHandlers } from './gas' @@ -379,7 +378,7 @@ export function getOpcodesForHF(common: Common, customOpcodes?: CustomOpcode[]): }, } opcodeBuilder = { ...opcodeBuilder, ...entry } - if (isTruthy(code.gasFunction)) { + if (code.gasFunction !== undefined) { dynamicGasHandlersCopy.set(code.opcode, code.gasFunction) } // logicFunction is never undefined diff --git a/packages/evm/src/precompiles/01-ecrecover.ts b/packages/evm/src/precompiles/01-ecrecover.ts index 3eb4fe51b1..9c7da88a6f 100644 --- a/packages/evm/src/precompiles/01-ecrecover.ts +++ b/packages/evm/src/precompiles/01-ecrecover.ts @@ -1,7 +1,6 @@ import { bufferToBigInt, ecrecover, - isFalsy, publicToAddress, setLengthLeft, setLengthRight, @@ -13,7 +12,7 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile01(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const gasUsed = opts._common.param('gasPrices', 'ecRecover') diff --git a/packages/evm/src/precompiles/02-sha256.ts b/packages/evm/src/precompiles/02-sha256.ts index e46c3fb02e..0e61aa4ff5 100644 --- a/packages/evm/src/precompiles/02-sha256.ts +++ b/packages/evm/src/precompiles/02-sha256.ts @@ -1,4 +1,4 @@ -import { isFalsy, toBuffer } from '@ethereumjs/util' +import { toBuffer } from '@ethereumjs/util' import { sha256 } from 'ethereum-cryptography/sha256' import { OOGResult } from '../evm' @@ -7,7 +7,7 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile02(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const data = opts.data diff --git a/packages/evm/src/precompiles/03-ripemd160.ts b/packages/evm/src/precompiles/03-ripemd160.ts index 4b32e929b4..13086a4f3c 100644 --- a/packages/evm/src/precompiles/03-ripemd160.ts +++ b/packages/evm/src/precompiles/03-ripemd160.ts @@ -1,4 +1,4 @@ -import { isFalsy, setLengthLeft, toBuffer } from '@ethereumjs/util' +import { setLengthLeft, toBuffer } from '@ethereumjs/util' import { ripemd160 } from 'ethereum-cryptography/ripemd160' import { OOGResult } from '../evm' @@ -7,7 +7,7 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile03(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const data = opts.data diff --git a/packages/evm/src/precompiles/04-identity.ts b/packages/evm/src/precompiles/04-identity.ts index a14b6471bd..17af5276c9 100644 --- a/packages/evm/src/precompiles/04-identity.ts +++ b/packages/evm/src/precompiles/04-identity.ts @@ -1,12 +1,10 @@ -import { isFalsy } from '@ethereumjs/util' - import { OOGResult } from '../evm' import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile04(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const data = opts.data diff --git a/packages/evm/src/precompiles/05-modexp.ts b/packages/evm/src/precompiles/05-modexp.ts index d52cac8047..80b83f7159 100644 --- a/packages/evm/src/precompiles/05-modexp.ts +++ b/packages/evm/src/precompiles/05-modexp.ts @@ -1,10 +1,4 @@ -import { - bigIntToBuffer, - bufferToBigInt, - isFalsy, - setLengthLeft, - setLengthRight, -} from '@ethereumjs/util' +import { bigIntToBuffer, bufferToBigInt, setLengthLeft, setLengthRight } from '@ethereumjs/util' import { OOGResult } from '../evm' @@ -83,7 +77,7 @@ export function expmod(a: bigint, power: bigint, modulo: bigint) { } export function precompile05(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const data = opts.data diff --git a/packages/evm/src/precompiles/06-ecadd.ts b/packages/evm/src/precompiles/06-ecadd.ts index 7380f99461..5a415d9d45 100644 --- a/packages/evm/src/precompiles/06-ecadd.ts +++ b/packages/evm/src/precompiles/06-ecadd.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { OOGResult } from '../evm' import type { ExecResult } from '../evm' @@ -8,7 +6,7 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile06(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const inputData = opts.data diff --git a/packages/evm/src/precompiles/07-ecmul.ts b/packages/evm/src/precompiles/07-ecmul.ts index 7da3659b02..a8f7cf34ff 100644 --- a/packages/evm/src/precompiles/07-ecmul.ts +++ b/packages/evm/src/precompiles/07-ecmul.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { OOGResult } from '../evm' import type { ExecResult } from '../evm' @@ -8,7 +6,7 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile07(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const inputData = opts.data const gasUsed = opts._common.param('gasPrices', 'ecMul') diff --git a/packages/evm/src/precompiles/08-ecpairing.ts b/packages/evm/src/precompiles/08-ecpairing.ts index 4e1e5a5b9e..c0355cc6bc 100644 --- a/packages/evm/src/precompiles/08-ecpairing.ts +++ b/packages/evm/src/precompiles/08-ecpairing.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { OOGResult } from '../evm' import type { ExecResult } from '../evm' @@ -8,7 +6,7 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile08(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const inputData = opts.data // no need to care about non-divisible-by-192, because bn128.pairing will properly fail in that case diff --git a/packages/evm/src/precompiles/09-blake2f.ts b/packages/evm/src/precompiles/09-blake2f.ts index ee984d818f..66b67b4e3a 100644 --- a/packages/evm/src/precompiles/09-blake2f.ts +++ b/packages/evm/src/precompiles/09-blake2f.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -158,7 +156,7 @@ export function F(h: Uint32Array, m: Uint32Array, t: Uint32Array, f: boolean, ro } export function precompile09(opts: PrecompileInput): ExecResult { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const data = opts.data if (data.length !== 213) { diff --git a/packages/evm/src/precompiles/0a-bls12-g1add.ts b/packages/evm/src/precompiles/0a-bls12-g1add.ts index 2a39249657..f944957406 100644 --- a/packages/evm/src/precompiles/0a-bls12-g1add.ts +++ b/packages/evm/src/precompiles/0a-bls12-g1add.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -9,7 +7,7 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToG1Point, BLS12_381_FromG1Point } = require('./util/bls12_381') export async function precompile0a(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/0b-bls12-g1mul.ts b/packages/evm/src/precompiles/0b-bls12-g1mul.ts index 6871824484..33c6be1241 100644 --- a/packages/evm/src/precompiles/0b-bls12-g1mul.ts +++ b/packages/evm/src/precompiles/0b-bls12-g1mul.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -13,7 +11,7 @@ const { } = require('./util/bls12_381') export async function precompile0b(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts b/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts index 3bd01c3f7c..458269cf88 100644 --- a/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts +++ b/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -13,7 +11,7 @@ const { } = require('./util/bls12_381') export async function precompile0c(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/0d-bls12-g2add.ts b/packages/evm/src/precompiles/0d-bls12-g2add.ts index 6f48dbddb7..78af41b78b 100644 --- a/packages/evm/src/precompiles/0d-bls12-g2add.ts +++ b/packages/evm/src/precompiles/0d-bls12-g2add.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -9,7 +7,7 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToG2Point, BLS12_381_FromG2Point } = require('./util/bls12_381') export async function precompile0d(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/0e-bls12-g2mul.ts b/packages/evm/src/precompiles/0e-bls12-g2mul.ts index 3e436ff0f7..cdb73062f2 100644 --- a/packages/evm/src/precompiles/0e-bls12-g2mul.ts +++ b/packages/evm/src/precompiles/0e-bls12-g2mul.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -13,7 +11,7 @@ const { } = require('./util/bls12_381') export async function precompile0e(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts b/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts index fa9d2aac29..7b3807aa44 100644 --- a/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts +++ b/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -15,7 +13,7 @@ const { } = require('./util/bls12_381') export async function precompile0f(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/10-bls12-pairing.ts b/packages/evm/src/precompiles/10-bls12-pairing.ts index b36790cbd1..a9bbb72c83 100644 --- a/packages/evm/src/precompiles/10-bls12-pairing.ts +++ b/packages/evm/src/precompiles/10-bls12-pairing.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -12,7 +10,7 @@ const zeroBuffer = Buffer.alloc(32, 0) const oneBuffer = Buffer.concat([Buffer.alloc(31, 0), Buffer.from('01', 'hex')]) export async function precompile10(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts b/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts index c2c60b475b..be7fc93d35 100644 --- a/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts +++ b/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -9,7 +7,7 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToFpPoint, BLS12_381_FromG1Point } = require('./util/bls12_381') export async function precompile11(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts b/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts index e1f20b9f3f..89f41dbde2 100644 --- a/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts +++ b/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts @@ -1,5 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' - import { EvmErrorResult, OOGResult } from '../evm' import { ERROR, EvmError } from '../exceptions' @@ -9,7 +7,7 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToFp2Point, BLS12_381_FromG2Point } = require('./util/bls12_381') export async function precompile12(opts: PrecompileInput): Promise { - if (isFalsy(opts.data)) throw new Error('opts.data missing but required') + if (opts.data === undefined) throw new Error('opts.data missing but required') const mcl = (opts._EVM)._mcl! diff --git a/packages/evm/src/precompiles/index.ts b/packages/evm/src/precompiles/index.ts index 51359a0b6b..f62c9fb317 100644 --- a/packages/evm/src/precompiles/index.ts +++ b/packages/evm/src/precompiles/index.ts @@ -1,5 +1,5 @@ import { Hardfork } from '@ethereumjs/common' -import { Address, isTruthy } from '@ethereumjs/util' +import { Address } from '@ethereumjs/util' import { precompile01 } from './01-ecrecover' import { precompile02 } from './02-sha256' @@ -149,7 +149,7 @@ const precompileAvailability: PrecompileAvailability = { function getPrecompile(address: Address, common: Common): PrecompileFunc { const addr = address.buf.toString('hex') - if (isTruthy(precompiles[addr])) { + if (precompiles[addr] !== undefined) { const availability = precompileAvailability[addr] if ( (availability.type === PrecompileAvailabilityCheck.Hardfork && @@ -193,7 +193,7 @@ function getActivePrecompiles( } const address = new Address(Buffer.from(addressString, 'hex')) const precompileFunc = getPrecompile(address, common) - if (isTruthy(precompileFunc)) { + if (precompileFunc !== undefined) { precompileMap.set(addressString, precompileFunc) } } diff --git a/packages/evm/tests/utils.ts b/packages/evm/tests/utils.ts index 5f3dfb39bd..c349187d39 100644 --- a/packages/evm/tests/utils.ts +++ b/packages/evm/tests/utils.ts @@ -1,6 +1,6 @@ import { Chain, Common } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' -import { Account, isTruthy } from '@ethereumjs/util' +import { Account } from '@ethereumjs/util' import path from 'path' import { Blockchain } from '../../blockchain/src' @@ -24,7 +24,7 @@ export function createAccount(nonce = BigInt(0), balance = BigInt(0xfff384)) { */ export function isRunningInKarma(): boolean { // eslint-disable-next-line no-undef - return isTruthy((globalThis).window?.__karma__) + return (globalThis).window?.__karma__ !== undefined } /** From ca413d505e2dab73d47ebc2459941a787233c8d0 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:33:18 -0400 Subject: [PATCH 25/56] evm: remove isTruthy/isFalsy in tests --- packages/evm/tests/precompiles/hardfork.spec.ts | 4 ++-- packages/evm/tests/runCode.spec.ts | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/evm/tests/precompiles/hardfork.spec.ts b/packages/evm/tests/precompiles/hardfork.spec.ts index b0779fea07..42e1a3ab3c 100644 --- a/packages/evm/tests/precompiles/hardfork.spec.ts +++ b/packages/evm/tests/precompiles/hardfork.spec.ts @@ -1,5 +1,5 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' -import { Address, isFalsy } from '@ethereumjs/util' +import { Address } from '@ethereumjs/util' import * as tape from 'tape' import { EVM } from '../../src' @@ -36,7 +36,7 @@ tape('Precompiles: hardfork availability', (t) => { // Check if ECPAIR is available in future hard forks. const commonPetersburg = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Petersburg }) ECPAIRING = getActivePrecompiles(commonPetersburg).get(ECPAIR_AddressStr)! - if (isFalsy(ECPAIRING)) { + if (ECPAIRING === undefined) { st.fail('ECPAIRING is not available in petersburg while it should be available') } else { st.pass('ECPAIRING available in petersburg') diff --git a/packages/evm/tests/runCode.spec.ts b/packages/evm/tests/runCode.spec.ts index 6f28a8145a..5e195545f0 100644 --- a/packages/evm/tests/runCode.spec.ts +++ b/packages/evm/tests/runCode.spec.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { EVM } from '../src' @@ -46,13 +45,13 @@ tape('VM.runCode: initial program counter', async (t) => { err = e } - if (isTruthy(testData.error)) { - err = isTruthy(err) ? err.message : 'no error thrown' + if (testData.error !== undefined) { + err = err?.message ?? 'no error thrown' t.equal(err, testData.error, 'error message should match') err = false } - t.assert(isFalsy(err)) + t.assert(err === false || err === undefined) } }) From 99078c1d28360a5037078416ac29632a5065dc41 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:44:27 -0400 Subject: [PATCH 26/56] common: remove isTruthy/isFalsy in tests --- packages/common/src/common.ts | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 78f5350923..e734a9b9a2 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -1,4 +1,4 @@ -import { TypeOutput, intToBuffer, isFalsy, isTruthy, toType } from '@ethereumjs/util' +import { TypeOutput, intToBuffer, toType } from '@ethereumjs/util' import { buf as crc32Buffer } from 'crc-32' import { EventEmitter } from 'events' @@ -178,7 +178,7 @@ export class Common extends EventEmitter { throw new Error(`Chain with ID ${chain} not supported`) } - if (isTruthy(initializedChains[chain])) { + if (initializedChains[chain] !== undefined) { return initializedChains[chain] as ChainConfig } @@ -191,7 +191,7 @@ export class Common extends EventEmitter { this._chainParams = this.setChain(opts.chain) this.DEFAULT_HARDFORK = this._chainParams.defaultHardfork ?? Hardfork.Merge this._hardfork = this.DEFAULT_HARDFORK - if (isTruthy(opts.hardfork)) { + if (opts.hardfork !== undefined) { this.setHardfork(opts.hardfork) } if (opts.eips) { @@ -285,7 +285,10 @@ export class Common extends EventEmitter { if (blockNumber >= BigInt(hf.block)) { hardfork = hf.name as Hardfork } - if (td && isTruthy(hf.ttd)) { + if ( + td && + (typeof hf.ttd === 'string' || (typeof hf.ttd === 'bigint' && hf.ttd !== BigInt(0))) + ) { if (td >= BigInt(hf.ttd)) { minTdHF = hf.name } else { @@ -296,14 +299,14 @@ export class Common extends EventEmitter { } if (td) { let msgAdd = `block number: ${blockNumber} (-> ${hardfork}), ` - if (isTruthy(minTdHF)) { + if (minTdHF !== undefined) { if (!this.hardforkGteHardfork(hardfork, minTdHF)) { const msg = 'HF determined by block number is lower than the minimum total difficulty HF' msgAdd += `total difficulty: ${td} (-> ${minTdHF})` throw new Error(`${msg}: ${msgAdd}`) } } - if (isTruthy(maxTdHF)) { + if (maxTdHF !== undefined) { if (!this.hardforkGteHardfork(maxTdHF, hardfork)) { const msg = 'Maximum HF determined by total difficulty is lower than the block number HF' msgAdd += `total difficulty: ${td} (-> ${maxTdHF})` @@ -360,7 +363,7 @@ export class Common extends EventEmitter { `${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}` ) } - if (isTruthy(EIPs[eip].requiredEIPs)) { + if (EIPs[eip].requiredEIPs !== undefined) { for (const elem of EIPs[eip].requiredEIPs) { if (!(eips.includes(elem) || this.isActivatedEIP(elem))) { throw new Error(`${eip} requires EIP ${elem}, but is not included in the EIP list`) @@ -412,7 +415,7 @@ export class Common extends EventEmitter { } // Parameter-inlining HF file (e.g. istanbul.json) } else { - if (isFalsy(hfChanges[1][topic])) { + if (hfChanges[1][topic] === undefined) { throw new Error(`Topic ${topic} not defined`) } if (hfChanges[1][topic][name] !== undefined) { @@ -495,7 +498,7 @@ export class Common extends EventEmitter { blockNumber = toType(blockNumber, TypeOutput.BigInt) hardfork = hardfork ?? this._hardfork const hfBlock = this.hardforkBlock(hardfork) - if (isTruthy(hfBlock) && blockNumber >= hfBlock) { + if (typeof hfBlock === 'bigint' && hfBlock !== BigInt(0) && blockNumber >= hfBlock) { return true } return false @@ -597,7 +600,7 @@ export class Common extends EventEmitter { blockNumber = toType(blockNumber, TypeOutput.BigInt) hardfork = hardfork ?? this._hardfork const block = this.hardforkBlock(hardfork) - return isTruthy(block) ? block === blockNumber : false + return typeof block === 'bigint' && block !== BigInt(0) ? block === blockNumber : false } /** @@ -809,9 +812,7 @@ export class Common extends EventEmitter { } if (hfChanges[0] === hardfork) break } - return isTruthy(value) - ? value - : (this._chainParams['consensus']['algorithm'] as ConsensusAlgorithm) + return value ?? (this._chainParams['consensus']['algorithm'] as ConsensusAlgorithm) } /** @@ -839,9 +840,7 @@ export class Common extends EventEmitter { } if (hfChanges[0] === hardfork) break } - return isTruthy(value) - ? value - : this._chainParams['consensus'][this.consensusAlgorithm() as ConsensusAlgorithm]! + return value ?? this._chainParams['consensus'][this.consensusAlgorithm() as ConsensusAlgorithm]! } /** From 4e24a013556b5aeebf93b1fc53e4cac8c1b77f7a Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 11:44:45 -0400 Subject: [PATCH 27/56] client: remove isTruthy/isFalsy from eth.ts --- packages/client/lib/rpc/modules/eth.ts | 42 ++++++++++++++------------ 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/client/lib/rpc/modules/eth.ts b/packages/client/lib/rpc/modules/eth.ts index ef242419d2..a6d8c61a70 100644 --- a/packages/client/lib/rpc/modules/eth.ts +++ b/packages/client/lib/rpc/modules/eth.ts @@ -7,8 +7,6 @@ import { bigIntToHex, bufferToHex, intToHex, - isFalsy, - isTruthy, setLengthLeft, toBuffer, toType, @@ -430,7 +428,7 @@ export class Eth { const [transaction, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -441,12 +439,12 @@ export class Eth { try { const runCallOpts = { - caller: isTruthy(from) ? Address.fromString(from) : undefined, - to: isTruthy(to) ? Address.fromString(to) : undefined, + caller: from !== undefined ? Address.fromString(from) : undefined, + to: to !== undefined ? Address.fromString(to) : undefined, gasLimit: toType(gasLimit, TypeOutput.BigInt), gasPrice: toType(gasPrice, TypeOutput.BigInt), value: toType(value, TypeOutput.BigInt), - data: isTruthy(data) ? toBuffer(data) : undefined, + data: data !== undefined ? toBuffer(data) : undefined, } const { execResult } = await vm.evm.runCall(runCallOpts) return bufferToHex(execResult.returnValue) @@ -488,14 +486,14 @@ export class Eth { const [transaction, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } const vm = await this._vm.copy() await vm.stateManager.setStateRoot(block.header.stateRoot) - if (isFalsy(transaction.gas)) { + if (transaction.gas === undefined) { // If no gas limit is specified use the last block gas limit as an upper bound. const latest = await this._chain.getCanonicalHeadHeader() transaction.gas = latest.gasLimit as any @@ -505,7 +503,8 @@ export class Eth { const tx = Transaction.fromTxData(txData, { common: vm._common, freeze: false }) // set from address - const from = isTruthy(transaction.from) ? Address.fromString(transaction.from) : Address.zero() + const from = + transaction.from !== undefined ? Address.fromString(transaction.from) : Address.zero() tx.getSenderAddress = () => { return from } @@ -537,7 +536,7 @@ export class Eth { const address = Address.fromString(addressHex) const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -606,7 +605,7 @@ export class Eth { const [addressHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -629,7 +628,7 @@ export class Eth { const [addressHex, positionHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -640,7 +639,7 @@ export class Eth { const storageTrie = await (vm.stateManager as any)._getStorageTrie(address) const position = setLengthLeft(toBuffer(positionHex), 32) const storage = await storageTrie.get(position) - return isTruthy(storage) + return storage !== null && storage !== undefined ? bufferToHex( setLengthLeft(Buffer.from(RLP.decode(Uint8Array.from(storage)) as Uint8Array), 32) ) @@ -681,7 +680,7 @@ export class Eth { const [addressHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -794,7 +793,7 @@ export class Eth { } } let from: Block, to: Block - if (isTruthy(blockHash)) { + if (blockHash !== undefined) { try { from = to = await this._chain.getBlock(toBuffer(blockHash)) } catch (error: any) { @@ -853,7 +852,7 @@ export class Eth { } }) let addrs - if (isTruthy(address)) { + if (address !== undefined) { if (Array.isArray(address)) { addrs = address.map((a) => toBuffer(a)) } else { @@ -885,7 +884,10 @@ export class Eth { const common = this.client.config.chainCommon.copy() const { syncTargetHeight } = this.client.config - if (isFalsy(syncTargetHeight) && !this.client.config.mine) { + if ( + (syncTargetHeight === undefined || syncTargetHeight === BigInt(0)) && + !this.client.config.mine + ) { throw { code: INTERNAL_ERROR, message: `client is not aware of the current chain height yet (give sync some more time)`, @@ -893,7 +895,7 @@ export class Eth { } // Set the tx common to an appropriate HF to create a tx // with matching HF rules - if (isTruthy(syncTargetHeight)) { + if (typeof syncTargetHeight === 'bigint' && syncTargetHeight !== BigInt(0)) { common.setHardforkByBlockNumber(syncTargetHeight) } @@ -954,7 +956,7 @@ export class Eth { const [addressHex, slotsHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (isFalsy(this._vm)) { + if (this._vm === undefined) { throw new Error('missing vm') } @@ -993,7 +995,7 @@ export class Eth { const startingBlock = bigIntToHex(synchronizer.startingBlock) let highestBlock - if (isTruthy(syncTargetHeight)) { + if (typeof syncTargetHeight === 'bigint' && syncTargetHeight !== BigInt(0)) { highestBlock = bigIntToHex(syncTargetHeight) } else { const bestPeer = await synchronizer.best() From c82852c3453f5ebc756ab0faed9d36415b5c648e Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 19:12:30 -0400 Subject: [PATCH 28/56] client: remove isTruthy/isFalsy from cli --- packages/client/bin/cli.ts | 43 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 21e427390b..a6eaa5a068 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -2,7 +2,7 @@ import { Blockchain } from '@ethereumjs/blockchain' import { Chain, Common, ConsensusAlgorithm, Hardfork } from '@ethereumjs/common' -import { Address, isFalsy, isTruthy, toBuffer } from '@ethereumjs/util' +import { Address, toBuffer } from '@ethereumjs/util' import { randomBytes } from 'crypto' import { existsSync } from 'fs' import { ensureDirSync, readFileSync, removeSync } from 'fs-extra' @@ -338,7 +338,7 @@ async function executeBlocks(client: EthereumClient) { process.exit() } const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService - if (isFalsy(execution)) throw new Error('executeBlocks requires execution') + if (execution === undefined) throw new Error('executeBlocks requires execution') await execution.executeBlocks(first, last, txHashes) } @@ -347,7 +347,7 @@ async function executeBlocks(client: EthereumClient) { * Note: this is destructive and removes blocks from the blockchain. Please back up your datadir. */ async function startBlock(client: EthereumClient) { - if (isFalsy(typeof args.startBlock)) return + if (args.startBlock === undefined) return const startBlock = BigInt(args.startBlock) const { blockchain } = client.chain const height = (await blockchain.getCanonicalHeadHeader()).number @@ -379,7 +379,7 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { const dbs = initDBs(config) let blockchain - if (isTruthy(customGenesisState)) { + if (customGenesisState !== undefined) { const validateConsensus = config.chainCommon.consensusAlgorithm() === ConsensusAlgorithm.Clique blockchain = await Blockchain.create({ db: dbs.chainDB, @@ -398,13 +398,13 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { ...dbs, }) - if (isTruthy(args.startBlock)) { + if (args.startBlock !== undefined) { await startBlock(client) } await client.open() - if (isTruthy(args.executeBlocks)) { + if (args.executeBlocks !== undefined) { // Special block execution debug mode (does not change any state) await executeBlocks(client) } else { @@ -557,7 +557,7 @@ function generateAccount(): Account { * Main entry point to start a client */ async function run() { - if (isTruthy(args.helprpc)) { + if (args.helprpc === true) { // Output RPC help and exit return helprpc() } @@ -567,14 +567,14 @@ async function run() { // Configure accounts for mining and prefunding in a local devnet const accounts: Account[] = [] - if (isTruthy(args.unlock)) { + if (typeof args.unlock === 'string') { accounts.push(...(await inputAccounts())) } let customGenesisState: GenesisState | undefined let common = new Common({ chain, hardfork: Hardfork.Chainstart }) - if (isTruthy(args.dev)) { + if (args.dev === true || typeof args.dev === 'string') { args.discDns = false if (accounts.length === 0) { // If generating new keys delete old chain data to prevent genesis block mismatch @@ -588,17 +588,17 @@ async function run() { // Configure common based on args given if ( - (isTruthy(args.customChainParams) || - isTruthy(args.customGenesisState) || - isTruthy(args.gethGenesis)) && - (args.network !== 'mainnet' || isTruthy(args.networkId)) + typeof args.customChainParams === 'string' || + typeof args.customGenesisState === 'string' || + (typeof args.gethGenesis === 'string' && + (args.network !== 'mainnet' || args.networkId !== undefined)) ) { console.error('cannot specify both custom chain parameters and preset network ID') process.exit() } // Use custom chain parameters file if specified - if (isTruthy(args.customChain)) { - if (isFalsy(args.customGenesisState)) { + if (typeof args.customChain === 'string') { + if (args.customGenesisState === undefined) { console.error('cannot have custom chain parameters without genesis state') process.exit() } @@ -613,7 +613,7 @@ async function run() { console.error(`invalid chain parameters: ${err.message}`) process.exit() } - } else if (isTruthy(args.gethGenesis)) { + } else if (typeof args.gethGenesis === 'string') { // Use geth genesis parameters file if specified const genesisFile = JSON.parse(readFileSync(args.gethGenesis, 'utf-8')) const chainName = path.parse(args.gethGenesis).base.split('.')[0] @@ -625,7 +625,7 @@ async function run() { customGenesisState = await parseGenesisState(genesisFile) } - if (isTruthy(args.mine) && accounts.length === 0) { + if (args.mine === true && accounts.length === 0) { console.error( 'Please provide an account to mine blocks with `--unlock [address]` or use `--dev` to generate' ) @@ -637,8 +637,8 @@ async function run() { ensureDirSync(configDirectory) const key = await Config.getClientKey(datadir, common) logger = getLogger(args) - const bootnodes = isTruthy(args.bootnodes) ? parseMultiaddrs(args.bootnodes) : undefined - const multiaddrs = isTruthy(args.multiaddrs) ? parseMultiaddrs(args.multiaddrs) : undefined + const bootnodes = args.bootnodes !== undefined ? parseMultiaddrs(args.bootnodes) : undefined + const multiaddrs = args.multiaddrs !== undefined ? parseMultiaddrs(args.multiaddrs) : undefined const config = new Config({ accounts, bootnodes, @@ -656,7 +656,7 @@ async function run() { maxPeers: args.maxPeers, maxPerRequest: args.maxPerRequest, maxFetcherJobs: args.maxFetcherJobs, - mine: isTruthy(args.mine) ? args.mine : args.dev, + mine: args.mine ?? args.dev, minerCoinbase: args.minerCoinbase, minPeers: args.minPeers, multiaddrs, @@ -671,8 +671,7 @@ async function run() { config.events.setMaxListeners(50) const client = await startClient(config, customGenesisState) - const servers = - isTruthy(args.rpc) || isTruthy(args.rpcEngine) ? startRPCServers(client, args) : [] + const servers = args.rpc === true || args.rpcEngine === true ? startRPCServers(client, args) : [] process.on('SIGINT', async () => { config.logger.info('Caught interrupt signal. Shutting down...') From 86562961ea41ec7e7bbd4cf8de464459b4c447d8 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 19:17:33 -0400 Subject: [PATCH 29/56] vm: remove isTruthy/isFalsy from execution lib --- packages/client/lib/execution/level.ts | 4 +--- packages/client/lib/execution/vmexecution.ts | 10 +++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/client/lib/execution/level.ts b/packages/client/lib/execution/level.ts index 793759e8ef..d8e2f45710 100644 --- a/packages/client/lib/execution/level.ts +++ b/packages/client/lib/execution/level.ts @@ -1,5 +1,3 @@ -// eslint-disable-next-line implicit-dependencies/no-implicit -import { isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import type { BatchDBOp, DB } from '@ethereumjs/trie' @@ -33,7 +31,7 @@ export class LevelDB implements DB { try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error: any) { - if (isTruthy(error.notFound)) { + if (error.notFound !== undefined) { // not found, returning null } else { throw error diff --git a/packages/client/lib/execution/vmexecution.ts b/packages/client/lib/execution/vmexecution.ts index dbf73d0402..868cd3eacf 100644 --- a/packages/client/lib/execution/vmexecution.ts +++ b/packages/client/lib/execution/vmexecution.ts @@ -7,7 +7,7 @@ import { import { ConsensusType, Hardfork } from '@ethereumjs/common' import { DefaultStateManager } from '@ethereumjs/statemanager' import { Trie } from '@ethereumjs/trie' -import { bufferToHex, isFalsy, isTruthy } from '@ethereumjs/util' +import { bufferToHex } from '@ethereumjs/util' import { VM } from '@ethereumjs/vm' import { Event } from '../types' @@ -39,7 +39,7 @@ export class VMExecution extends Execution { constructor(options: ExecutionOptions) { super(options) - if (isFalsy(this.config.vm)) { + if (this.config.vm === undefined) { const trie = new Trie({ db: new LevelDB(this.stateDB), useKeyHashing: true, @@ -110,7 +110,7 @@ export class VMExecution extends Execution { const result = await this.vm.runBlock(opts) receipts = result.receipts } - if (isTruthy(receipts)) { + if (receipts !== undefined) { // Save receipts this.pendingReceipts?.set(block.hash().toString('hex'), receipts) } @@ -294,7 +294,7 @@ export class VMExecution extends Execution { ) numExecuted = await this.vmPromise - if (isTruthy(errorBlock)) { + if (errorBlock !== undefined) { await this.chain.blockchain.setIteratorHead( 'vm', (errorBlock as unknown as Block).header.parentHash @@ -308,7 +308,7 @@ export class VMExecution extends Execution { throw new Error('cannot get iterator head: blockchain has no getIteratorHead function') } - if (isTruthy(numExecuted && numExecuted > 0)) { + if (typeof numExecuted === 'number' && numExecuted > 0) { const firstNumber = startHeadBlock.header.number const firstHash = short(startHeadBlock.hash()) const lastNumber = endHeadBlock.header.number From 75f7940b0b64b6a1e038f4100c51aba3c5784908 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Thu, 25 Aug 2022 19:17:49 -0400 Subject: [PATCH 30/56] vm: remove isTruthy/isFalsy from miner lib --- packages/client/lib/miner/miner.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/client/lib/miner/miner.ts b/packages/client/lib/miner/miner.ts index b2e68d243e..3af2fd527a 100644 --- a/packages/client/lib/miner/miner.ts +++ b/packages/client/lib/miner/miner.ts @@ -1,7 +1,6 @@ import { BlockHeader } from '@ethereumjs/block' import { ConsensusType, Hardfork } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { MemoryLevel } from 'memory-level' import { Event } from '../types' @@ -95,7 +94,7 @@ export class Miner { const inTurn = await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress ) - if (isFalsy(inTurn)) { + if (inTurn === false) { const signerCount = (blockchain.consensus as CliqueConsensus).cliqueActiveSigners().length timeout += Math.random() * signerCount * 500 } @@ -204,7 +203,7 @@ export class Miner { } if (this.config.chainCommon.consensusType() === ConsensusType.ProofOfWork) { - while (isFalsy(this.nextSolution)) { + while (this.nextSolution === undefined) { this.config.logger.info(`Miner: Waiting to find next PoW solution 🔨`) await new Promise((r) => setTimeout(r, 1000)) } @@ -229,12 +228,16 @@ export class Miner { inTurn = await (vmCopy.blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress ) - difficulty = isTruthy(inTurn) ? 2 : 1 + difficulty = inTurn === true ? 2 : 1 } let baseFeePerGas const londonHardforkBlock = this.config.chainCommon.hardforkBlock(Hardfork.London) - if (isTruthy(londonHardforkBlock) && number === londonHardforkBlock) { + if ( + typeof londonHardforkBlock === 'bigint' && + londonHardforkBlock !== BigInt(0) && + number === londonHardforkBlock + ) { // Get baseFeePerGas from `paramByEIP` since 1559 not currently active on common baseFeePerGas = this.config.chainCommon.paramByEIP('gasConfig', 'initialBaseFee', 1559) ?? BigInt(0) @@ -271,7 +274,9 @@ export class Miner { const txs = await this.service.txPool.txsByPriceAndNonce(baseFeePerGas) this.config.logger.info( `Miner: Assembling block from ${txs.length} eligible txs ${ - isTruthy(baseFeePerGas) ? `(baseFee: ${baseFeePerGas})` : '' + typeof baseFeePerGas === 'bigint' && baseFeePerGas !== BigInt(0) + ? `(baseFee: ${baseFeePerGas})` + : '' }` ) let index = 0 @@ -305,7 +310,7 @@ export class Miner { `Miner: Sealed block with ${block.transactions.length} txs ${ this.config.chainCommon.consensusType() === ConsensusType.ProofOfWork ? `(difficulty: ${block.header.difficulty})` - : `(${isTruthy(inTurn) ? 'in turn' : 'not in turn'})` + : `(${inTurn === true ? 'in turn' : 'not in turn'})` }` ) this.assembling = false From b3cba9e838b3116a53699663a90d0435a0c01536 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 10:37:08 -0400 Subject: [PATCH 31/56] client: more removal of isTruthy/isFalsy --- packages/client/bin/startRpc.ts | 5 ++--- packages/client/lib/logging.ts | 17 +++++++++-------- packages/client/lib/net/peer/rlpxpeer.ts | 7 +++---- .../client/test/integration/mocks/network.ts | 9 ++++----- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/client/bin/startRpc.ts b/packages/client/bin/startRpc.ts index 6cd146cca3..4742787ab9 100644 --- a/packages/client/bin/startRpc.ts +++ b/packages/client/bin/startRpc.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import { readFileSync, writeFileSync } from 'fs' import { RPCManager, saveReceiptsMethods } from '../lib/rpc' @@ -38,11 +37,11 @@ type RPCArgs = { */ function parseJwtSecret(config: Config, jwtFilePath?: string): Buffer { let jwtSecret - if (isTruthy(jwtFilePath)) { + if (jwtFilePath !== undefined) { const jwtSecretContents = readFileSync(jwtFilePath, 'utf-8').trim() const hexPattern = new RegExp(/^(0x|0X)?(?[a-fA-F0-9]+)$/, 'g') const jwtSecretHex = hexPattern.exec(jwtSecretContents)?.groups?.jwtSecret - if (isFalsy(jwtSecretHex) || jwtSecretHex.length !== 64) { + if (jwtSecretHex === undefined || jwtSecretHex.length !== 64) { throw Error('Need a valid 256 bit hex encoded secret') } config.logger.debug(`Read a hex encoded jwt secret from path=${jwtFilePath}`) diff --git a/packages/client/lib/logging.ts b/packages/client/lib/logging.ts index c7d4e89ede..c67d1ca0fe 100644 --- a/packages/client/lib/logging.ts +++ b/packages/client/lib/logging.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import * as chalk from 'chalk' import { createLogger, format, transports as wTransports } from 'winston' @@ -32,10 +31,10 @@ enum LevelColors { * Adds stack trace to error message if included */ const errorFormat = format((info: any) => { - if (info.message instanceof Error && isTruthy(info.message.stack)) { + if (info.message instanceof Error && info.message.stack !== undefined) { return { ...info, message: info.message.stack } } - if (info instanceof Error && isTruthy(info.stack)) { + if (info instanceof Error && info.stack !== undefined) { return { ...info, message: info.stack } } return info @@ -55,7 +54,7 @@ function logFormat(colors = false) { return printf((info: any) => { let level = info.level.toUpperCase() - if (isFalsy(info.message)) info.message = '(empty message)' + if (info.message === undefined) info.message = '(empty message)' if (colors) { const colorLevel = LevelColors[info.level as keyof typeof LevelColors] @@ -65,8 +64,10 @@ function logFormat(colors = false) { const regex = /(\w+)=(.+?)(?:\s|$)/g const replaceFn = (_: any, tag: string, char: string) => `${color(tag)}=${char} ` info.message = info.message.replace(regex, replaceFn) - if (isTruthy(info.attentionCL)) info.attentionCL = info.attentionCL.replace(regex, replaceFn) - if (isTruthy(info.attentionHF)) info.attentionHF = info.attentionHF.replace(regex, replaceFn) + if (info.attentionCL !== undefined) + info.attentionCL = info.attentionCL.replace(regex, replaceFn) + if (info.attentionHF !== undefined) + info.attentionHF = info.attentionHF.replace(regex, replaceFn) } if (info.attentionCL !== undefined) attentionCL = info.attentionCL @@ -101,7 +102,7 @@ function logFileTransport(args: any) { level: args.logLevelFile, format: formatConfig(), } - if (isFalsy(args.logRotate)) { + if (args.logRotate !== true) { return new wTransports.File({ ...opts, filename, @@ -129,7 +130,7 @@ export function getLogger(args: { [key: string]: any } = { loglevel: 'info' }) { format: formatConfig(true), }), ] - if (isTruthy(args.logFile)) { + if (typeof args.logFile === 'string') { transports.push(logFileTransport(args)) } const logger = createLogger({ diff --git a/packages/client/lib/net/peer/rlpxpeer.ts b/packages/client/lib/net/peer/rlpxpeer.ts index bbc49bfc26..5b2cf082e3 100644 --- a/packages/client/lib/net/peer/rlpxpeer.ts +++ b/packages/client/lib/net/peer/rlpxpeer.ts @@ -4,7 +4,6 @@ import { RLPx as Devp2pRLPx, SNAP as Devp2pSNAP, } from '@ethereumjs/devp2p' -import { isTruthy } from '@ethereumjs/util' import { randomBytes } from 'crypto' import { Event } from '../../types' @@ -16,7 +15,7 @@ import type { Protocol } from '../protocol' import type { RlpxServer } from '../server' import type { PeerOptions } from './peer' import type { Capabilities as Devp2pCapabilities, Peer as Devp2pRlpxPeer } from '@ethereumjs/devp2p' -const devp2pCapabilities: any = { +const devp2pCapabilities = { snap1: Devp2pSNAP.snap, eth66: Devp2pETH.eth66, les2: Devp2pLES.les2, @@ -89,8 +88,8 @@ export class RlpxPeer extends Peer { const { name, versions } = protocol const keys = versions.map((v: number) => name + String(v)) for (const key of keys) { - const capability = devp2pCapabilities[key] - if (isTruthy(capability)) { + const capability = devp2pCapabilities[key as keyof typeof devp2pCapabilities] + if (capability !== undefined) { capabilities.push(capability) } } diff --git a/packages/client/test/integration/mocks/network.ts b/packages/client/test/integration/mocks/network.ts index 8f782fa5d3..ab5953d56c 100644 --- a/packages/client/test/integration/mocks/network.ts +++ b/packages/client/test/integration/mocks/network.ts @@ -1,4 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' import { EventEmitter } from 'events' const DuplexPair = require('it-pair/duplex') @@ -26,7 +25,7 @@ interface ServerDetails { export const servers: ServerDetails = {} export function createServer(location: string) { - if (isTruthy(servers[location])) { + if (servers[location] !== undefined) { throw new Error(`Already running a server at ${location}`) } servers[location] = { @@ -39,9 +38,9 @@ export function createServer(location: string) { } export function destroyStream(id: string, location: string) { - if (isTruthy(servers[location])) { + if (servers[location] !== undefined) { const stream = servers[location].streams[id] - if (isTruthy(stream)) { + if (stream !== undefined) { delete servers[location].streams[id] } } @@ -58,7 +57,7 @@ export async function destroyServer(location: string) { } export function createStream(id: string, location: string, protocols: string[]) { - if (isFalsy(servers[location])) { + if (servers[location] === undefined) { throw new Error(`There is no server at ${location}`) } const stream = Stream(protocols) From 99a458fb77b286ba62ab937f6411ab2770afd3fd Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 14:16:04 -0400 Subject: [PATCH 32/56] client: attempt fixing tests --- packages/client/bin/cli.ts | 2 +- packages/client/lib/logging.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index a6eaa5a068..2ec61d1e9d 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -347,7 +347,7 @@ async function executeBlocks(client: EthereumClient) { * Note: this is destructive and removes blocks from the blockchain. Please back up your datadir. */ async function startBlock(client: EthereumClient) { - if (args.startBlock === undefined) return + if (args.startBlock === undefined || args.startBlock === 0) return const startBlock = BigInt(args.startBlock) const { blockchain } = client.chain const height = (await blockchain.getCanonicalHeadHeader()).number diff --git a/packages/client/lib/logging.ts b/packages/client/lib/logging.ts index c67d1ca0fe..c0a44a63d4 100644 --- a/packages/client/lib/logging.ts +++ b/packages/client/lib/logging.ts @@ -64,9 +64,9 @@ function logFormat(colors = false) { const regex = /(\w+)=(.+?)(?:\s|$)/g const replaceFn = (_: any, tag: string, char: string) => `${color(tag)}=${char} ` info.message = info.message.replace(regex, replaceFn) - if (info.attentionCL !== undefined) + if (typeof info.attentionCL === 'string') info.attentionCL = info.attentionCL.replace(regex, replaceFn) - if (info.attentionHF !== undefined) + if (typeof info.attentionHF === 'string') info.attentionHF = info.attentionHF.replace(regex, replaceFn) } From 0493427566200ae33ba67def855fcc3a1692c676 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 14:30:09 -0400 Subject: [PATCH 33/56] trie: remove remaining isTruthy --- packages/trie/test/official.spec.ts | 7 +++---- packages/trie/test/trie/secure.spec.ts | 13 +++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/trie/test/official.spec.ts b/packages/trie/test/official.spec.ts index 1ad27b7ba7..5d93fc4c57 100644 --- a/packages/trie/test/official.spec.ts +++ b/packages/trie/test/official.spec.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { Trie } from '../src' @@ -13,9 +12,9 @@ tape('official tests', async function (t) { const expect = jsonTests[testName].root for (const input of inputs) { for (let i = 0; i < 2; i++) { - if (isTruthy(input[i]) && input[i].slice(0, 2) === '0x') { + if (input[i] !== undefined && input[i] !== null && input[i].slice(0, 2) === '0x') { input[i] = Buffer.from(input[i].slice(2), 'hex') - } else if (isTruthy(input[i]) && typeof input[i] === 'string') { + } else if (typeof input[i] === 'string') { input[i] = Buffer.from(input[i]) } await trie.put(Buffer.from(input[0]), input[1]) @@ -42,7 +41,7 @@ tape('official tests any order', async function (t) { key = Buffer.from(key.slice(2), 'hex') } - if (isTruthy(val) && val.slice(0, 2) === '0x') { + if (val !== undefined && val !== null && val.slice(0, 2) === '0x') { val = Buffer.from(val.slice(2), 'hex') } diff --git a/packages/trie/test/trie/secure.spec.ts b/packages/trie/test/trie/secure.spec.ts index 66b8e70d7c..1bd5ba52a5 100644 --- a/packages/trie/test/trie/secure.spec.ts +++ b/packages/trie/test/trie/secure.spec.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { createHash } from 'crypto' import * as tape from 'tape' @@ -41,7 +40,10 @@ tape('SecureTrie', function (t) { it.test('empty values', async function (t) { for (const row of jsonTests.emptyValues.in) { - const val = isTruthy(row[1]) ? Buffer.from(row[1]) : (null as unknown as Buffer) + const val = + row[1] !== undefined && row[1] !== null + ? Buffer.from(row[1]) + : (null as unknown as Buffer) await trie.put(Buffer.from(row[0]), val) } t.equal('0x' + trie.root().toString('hex'), jsonTests.emptyValues.root) @@ -51,7 +53,10 @@ tape('SecureTrie', function (t) { it.test('branchingTests', async function (t) { trie = new Trie({ useKeyHashing: true, db: new MapDB() }) for (const row of jsonTests.branchingTests.in) { - const val = isTruthy(row[1]) ? Buffer.from(row[1]) : (null as unknown as Buffer) + const val = + row[1] !== undefined && row[1] !== null + ? Buffer.from(row[1]) + : (null as unknown as Buffer) await trie.put(Buffer.from(row[0]), val) } t.equal('0x' + trie.root().toString('hex'), jsonTests.branchingTests.root) @@ -61,7 +66,7 @@ tape('SecureTrie', function (t) { it.test('jeff', async function (t) { for (const row of jsonTests.jeff.in) { let val = row[1] - if (isTruthy(val)) { + if (val !== undefined && val !== null) { val = Buffer.from(row[1].slice(2), 'hex') } await trie.put(Buffer.from(row[0].slice(2), 'hex'), val) From b80188465b74d8125796e8e1513883d258070653 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 14:57:04 -0400 Subject: [PATCH 34/56] client: fix broken test --- packages/client/bin/cli.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 2ec61d1e9d..695819ceb4 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -347,7 +347,7 @@ async function executeBlocks(client: EthereumClient) { * Note: this is destructive and removes blocks from the blockchain. Please back up your datadir. */ async function startBlock(client: EthereumClient) { - if (args.startBlock === undefined || args.startBlock === 0) return + if (typeof args.startBlock === 'number') return const startBlock = BigInt(args.startBlock) const { blockchain } = client.chain const height = (await blockchain.getCanonicalHeadHeader()).number @@ -398,7 +398,7 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { ...dbs, }) - if (args.startBlock !== undefined) { + if (typeof args.startBlock === 'number') { await startBlock(client) } @@ -656,7 +656,7 @@ async function run() { maxPeers: args.maxPeers, maxPerRequest: args.maxPerRequest, maxFetcherJobs: args.maxFetcherJobs, - mine: args.mine ?? args.dev, + mine: args.mine === true ? args.mine : args.dev, minerCoinbase: args.minerCoinbase, minPeers: args.minPeers, multiaddrs, From 234effe9c0d2ccf83c90dfbc8c2fa1748440e455 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 14:57:17 -0400 Subject: [PATCH 35/56] client: improve printf info types --- packages/client/lib/logging.ts | 58 +++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/packages/client/lib/logging.ts b/packages/client/lib/logging.ts index c0a44a63d4..0c04f93c89 100644 --- a/packages/client/lib/logging.ts +++ b/packages/client/lib/logging.ts @@ -51,33 +51,39 @@ const errorFormat = format((info: any) => { * */ function logFormat(colors = false) { - return printf((info: any) => { - let level = info.level.toUpperCase() - - if (info.message === undefined) info.message = '(empty message)' - - if (colors) { - const colorLevel = LevelColors[info.level as keyof typeof LevelColors] - const color = chalk.keyword(colorLevel).bind(chalk) - level = color(level) - - const regex = /(\w+)=(.+?)(?:\s|$)/g - const replaceFn = (_: any, tag: string, char: string) => `${color(tag)}=${char} ` - info.message = info.message.replace(regex, replaceFn) - if (typeof info.attentionCL === 'string') - info.attentionCL = info.attentionCL.replace(regex, replaceFn) - if (typeof info.attentionHF === 'string') - info.attentionHF = info.attentionHF.replace(regex, replaceFn) + return printf( + (info: { + level: string + message: string | undefined + [key: string]: string | null | undefined + }) => { + let level = info.level.toUpperCase() + + if (info.message === undefined) info.message = '(empty message)' + + if (colors) { + const colorLevel = LevelColors[info.level as keyof typeof LevelColors] + const color = chalk.keyword(colorLevel).bind(chalk) + level = color(level) + + const regex = /(\w+)=(.+?)(?:\s|$)/g + const replaceFn = (_: any, tag: string, char: string) => `${color(tag)}=${char} ` + info.message = info.message.replace(regex, replaceFn) + if (typeof info.attentionCL === 'string') + info.attentionCL = info.attentionCL.replace(regex, replaceFn) + if (typeof info.attentionHF === 'string') + info.attentionHF = info.attentionHF.replace(regex, replaceFn) + } + + if (info.attentionCL !== undefined) attentionCL = info.attentionCL + if (info.attentionHF !== undefined) attentionHF = info.attentionHF + const CLLog = attentionCL !== null ? `[ ${attentionCL} ] ` : '' + const HFLog = attentionHF !== null ? `[ ${attentionHF} ] ` : '' + + const msg = `[${info.timestamp}] ${level} ${CLLog}${HFLog}${info.message}` + return msg } - - if (info.attentionCL !== undefined) attentionCL = info.attentionCL - if (info.attentionHF !== undefined) attentionHF = info.attentionHF - const CLLog = attentionCL !== null ? `[ ${attentionCL} ] ` : '' - const HFLog = attentionHF !== null ? `[ ${attentionHF} ] ` : '' - - const msg = `[${info.timestamp}] ${level} ${CLLog}${HFLog}${info.message}` - return msg - }) + ) } /** From d472b6e168957f3abcb85b5b36fca7f6cc529488 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 14:57:41 -0400 Subject: [PATCH 36/56] client: remove more isTruthy/isFalsy instances --- packages/client/lib/net/protocol/boundprotocol.ts | 9 +++++---- packages/client/lib/util/rpc.ts | 13 ++++++------- packages/client/test/util/rpc.spec.ts | 6 ++++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/client/lib/net/protocol/boundprotocol.ts b/packages/client/lib/net/protocol/boundprotocol.ts index 4f236ee6cb..a29c60f624 100644 --- a/packages/client/lib/net/protocol/boundprotocol.ts +++ b/packages/client/lib/net/protocol/boundprotocol.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { Event } from '../../types' import type { Config } from '../../config' @@ -101,7 +99,7 @@ export class BoundProtocol { error = new Error(`Could not decode message ${message.name}: ${e}`) } const resolver = this.resolvers.get(incoming.code) - if (isTruthy(resolver)) { + if (resolver !== undefined) { clearTimeout(resolver.timeout) this.resolvers.delete(incoming.code) if (error) { @@ -162,7 +160,10 @@ export class BoundProtocol { resolve: null, reject: null, } - if (isTruthy(this.resolvers.get(message.response!))) { + if ( + typeof message.response === 'number' && + this.resolvers.get(message.response) !== undefined + ) { throw new Error(`Only one active request allowed per message type (${name})`) } this.resolvers.set(message.response!, resolver) diff --git a/packages/client/lib/util/rpc.ts b/packages/client/lib/util/rpc.ts index 96fadfcc7c..a2532e3cd7 100644 --- a/packages/client/lib/util/rpc.ts +++ b/packages/client/lib/util/rpc.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { json as jsonParser } from 'body-parser' import * as Connect from 'connect' import * as cors from 'cors' @@ -47,7 +46,7 @@ export function inspectParams(params: any, shorten?: number) { colors: true, maxStringLength: 100, } as any) - if (isTruthy(shorten)) { + if (typeof shorten === 'number') { inspected = inspected.replace(/\n/g, '').replace(/ {2}/g, ' ') if (inspected.length > shorten) { inspected = inspected.slice(0, shorten) + '...' @@ -78,10 +77,10 @@ export function createRPCServer( msg = `${request.method}${batchAddOn} responded with:\n${inspectParams(response)}` } else { msg = `${request.method}${batchAddOn} responded with: ` - if (isTruthy(response.result)) { + if (response.result !== undefined) { msg += inspectParams(response, 125) } - if (isTruthy(response.error)) { + if (response.error !== undefined) { msg += `error: ${response.error.message}` } } @@ -131,7 +130,7 @@ export function createRPCServer( ] const ethEngineSubsetMethods: { [key: string]: Function } = {} for (const method of ethMethodsToBeIncluded) { - if (isTruthy(ethMethods[method])) ethEngineSubsetMethods[method] = ethMethods[method] + if (ethMethods[method] !== undefined) ethEngineSubsetMethods[method] = ethMethods[method] } methods = { ...ethEngineSubsetMethods, ...manager.getMethods(true) } break @@ -161,7 +160,7 @@ export function createRPCServerListener(opts: CreateRPCServerListenerOpts): Http const { server, withEngineMiddleware, rpcCors } = opts const app = Connect() - if (isTruthy(rpcCors)) app.use(cors({ origin: rpcCors })) + if (typeof rpcCors === 'string') app.use(cors({ origin: rpcCors })) // GOSSIP_MAX_SIZE_BELLATRIX is proposed to be 10MiB app.use(jsonParser({ limit: '11mb' })) @@ -197,7 +196,7 @@ export function createWsRPCServerListener(opts: CreateWSServerOpts): HttpServer const app = Connect() // In case browser pre-flights the upgrade request with an options request // more likely in case of wss connection - if (isTruthy(rpcCors)) app.use(cors({ origin: rpcCors })) + if (typeof rpcCors === 'string') app.use(cors({ origin: rpcCors })) httpServer = createServer(app) } diff --git a/packages/client/test/util/rpc.spec.ts b/packages/client/test/util/rpc.spec.ts index 467a9fc9d4..bde2a0dda4 100644 --- a/packages/client/test/util/rpc.spec.ts +++ b/packages/client/test/util/rpc.spec.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { EthereumClient } from '../../lib/client' @@ -43,7 +42,10 @@ tape('[Util/RPC]', (t) => { server.emit('response', req, []) // empty server.emit('response', [req], respBulk) // mismatch length - st.ok(isTruthy(httpServer) && isTruthy(wsServer), 'should return http and ws servers') + st.ok( + httpServer !== undefined && wsServer !== undefined, + 'should return http and ws servers' + ) } } st.end() From 2fdde0d4b6a4f65ba9a09e1a057aa842467a0e1c Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 15:32:20 -0400 Subject: [PATCH 37/56] client: remove more isTruthy/isFalsy instances --- packages/client/browser/util/index.ts | 3 +-- packages/client/lib/net/server/rlpxserver.ts | 15 ++++++------ packages/client/lib/rpc/validation.ts | 24 +++++++++---------- .../client/lib/service/fullethereumservice.ts | 5 ++-- packages/client/lib/util/index.ts | 3 +-- 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/packages/client/browser/util/index.ts b/packages/client/browser/util/index.ts index 0f7ef41959..dac3e915d1 100644 --- a/packages/client/browser/util/index.ts +++ b/packages/client/browser/util/index.ts @@ -1,7 +1,6 @@ /** * @module util */ -import { isFalsy } from '@ethereumjs/util' import { platform } from 'os' import { version as packageVersion } from '../../package.json' @@ -9,7 +8,7 @@ import { version as packageVersion } from '../../package.json' export * from '../../lib/util/parse' export function short(buf: Buffer | string): string { - if (isFalsy(buf)) return '' + if (buf === null || buf === undefined || buf === '') return '' const bufStr = Buffer.isBuffer(buf) ? `0x${buf.toString('hex')}` : buf let str = bufStr.substring(0, 6) + '…' if (bufStr.length === 66) { diff --git a/packages/client/lib/net/server/rlpxserver.ts b/packages/client/lib/net/server/rlpxserver.ts index 2776be4540..9c096f3a33 100644 --- a/packages/client/lib/net/server/rlpxserver.ts +++ b/packages/client/lib/net/server/rlpxserver.ts @@ -1,5 +1,4 @@ import { DPT as Devp2pDPT, RLPx as Devp2pRLPx } from '@ethereumjs/devp2p' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { Event } from '../../types' import { RlpxPeer } from '../peer/rlpxpeer' @@ -90,7 +89,7 @@ export class RlpxServer extends Server { */ getRlpxInfo() { // TODO: return undefined? note that this.rlpx might be undefined if called before initRlpx - if (isFalsy(this.rlpx)) { + if (this.rlpx === undefined || this.rlpx === null) { return { enode: undefined, id: undefined, @@ -222,7 +221,7 @@ export class RlpxServer extends Server { resolve() }) - if (isTruthy(this.config.port)) { + if (typeof this.config.port === 'number') { this.dpt.bind(this.config.port, '0.0.0.0') } }) @@ -251,7 +250,7 @@ export class RlpxServer extends Server { protocols: Array.from(this.protocols), // @ts-ignore: Property 'server' does not exist on type 'Socket'. // TODO: check this error - inbound: isTruthy(rlpxPeer._socket?.server), + inbound: rlpxPeer._socket.server !== undefined, }) try { await peer.accept(rlpxPeer, this) @@ -275,9 +274,9 @@ export class RlpxServer extends Server { } }) - this.rlpx.on('peer:error', (rlpxPeer: any, error: Error) => { - const peerId = isTruthy(rlpxPeer) && rlpxPeer.getId() - if (isFalsy(peerId)) { + this.rlpx.on('peer:error', (rlpxPeer: Devp2pRLPxPeer, error: Error) => { + const peerId = rlpxPeer.getId() + if (peerId === null) { return this.error(error) } this.error(error) @@ -293,7 +292,7 @@ export class RlpxServer extends Server { resolve() }) - if (isTruthy(this.config.port)) { + if (typeof this.config.port === 'number') { this.rlpx.listen(this.config.port, '0.0.0.0') } }) diff --git a/packages/client/lib/rpc/validation.ts b/packages/client/lib/rpc/validation.ts index eb29816944..d0483b0f6c 100644 --- a/packages/client/lib/rpc/validation.ts +++ b/packages/client/lib/rpc/validation.ts @@ -1,5 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' - import { INVALID_PARAMS } from './error-code' /** @@ -21,10 +19,10 @@ export function middleware(method: any, requiredParamsCount: number, validators: } for (let i = 0; i < validators.length; i++) { - if (isTruthy(validators[i])) { + if (validators[i] !== undefined) { for (let j = 0; j < validators[i].length; j++) { const error = validators[i][j](params, i) - if (isTruthy(error)) { + if (error !== undefined) { return reject(error) } } @@ -198,7 +196,7 @@ export const validators = { const tx = params[index] for (const field of requiredFields) { - if (isFalsy(tx[field])) { + if (tx[field] === undefined) { return { code: INVALID_PARAMS, message: `invalid argument ${index}: required field ${field}`, @@ -207,21 +205,21 @@ export const validators = { } const validate = (field: any, validator: Function) => { - if (isFalsy(field)) return + if (field === undefined) return const v = validator([field], 0) - if (isTruthy(v)) return v + if (v !== undefined) return v } // validate addresses for (const field of [tx.to, tx.from]) { const v = validate(field, this.address) - if (isTruthy(v)) return v + if (v !== undefined) return v } // validate hex for (const field of [tx.gas, tx.gasPrice, tx.value, tx.data]) { const v = validate(field, this.hex) - if (isTruthy(v)) return v + if (v !== undefined) return v } } } @@ -247,7 +245,7 @@ export const validators = { for (const [key, validator] of Object.entries(form)) { const value = params[index][key] const result = validator([value], 0) - if (isTruthy(result)) { + if (result !== undefined) { // add key to message for context const originalMessage = result.message.split(':') const message = `invalid argument ${index} for key '${key}':${originalMessage[1]}` @@ -277,7 +275,7 @@ export const validators = { } for (const value of params[index]) { const result = validator([value], 0) - if (isTruthy(result)) return result + if (result !== undefined) return result } } } @@ -314,7 +312,7 @@ export const validators = { get optional() { return (validator: any) => { return (params: any, index: number) => { - if (isFalsy(params[index])) { + if (params[index] === undefined || params[index] === '') { return } return validator(params, index) @@ -332,7 +330,7 @@ export const validators = { get either() { return (...validators: any) => { return (params: any, index: number) => { - if (isFalsy(params[index])) { + if (params[index] === undefined) { return } const results = validators.map((v: any) => v(params, index)) diff --git a/packages/client/lib/service/fullethereumservice.ts b/packages/client/lib/service/fullethereumservice.ts index 5fe50b5a47..9fe828a5df 100644 --- a/packages/client/lib/service/fullethereumservice.ts +++ b/packages/client/lib/service/fullethereumservice.ts @@ -231,8 +231,9 @@ export class FullEthereumService extends EthereumService { const { reqId, block, max, skip, reverse } = message.data if (typeof block === 'bigint') { if ( - (isTruthy(reverse) && block > this.chain.headers.height) || - (isFalsy(reverse) && block + BigInt(max * skip) > this.chain.headers.height) + (reverse === true && block > this.chain.headers.height) || + ((reverse === false || reverse === undefined) && + block + BigInt(max * skip) > this.chain.headers.height) ) { // Respond with an empty list in case the header is higher than the current height // This is to ensure Geth does not disconnect with "useless peer" diff --git a/packages/client/lib/util/index.ts b/packages/client/lib/util/index.ts index d458f018ce..f537c87f49 100644 --- a/packages/client/lib/util/index.ts +++ b/packages/client/lib/util/index.ts @@ -1,7 +1,6 @@ /** * @module util */ -import { isFalsy } from '@ethereumjs/util' import { platform } from 'os' import { version as packageVersion } from '../../package.json' @@ -10,7 +9,7 @@ export * from './parse' export * from './rpc' export function short(buf: Buffer | string): string { - if (isFalsy(buf)) return '' + if (buf === null || buf === undefined || buf === '') return '' const bufStr = Buffer.isBuffer(buf) ? `0x${buf.toString('hex')}` : buf let str = bufStr.substring(0, 6) + '…' if (bufStr.length === 66) { From cdd34788f63dad274da1ca7af76241430b715a68 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 15:57:06 -0400 Subject: [PATCH 38/56] client: fix optional validation if --- packages/client/lib/rpc/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/lib/rpc/validation.ts b/packages/client/lib/rpc/validation.ts index d0483b0f6c..867341ba20 100644 --- a/packages/client/lib/rpc/validation.ts +++ b/packages/client/lib/rpc/validation.ts @@ -312,7 +312,7 @@ export const validators = { get optional() { return (validator: any) => { return (params: any, index: number) => { - if (params[index] === undefined || params[index] === '') { + if (params[index] === undefined || params[index] === '' || params[index] === null) { return } return validator(params, index) From 2b29c047525cca4970ffe99eafe8a8dc4221b1c1 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 15:57:14 -0400 Subject: [PATCH 39/56] client: remove more isTruthy/isFalsy instances --- packages/client/lib/rpc/modules/engine.ts | 19 ++++++++++--------- .../client/lib/service/fullethereumservice.ts | 10 ++++------ packages/client/lib/service/txpool.ts | 19 ++++++++++++------- packages/client/lib/sync/beaconsync.ts | 16 +++++++++------- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/packages/client/lib/rpc/modules/engine.ts b/packages/client/lib/rpc/modules/engine.ts index a2153c3545..eee1b6b07c 100644 --- a/packages/client/lib/rpc/modules/engine.ts +++ b/packages/client/lib/rpc/modules/engine.ts @@ -3,7 +3,7 @@ import { Hardfork } from '@ethereumjs/common' import { RLP } from '@ethereumjs/rlp' import { Trie } from '@ethereumjs/trie' import { TransactionFactory } from '@ethereumjs/tx' -import { bufferToHex, isFalsy, isTruthy, toBuffer, zeros } from '@ethereumjs/util' +import { bufferToHex, toBuffer, zeros } from '@ethereumjs/util' import { PendingBlock } from '../../miner' import { short } from '../../util' @@ -275,7 +275,7 @@ export class Engine { this.service = client.services.find((s) => s.name === 'eth') as FullEthereumService this.chain = this.service.chain this.config = this.chain.config - if (isFalsy(this.service.execution)) { + if (this.service.execution === undefined) { throw Error('execution required for engine module') } this.execution = this.service.execution @@ -378,7 +378,7 @@ export class Engine { const blockExists = await validBlock(toBuffer(blockHash), this.chain) if (blockExists) { const isBlockExecuted = await this.vm.stateManager.hasStateRoot(blockExists.header.stateRoot) - if (isTruthy(isBlockExecuted)) { + if (isBlockExecuted) { const response = { status: Status.VALID, latestValidHash: blockHash, @@ -393,7 +393,7 @@ export class Engine { const parent = await this.chain.getBlock(toBuffer(parentHash)) const isBlockExecuted = await this.vm.stateManager.hasStateRoot(parent.header.stateRoot) // If the parent is not executed throw an error, it will be caught and return SYNCING or ACCEPTED. - if (isFalsy(isBlockExecuted)) { + if (isBlockExecuted) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } if (!parent._common.gteHardfork(Hardfork.Merge)) { @@ -491,14 +491,14 @@ export class Engine { /* * Process head block */ - let headBlock: Block + let headBlock: Block | undefined try { headBlock = await this.chain.getBlock(toBuffer(headBlockHash)) } catch (error) { headBlock = (await this.service.beaconSync?.skeleton.getBlockByHash(toBuffer(headBlockHash))) ?? - (this.remoteBlocks.get(headBlockHash.slice(2)) as Block) - if (isFalsy(headBlock)) { + this.remoteBlocks.get(headBlockHash.slice(2)) + if (headBlock === undefined) { this.config.logger.debug(`Forkchoice requested unknown head hash=${short(headBlockHash)}`) const payloadStatus = { status: Status.SYNCING, @@ -551,7 +551,7 @@ export class Engine { try { const parent = await this.chain.getBlock(toBuffer(headBlock.header.parentHash)) const isBlockExecuted = await this.vm.stateManager.hasStateRoot(parent.header.stateRoot) - if (isFalsy(isBlockExecuted)) { + if (isBlockExecuted) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } parentBlocks = await recursivelyFindParents( @@ -580,7 +580,8 @@ export class Engine { const timeDiff = new Date().getTime() / 1000 - Number(headBlock.header.timestamp) if ( - (isFalsy(this.config.syncTargetHeight) || + (typeof this.config.syncTargetHeight !== 'bigint' || + this.config.syncTargetHeight === BigInt(0) || this.config.syncTargetHeight < headBlock.header.number) && timeDiff < 30 ) { diff --git a/packages/client/lib/service/fullethereumservice.ts b/packages/client/lib/service/fullethereumservice.ts index 9fe828a5df..bf6f3fb0aa 100644 --- a/packages/client/lib/service/fullethereumservice.ts +++ b/packages/client/lib/service/fullethereumservice.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { encodeReceipt } from '@ethereumjs/vm/dist/runBlock' import { VMExecution } from '../execution' @@ -232,8 +231,7 @@ export class FullEthereumService extends EthereumService { if (typeof block === 'bigint') { if ( (reverse === true && block > this.chain.headers.height) || - ((reverse === false || reverse === undefined) && - block + BigInt(max * skip) > this.chain.headers.height) + (reverse !== true && block + BigInt(max * skip) > this.chain.headers.height) ) { // Respond with an empty list in case the header is higher than the current height // This is to ensure Geth does not disconnect with "useless peer" @@ -287,7 +285,7 @@ export class FullEthereumService extends EthereumService { let receiptsSize = 0 for (const hash of hashes) { const blockReceipts = await receiptsManager.getReceipts(hash, true, true) - if (isFalsy(blockReceipts)) continue + if (blockReceipts === undefined) continue receipts.push(...blockReceipts) const receiptsBuffer = Buffer.concat(receipts.map((r) => encodeReceipt(r, r.txType))) receiptsSize += Buffer.byteLength(receiptsBuffer) @@ -315,8 +313,8 @@ export class FullEthereumService extends EthereumService { } else { if (typeof block === 'bigint') { if ( - (isTruthy(reverse) && block > this.chain.headers.height) || - (isFalsy(reverse) && block + BigInt(max * skip) > this.chain.headers.height) + (reverse === true && block > this.chain.headers.height) || + (reverse !== true && block + BigInt(max * skip) > this.chain.headers.height) ) { // Don't respond to requests greater than the current height return diff --git a/packages/client/lib/service/txpool.ts b/packages/client/lib/service/txpool.ts index b15746c403..07c0f630e5 100644 --- a/packages/client/lib/service/txpool.ts +++ b/packages/client/lib/service/txpool.ts @@ -1,5 +1,5 @@ import { Capability } from '@ethereumjs/tx' -import { Address, bufferToHex, isFalsy, isTruthy } from '@ethereumjs/util' +import { Address, bufferToHex } from '@ethereumjs/util' import Heap = require('qheap') import type { Config } from '../config' @@ -194,7 +194,12 @@ export class TxPool { * Checks if tx pool should be started */ checkRunState() { - if (this.running || isFalsy(this.config.syncTargetHeight)) return + if ( + this.running || + typeof this.config.syncTargetHeight !== 'bigint' || + this.config.syncTargetHeight === BigInt(0) + ) + return // If height gte target, we are close enough to the // head of the chain that the tx pool can be started const target = @@ -265,7 +270,7 @@ export class TxPool { } } const block = await this.service.chain.getCanonicalHeadHeader() - if (isTruthy(block.baseFeePerGas)) { + if (typeof block.baseFeePerGas === 'bigint' && block.baseFeePerGas !== BigInt(0)) { if (currentGasPrice.maxFee < block.baseFeePerGas / BigInt(2) && !isLocalTransaction) { throw new Error( `Tx cannot pay basefee of ${block.baseFeePerGas}, have ${currentGasPrice.maxFee} (not within 50% range of current basefee)` @@ -496,14 +501,14 @@ export class TxPool { this.config.logger.debug( `TxPool: requesting txs number=${reqHashes.length} pending=${this.pending.length}` ) - const getPooledTxs = await peer.eth!.getPooledTransactions({ + const getPooledTxs = await peer.eth?.getPooledTransactions({ hashes: reqHashes.slice(0, this.TX_RETRIEVAL_LIMIT), }) // Remove from pending list regardless if tx is in result this.pending = this.pending.filter((hash) => !reqHashesStr.includes(hash)) - if (isFalsy(getPooledTxs)) { + if (getPooledTxs === undefined) { return } const [_, txs] = getPooledTxs @@ -576,7 +581,7 @@ export class TxPool { */ private normalizedGasPrice(tx: TypedTransaction, baseFee?: bigint) { const supports1559 = tx.supports(Capability.EIP1559FeeMarket) - if (isTruthy(baseFee)) { + if (typeof baseFee === 'bigint' && baseFee !== BigInt(0)) { if (supports1559) { return (tx as FeeMarketEIP1559Transaction).maxPriorityFeePerGas } else { @@ -648,7 +653,7 @@ export class TxPool { // therefore no txs from this address are currently executable continue } - if (isTruthy(baseFee)) { + if (typeof baseFee === 'bigint' && baseFee !== BigInt(0)) { // If any tx has an insufficient gasPrice, // remove all txs after that since they cannot be executed const found = txsSortedByNonce.findIndex((tx) => this.normalizedGasPrice(tx) < baseFee) diff --git a/packages/client/lib/sync/beaconsync.ts b/packages/client/lib/sync/beaconsync.ts index 4e55790494..a97a0d8f49 100644 --- a/packages/client/lib/sync/beaconsync.ts +++ b/packages/client/lib/sync/beaconsync.ts @@ -1,5 +1,3 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' - import { Event } from '../types' import { short } from '../util' @@ -72,7 +70,7 @@ export class BeaconSynchronizer extends Synchronizer { this.config.events.on(Event.CHAIN_UPDATED, this.runExecution) const subchain = this.skeleton.bounds() - if (isTruthy(subchain)) { + if (subchain !== undefined) { const { head, tail, next } = subchain this.config.logger.info(`Resuming beacon sync head=${head} tail=${tail} next=${short(next)}`) } @@ -214,7 +212,7 @@ export class BeaconSynchronizer extends Synchronizer { * @return Resolves when sync completed */ async syncWithPeer(peer?: Peer): Promise { - if (!isTruthy(this.skeleton.bounds()) || (await this.skeleton.isLinked())) { + if (this.skeleton.bounds() === undefined || (await this.skeleton.isLinked())) { this.clearFetcher() return false } @@ -223,7 +221,11 @@ export class BeaconSynchronizer extends Synchronizer { if (!latest) return false const height = latest.number - if (isFalsy(this.config.syncTargetHeight) || this.config.syncTargetHeight < latest.number) { + if ( + typeof this.config.syncTargetHeight !== 'bigint' || + this.config.syncTargetHeight === BigInt(0) || + this.config.syncTargetHeight < latest.number + ) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } @@ -241,7 +243,7 @@ export class BeaconSynchronizer extends Synchronizer { count = tail - this.chain.blocks.height - BigInt(1) } - if (count > BigInt(0) && (!isTruthy(this.fetcher) || isTruthy(this.fetcher.errored))) { + if (count > BigInt(0) && (this.fetcher === null || this.fetcher.errored !== undefined)) { this.config.logger.debug( `syncWithPeer - new ReverseBlockFetcher peer=${peer?.id} subChainTail=${tail} first=${first} count=${count} chainHeight=${this.chain.blocks.height} ` ) @@ -284,7 +286,7 @@ export class BeaconSynchronizer extends Synchronizer { // Execute single block when within 50 blocks of head if skeleton not filling, // otherwise run execution in batch of 50 blocks when filling canonical chain. const shouldRunOnlyBatched = !( - isTruthy(this.skeleton.bounds()) && + this.skeleton.bounds() !== undefined && this.chain.blocks.height > this.skeleton.bounds().head - BigInt(50) ) if (!shouldRunOnlyBatched || this.chain.blocks.height % BigInt(50) === BigInt(0)) { From e2cd9aaf21f78e5c8fd7edf379b8c8249fc38e3e Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 16:26:31 -0400 Subject: [PATCH 40/56] client: remove more isTruthy/isFalsy instances --- .../client/lib/net/protocol/flowcontrol.ts | 11 +++-- .../client/lib/net/protocol/lesprotocol.ts | 26 ++++++------ packages/client/lib/net/protocol/protocol.ts | 6 +-- packages/client/lib/util/parse.ts | 41 +++++++++---------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/packages/client/lib/net/protocol/flowcontrol.ts b/packages/client/lib/net/protocol/flowcontrol.ts index 134e7b183a..78d9e45602 100644 --- a/packages/client/lib/net/protocol/flowcontrol.ts +++ b/packages/client/lib/net/protocol/flowcontrol.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import type { Peer } from '../peer/peer' interface Mrc { @@ -68,7 +66,7 @@ export class FlowControl { const mrr = peer.les!.status.mrr const bl = peer.les!.status.bl const params = this.in.get(peer.id) ?? ({ ble: bl } as FlowParams) - if (isTruthy(params.last)) { + if (typeof params.last === 'number' && params.last !== 0) { // recharge BLE at rate of MRR when less than BL params.ble = Math.min(params.ble! + mrr * (now - params.last), bl) } @@ -90,7 +88,12 @@ export class FlowControl { handleRequest(peer: Peer, messageName: string, count: number): number { const now = Date.now() const params = this.out.get(peer.id) ?? {} - if (isTruthy(params.bv) && isTruthy(params.last)) { + if ( + typeof params.bv === 'number' && + params.bv !== 0 && + typeof params.last === 'number' && + params.last !== 0 + ) { params.bv = Math.min(params.bv + this.mrr * (now - params.last), this.bl) } else { params.bv = this.bl diff --git a/packages/client/lib/net/protocol/lesprotocol.ts b/packages/client/lib/net/protocol/lesprotocol.ts index 75da1d9ec7..daae3edcfb 100644 --- a/packages/client/lib/net/protocol/lesprotocol.ts +++ b/packages/client/lib/net/protocol/lesprotocol.ts @@ -1,11 +1,5 @@ import { BlockHeader } from '@ethereumjs/block' -import { - bigIntToBuffer, - bufferToBigInt, - bufferToInt, - intToBuffer, - isTruthy, -} from '@ethereumjs/util' +import { bigIntToBuffer, bufferToBigInt, bufferToInt, intToBuffer } from '@ethereumjs/util' import { Protocol } from './protocol' @@ -184,7 +178,9 @@ export class LesProtocol extends Protocol { const nextFork = this.config.chainCommon.nextHardforkBlock(this.config.chainCommon.hardfork()) const forkID = [ Buffer.from(forkHash.slice(2), 'hex'), - isTruthy(nextFork) ? bigIntToBuffer(nextFork) : Buffer.from([]), + typeof nextFork === 'bigint' && nextFork !== BigInt(0) + ? bigIntToBuffer(nextFork) + : Buffer.from([]), ] return { @@ -204,9 +200,9 @@ export class LesProtocol extends Protocol { * @param status status message payload */ decodeStatus(status: any): any { - this.isServer = isTruthy(status.serveHeaders) + this.isServer = status.serveHeaders !== undefined && status.serveHeaders !== false const mrc: any = {} - if (isTruthy(status['flowControl/MRC'])) { + if (status['flowControl/MRC'] !== undefined) { for (let entry of status['flowControl/MRC']) { entry = entry.map((e: any) => bufferToInt(e)) mrc[entry[0]] = { base: entry[1], req: entry[2] } @@ -227,9 +223,13 @@ export class LesProtocol extends Protocol { serveHeaders: this.isServer, serveChainSince: status.serveChainSince ?? 0, serveStateSince: status.serveStateSince ?? 0, - txRelay: isTruthy(status.txRelay), - bl: isTruthy(status['flowControl/BL']) ? bufferToInt(status['flowControl/BL']) : undefined, - mrr: isTruthy(status['flowControl/MRR']) ? bufferToInt(status['flowControl/MRR']) : undefined, + txRelay: status.txRelay === true, + bl: + status['flowControl/BL'] !== undefined ? bufferToInt(status['flowControl/BL']) : undefined, + mrr: + status['flowControl/MRR'] !== undefined + ? bufferToInt(status['flowControl/MRR']) + : undefined, mrc, } } diff --git a/packages/client/lib/net/protocol/protocol.ts b/packages/client/lib/net/protocol/protocol.ts index 2e10bfbf02..fe7083f7ec 100644 --- a/packages/client/lib/net/protocol/protocol.ts +++ b/packages/client/lib/net/protocol/protocol.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { BoundProtocol } from './boundprotocol' import type { Config } from '../../config' @@ -74,12 +72,12 @@ export class Protocol { reject(new Error(`Handshake timed out after ${this.timeout}ms`)) }, this.timeout) const handleStatus = (status: any) => { - if (isTruthy(timeout)) { + if (timeout !== null && timeout !== 0) { clearTimeout(timeout) resolve(this.decodeStatus(status)) } } - if (isTruthy(sender.status)) { + if (sender.status !== undefined) { handleStatus(sender.status) } else { sender.once('status', handleStatus) diff --git a/packages/client/lib/util/parse.ts b/packages/client/lib/util/parse.ts index 8ff39fe411..961de9d308 100644 --- a/packages/client/lib/util/parse.ts +++ b/packages/client/lib/util/parse.ts @@ -3,9 +3,7 @@ import { addHexPrefix, bigIntToHex, intToHex, - isFalsy, isHexPrefixed, - isTruthy, stripHexPrefix, } from '@ethereumjs/util' import { Multiaddr, multiaddr } from 'multiaddr' @@ -20,7 +18,7 @@ import type { Common } from '@ethereumjs/common' * @param input comma separated string */ export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] { - if (isFalsy(input)) { + if (input === '') { return [] } if (!Array.isArray(input) && typeof input === 'object') { @@ -46,7 +44,7 @@ export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] { // parse as object if (typeof s === 'object') { const { ip, port } = s as any - if (isTruthy(ip) && isTruthy(port)) { + if (ip !== undefined && port !== undefined) { return multiaddr(`/ip4/${ip}/tcp/${port}`) } } @@ -143,20 +141,21 @@ async function parseGethParams(json: any) { baseFeePerGas, }, bootstrapNodes: [], - consensus: isTruthy(config.clique) - ? { - type: 'poa', - algorithm: 'clique', - clique: { - period: config.clique.period, - epoch: config.clique.epoch, + consensus: + config.clique !== undefined + ? { + type: 'poa', + algorithm: 'clique', + clique: { + period: config.clique.period, + epoch: config.clique.epoch, + }, + } + : { + type: 'pow', + algorithm: 'ethash', + ethash: {}, }, - } - : { - type: 'pow', - algorithm: 'ethash', - ethash: {}, - }, } const forkMap: { [key: string]: string } = { @@ -200,7 +199,7 @@ export async function parseCustomParams(json: any, name?: string) { if (['config', 'difficulty', 'gasLimit', 'alloc'].some((field) => !(field in json))) { throw new Error('Invalid format, expected geth genesis fields missing') } - if (isTruthy(name)) { + if (name !== undefined) { json.name = name } return parseGethParams(json) @@ -219,8 +218,8 @@ export async function parseGenesisState(json: any) { let { balance, code, storage } = json.alloc[address] address = addHexPrefix(address) balance = isHexPrefixed(balance) ? balance : bigIntToHex(BigInt(balance)) - code = isTruthy(code) ? addHexPrefix(code) : undefined - storage = isTruthy(storage) ? Object.entries(storage) : undefined + code = code !== undefined ? addHexPrefix(code) : undefined + storage = storage !== undefined ? Object.entries(storage) : undefined state[address] = [balance, code, storage] as any } return state @@ -245,7 +244,7 @@ export function parseKey(input: string | Buffer) { export function setCommonForkHashes(common: Common, genesisHash: Buffer) { for (const hf of (common as any)._chainParams.hardforks) { if ( - isFalsy(hf.forkHash) && + (hf.forkHash === null || hf.forkhash === undefined) && typeof hf.block !== 'undefined' && (hf.block !== null || typeof hf.td !== 'undefined') ) { From a3b59fb2b5496ea26cd42baadda7643ee4d6612e Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 17:25:23 -0400 Subject: [PATCH 41/56] client: remove remaining instances of isTruthy/isFalsy --- packages/client/lib/net/protocol/protocol.ts | 2 +- .../client/lib/net/server/libp2pserver.ts | 3 +- packages/client/lib/net/server/server.ts | 6 ++-- packages/client/lib/rpc/modules/engine.ts | 4 +-- .../lib/rpc/util/CLConnectionManager.ts | 3 +- .../client/lib/sync/fetcher/blockfetcher.ts | 12 +++++--- packages/client/lib/sync/fetcher/fetcher.ts | 3 +- packages/client/lib/sync/fullsync.ts | 30 ++++++++++++++----- packages/client/lib/sync/lightsync.ts | 7 +++-- packages/client/lib/sync/sync.ts | 5 ++-- .../client/test/integration/merge.spec.ts | 10 +++++-- .../test/integration/mocks/mockserver.ts | 6 ++-- packages/client/test/logging.spec.ts | 3 +- .../client/test/rpc/admin/nodeInfo.spec.ts | 3 +- packages/client/test/rpc/helpers.ts | 21 ++++++------- packages/client/test/rpc/rpc.spec.ts | 3 +- packages/client/test/rpc/util.ts | 6 ++-- packages/client/test/sync/txpool.spec.ts | 6 ++-- 18 files changed, 74 insertions(+), 59 deletions(-) diff --git a/packages/client/lib/net/protocol/protocol.ts b/packages/client/lib/net/protocol/protocol.ts index fe7083f7ec..14cd9808f5 100644 --- a/packages/client/lib/net/protocol/protocol.ts +++ b/packages/client/lib/net/protocol/protocol.ts @@ -77,7 +77,7 @@ export class Protocol { resolve(this.decodeStatus(status)) } } - if (sender.status !== undefined) { + if (sender.status !== undefined && sender.status !== null) { handleStatus(sender.status) } else { sender.once('status', handleStatus) diff --git a/packages/client/lib/net/server/libp2pserver.ts b/packages/client/lib/net/server/libp2pserver.ts index 68b3741fb4..fb36c8dfab 100644 --- a/packages/client/lib/net/server/libp2pserver.ts +++ b/packages/client/lib/net/server/libp2pserver.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' // eslint-disable-next-line implicit-dependencies/no-implicit, import/no-extraneous-dependencies import { keys } from 'libp2p-crypto' import { multiaddr } from 'multiaddr' @@ -142,7 +141,7 @@ export class Libp2pServer extends Server { */ isBanned(peerId: string): boolean { const expireTime = this.banned.get(peerId) - if (isTruthy(expireTime) && expireTime > Date.now()) { + if (typeof expireTime === 'number' && expireTime !== 0 && expireTime > Date.now()) { return true } this.banned.delete(peerId) diff --git a/packages/client/lib/net/server/server.ts b/packages/client/lib/net/server/server.ts index 6a4f2059a6..a745674ab7 100644 --- a/packages/client/lib/net/server/server.ts +++ b/packages/client/lib/net/server/server.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { parseKey, parseMultiaddrs } from '../../util/parse' import type { Config } from '../../config' @@ -44,8 +42,8 @@ export class Server { */ constructor(options: ServerOptions) { this.config = options.config - this.key = isTruthy(options.key) ? parseKey(options.key) : this.config.key - this.bootnodes = isTruthy(options.bootnodes) ? parseMultiaddrs(options.bootnodes) : [] + this.key = options.key !== undefined ? parseKey(options.key) : this.config.key + this.bootnodes = options.bootnodes !== undefined ? parseMultiaddrs(options.bootnodes) : [] this.dnsNetworks = options.dnsNetworks ?? [] this.refreshInterval = options.refreshInterval ?? 30000 diff --git a/packages/client/lib/rpc/modules/engine.ts b/packages/client/lib/rpc/modules/engine.ts index eee1b6b07c..3b671d0e1c 100644 --- a/packages/client/lib/rpc/modules/engine.ts +++ b/packages/client/lib/rpc/modules/engine.ts @@ -393,7 +393,7 @@ export class Engine { const parent = await this.chain.getBlock(toBuffer(parentHash)) const isBlockExecuted = await this.vm.stateManager.hasStateRoot(parent.header.stateRoot) // If the parent is not executed throw an error, it will be caught and return SYNCING or ACCEPTED. - if (isBlockExecuted) { + if (!isBlockExecuted) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } if (!parent._common.gteHardfork(Hardfork.Merge)) { @@ -551,7 +551,7 @@ export class Engine { try { const parent = await this.chain.getBlock(toBuffer(headBlock.header.parentHash)) const isBlockExecuted = await this.vm.stateManager.hasStateRoot(parent.header.stateRoot) - if (isBlockExecuted) { + if (!isBlockExecuted) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } parentBlocks = await recursivelyFindParents( diff --git a/packages/client/lib/rpc/util/CLConnectionManager.ts b/packages/client/lib/rpc/util/CLConnectionManager.ts index 323b955fef..67aa388c1f 100644 --- a/packages/client/lib/rpc/util/CLConnectionManager.ts +++ b/packages/client/lib/rpc/util/CLConnectionManager.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isTruthy } from '@ethereumjs/util' import { Event } from '../../types' import { short, timeDiff } from '../../util' @@ -152,7 +151,7 @@ export class CLConnectionManager { if (update.headBlock) { msg += ` timestampDiff=${this.timeDiffStr(update.headBlock)}` } - if (isTruthy(update.error)) { + if (update.error !== undefined) { msg += ` error=${update.error}` } return msg diff --git a/packages/client/lib/sync/fetcher/blockfetcher.ts b/packages/client/lib/sync/fetcher/blockfetcher.ts index 8c277859b9..135183f923 100644 --- a/packages/client/lib/sync/fetcher/blockfetcher.ts +++ b/packages/client/lib/sync/fetcher/blockfetcher.ts @@ -1,5 +1,5 @@ import { Block } from '@ethereumjs/block' -import { KECCAK256_RLP, KECCAK256_RLP_ARRAY, isFalsy } from '@ethereumjs/util' +import { KECCAK256_RLP, KECCAK256_RLP_ARRAY } from '@ethereumjs/util' import { Event } from '../../types' @@ -45,14 +45,18 @@ export class BlockFetcher extends BlockFetcherBase { max: count, reverse: this.reverse, }) - if (isFalsy(headersResult) || headersResult[1].length === 0) { + if (!Array.isArray(headersResult) || headersResult[1].length === 0) { // Catch occasional null or empty responses this.debug(`Peer ${peerInfo} returned no headers for blocks=${blocksRange}`) return [] } const headers = headersResult[1] - const bodiesResult = await peer!.eth!.getBlockBodies({ hashes: headers.map((h) => h.hash()) }) - if (isFalsy(bodiesResult) || isFalsy(bodiesResult[1]) || bodiesResult[1].length === 0) { + const bodiesResult = await peer?.eth?.getBlockBodies({ hashes: headers.map((h) => h.hash()) }) + if ( + !Array.isArray(bodiesResult) || + !Array.isArray(bodiesResult[1]) || + bodiesResult[1].length === 0 + ) { // Catch occasional null or empty responses this.debug(`Peer ${peerInfo} returned no bodies for blocks=${blocksRange}`) return [] diff --git a/packages/client/lib/sync/fetcher/fetcher.ts b/packages/client/lib/sync/fetcher/fetcher.ts index 168a514c56..4bf99bab05 100644 --- a/packages/client/lib/sync/fetcher/fetcher.ts +++ b/packages/client/lib/sync/fetcher/fetcher.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import { debug as createDebugLogger } from 'debug' import Heap = require('qheap') import { Readable, Writable } from 'stream' @@ -544,6 +543,6 @@ export abstract class Fetcher extends Readable * @param task */ private isBlockFetcherJobTask(task: JobTask | BlockFetcherJobTask): task is BlockFetcherJobTask { - return isTruthy(task) && 'first' in task && 'count' in task + return task !== undefined && 'first' in task && 'count' in task } } diff --git a/packages/client/lib/sync/fullsync.ts b/packages/client/lib/sync/fullsync.ts index b54148930f..ab480185b9 100644 --- a/packages/client/lib/sync/fullsync.ts +++ b/packages/client/lib/sync/fullsync.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { Event } from '../types' import { short } from '../util' @@ -103,7 +102,7 @@ export class FullSynchronizer extends Synchronizer { const peers = this.pool.peers.filter(this.syncable.bind(this)) if (peers.length < this.config.minPeers && !this.forceSync) return for (const peer of peers) { - if (typeof peer.eth !== 'undefined' && isTruthy(peer.eth.status)) { + if (peer.eth?.status !== undefined) { const td = peer.eth.status.td if ( (!best && td >= this.chain.blocks.td) || @@ -131,7 +130,11 @@ export class FullSynchronizer extends Synchronizer { * Checks if tx pool should be started */ checkTxPoolState() { - if (isFalsy(this.config.syncTargetHeight) || this.txPool.running) { + if ( + this.config.syncTargetHeight === undefined || + this.config.syncTargetHeight === BigInt(0) || + this.txPool.running + ) { return } // If height gte target, we are close enough to the @@ -153,7 +156,11 @@ export class FullSynchronizer extends Synchronizer { if (!latest) return false const height = latest.number - if (isFalsy(this.config.syncTargetHeight) || this.config.syncTargetHeight < latest.number) { + if ( + this.config.syncTargetHeight === undefined || + this.config.syncTargetHeight === BigInt(0) || + this.config.syncTargetHeight < latest.number + ) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } @@ -249,7 +256,8 @@ export class FullSynchronizer extends Synchronizer { if (!this.running) return // Batch the execution if we are not close to the head const shouldRunOnlyBatched = - isTruthy(this.config.syncTargetHeight) && + typeof this.config.syncTargetHeight === 'bigint' && + this.config.syncTargetHeight !== BigInt(0) && this.chain.blocks.height <= this.config.syncTargetHeight - BigInt(50) await this.execution.run(true, shouldRunOnlyBatched) this.txPool.checkRunState() @@ -320,7 +328,11 @@ export class FullSynchronizer extends Synchronizer { await this.chain.putBlocks([block]) // Check if new sync target height can be set const blockNumber = block.header.number - if (isFalsy(this.config.syncTargetHeight) || blockNumber > this.config.syncTargetHeight) { + if ( + this.config.syncTargetHeight === undefined || + this.config.syncTargetHeight === BigInt(0) || + blockNumber > this.config.syncTargetHeight + ) { this.config.syncTargetHeight = blockNumber } } else { @@ -353,7 +365,11 @@ export class FullSynchronizer extends Synchronizer { } // Check if new sync target height can be set if (newSyncHeight && blockNumber <= newSyncHeight[1]) continue - if (isTruthy(this.config.syncTargetHeight) && blockNumber <= this.config.syncTargetHeight) + if ( + typeof this.config.syncTargetHeight === 'bigint' && + this.config.syncTargetHeight !== BigInt(0) && + blockNumber <= this.config.syncTargetHeight + ) continue newSyncHeight = value } diff --git a/packages/client/lib/sync/lightsync.ts b/packages/client/lib/sync/lightsync.ts index 3a0be29a29..d813fdf6a8 100644 --- a/packages/client/lib/sync/lightsync.ts +++ b/packages/client/lib/sync/lightsync.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isFalsy } from '@ethereumjs/util' import { Event } from '../types' import { short } from '../util' @@ -105,7 +104,11 @@ export class LightSynchronizer extends Synchronizer { if (!latest) return false const height = peer!.les!.status.headNum - if (isFalsy(this.config.syncTargetHeight) || this.config.syncTargetHeight < height) { + if ( + this.config.syncTargetHeight === undefined || + this.config.syncTargetHeight === BigInt(0) || + this.config.syncTargetHeight < height + ) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } diff --git a/packages/client/lib/sync/sync.ts b/packages/client/lib/sync/sync.ts index c95c147099..c46bcfaa3b 100644 --- a/packages/client/lib/sync/sync.ts +++ b/packages/client/lib/sync/sync.ts @@ -1,5 +1,4 @@ import { Hardfork } from '@ethereumjs/common' -import { isFalsy, isTruthy } from '@ethereumjs/util' import { FlowControl } from '../net/protocol' import { Event } from '../types' @@ -145,7 +144,7 @@ export abstract class Synchronizer { * @emits {@link Event.SYNC_SYNCHRONIZED} */ updateSynchronizedState() { - if (isFalsy(this.config.syncTargetHeight)) { + if (this.config.syncTargetHeight === undefined || this.config.syncTargetHeight === BigInt(0)) { return } if (this.chain.headers.height >= this.config.syncTargetHeight) { @@ -183,7 +182,7 @@ export abstract class Synchronizer { const resolveSync = (height?: number) => { this.clearFetcher() resolve(true) - const heightStr = isTruthy(height) ? ` height=${height}` : '' + const heightStr = typeof height === 'number' && height !== 0 ? ` height=${height}` : '' this.config.logger.info(`Finishing up sync with the current fetcher ${heightStr}`) } this.config.events.once(Event.SYNC_SYNCHRONIZED, resolveSync) diff --git a/packages/client/test/integration/merge.spec.ts b/packages/client/test/integration/merge.spec.ts index 1f3c921ccf..d8482245bd 100644 --- a/packages/client/test/integration/merge.spec.ts +++ b/packages/client/test/integration/merge.spec.ts @@ -7,7 +7,7 @@ import { ConsensusType, Hardfork, } from '@ethereumjs/common' -import { Address, isFalsy, isTruthy } from '@ethereumjs/util' +import { Address } from '@ethereumjs/util' import * as tape from 'tape' import { Chain } from '../../lib/blockchain' @@ -145,7 +145,7 @@ tape('[Integration:Merge]', async (t) => { remoteService.config.events.on(Event.CHAIN_UPDATED, async () => { const { height, td } = remoteService.chain.headers if (td > targetTTD) { - if (isFalsy(terminalHeight)) { + if (terminalHeight === undefined || terminalHeight === BigInt(0)) { terminalHeight = height } t.equal( @@ -159,7 +159,11 @@ tape('[Integration:Merge]', async (t) => { await destroy(remoteServer, remoteService) t.end() } - if (isTruthy(terminalHeight) && terminalHeight < height) { + if ( + typeof terminalHeight === 'bigint' && + terminalHeight !== BigInt(0) && + terminalHeight < height + ) { t.fail('chain should not exceed merge terminal block') } }) diff --git a/packages/client/test/integration/mocks/mockserver.ts b/packages/client/test/integration/mocks/mockserver.ts index 98f73f2e42..66f5966b59 100644 --- a/packages/client/test/integration/mocks/mockserver.ts +++ b/packages/client/test/integration/mocks/mockserver.ts @@ -1,5 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' - import { Server } from '../../../lib/net/server' import { Event } from '../../../lib/types' @@ -51,7 +49,7 @@ export class MockServer extends Server { // This wait is essential to clear out the pending setTimeout in the // createStream in ./network.ts await this.wait(20) - while (isTruthy(servers[this.location])) { + while (servers[this.location] !== undefined) { await destroyServer(this.location) } await super.stop() @@ -90,7 +88,7 @@ export class MockServer extends Server { disconnect(id: string) { const peer = this.peers[id] - if (isTruthy(peer)) this.config.events.emit(Event.PEER_DISCONNECTED, peer) + if (peer !== undefined) this.config.events.emit(Event.PEER_DISCONNECTED, peer) } async wait(delay?: number) { diff --git a/packages/client/test/logging.spec.ts b/packages/client/test/logging.spec.ts index a33da3951b..3363f5cc8e 100644 --- a/packages/client/test/logging.spec.ts +++ b/packages/client/test/logging.spec.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { getLogger } from '../lib/logging' @@ -25,7 +24,7 @@ tape('[Logging]', (t) => { }) t.test('should colorize key=value pairs', (st) => { - if (isTruthy(process.env.GITHUB_ACTION)) { + if (process.env.GITHUB_ACTION !== undefined) { st.skip('no color functionality in ci') return st.end() } diff --git a/packages/client/test/rpc/admin/nodeInfo.spec.ts b/packages/client/test/rpc/admin/nodeInfo.spec.ts index 2cd2bc5cda..46cf04bfaa 100644 --- a/packages/client/test/rpc/admin/nodeInfo.spec.ts +++ b/packages/client/test/rpc/admin/nodeInfo.spec.ts @@ -1,4 +1,3 @@ -import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { baseRequest, createClient, createManager, params, startRPC } from '../helpers' @@ -13,7 +12,7 @@ tape(method, async (t) => { const expectRes = (res: any) => { const { result } = res.body - if (isTruthy(result)) { + if (result !== undefined) { t.pass('admin_nodeInfo returns a value') } else { throw new Error('no return value') diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 01324faaef..2972aceb1c 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -1,7 +1,7 @@ import { BlockHeader } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain as ChainEnum, Common } from '@ethereumjs/common' -import { Address, isTruthy } from '@ethereumjs/util' +import { Address } from '@ethereumjs/util' import { Server as RPCServer } from 'jayson/promise' import { MemoryLevel } from 'memory-level' @@ -44,11 +44,12 @@ export function startRPC( ) { const { port, wsServer } = opts const server = new RPCServer(methods) - const httpServer = isTruthy(wsServer) - ? createWsRPCServerListener({ server, withEngineMiddleware }) - : createRPCServerListener({ server, withEngineMiddleware }) + const httpServer = + wsServer === true + ? createWsRPCServerListener({ server, withEngineMiddleware }) + : createRPCServerListener({ server, withEngineMiddleware }) if (!httpServer) throw Error('Could not create server') - if (isTruthy(port)) httpServer.listen(port) + if (port !== undefined) httpServer.listen(port) return httpServer } @@ -80,7 +81,7 @@ export function createClient(clientOpts: any = {}) { const clientConfig = { ...defaultClientConfig, ...clientOpts } chain.getTd = async (_hash: Buffer, _num: bigint) => BigInt(1000) - if (isTruthy(chain._headers)) { + if (chain._headers !== undefined) { chain._headers.latest = BlockHeader.fromHeaderData({}, { common }) } @@ -96,7 +97,7 @@ export function createClient(clientOpts: any = {}) { config.syncTargetHeight = clientOpts.syncTargetHeight - const synchronizer: any = { + const synchronizer = { startingBlock: 0, best: () => { return undefined @@ -107,8 +108,8 @@ export function createClient(clientOpts: any = {}) { } let execution - if (isTruthy(clientOpts.includeVM)) { - const metaDB: any = isTruthy(clientOpts.enableMetaDB) ? new MemoryLevel() : undefined + if (clientOpts.includeVM === true) { + const metaDB: any = clientOpts.enableMetaDB === true ? new MemoryLevel() : undefined execution = new VMExecution({ config, chain, metaDB }) } @@ -146,7 +147,7 @@ export function createClient(clientOpts: any = {}) { }, } - if (isTruthy(clientOpts.includeVM)) { + if (clientOpts.includeVM === true) { client.services[0].txPool = new TxPool({ config, service: client.services[0] }) } diff --git a/packages/client/test/rpc/rpc.spec.ts b/packages/client/test/rpc/rpc.spec.ts index 543a02a787..f77ddafc8b 100644 --- a/packages/client/test/rpc/rpc.spec.ts +++ b/packages/client/test/rpc/rpc.spec.ts @@ -1,4 +1,3 @@ -import { isFalsy } from '@ethereumjs/util' import { encode } from 'jwt-simple' import * as tape from 'tape' @@ -134,7 +133,7 @@ tape('call JSON RPC with nonexistent method', (t) => { .set('Content-Type', 'application/json') .send(req) .expect((res: any) => { - if (isFalsy(res.body.error)) { + if (res.body.error === undefined) { throw new Error('should return an error object') } if (res.body.error.code !== METHOD_NOT_FOUND) { diff --git a/packages/client/test/rpc/util.ts b/packages/client/test/rpc/util.ts index b0c1f274aa..fd3197ced2 100644 --- a/packages/client/test/rpc/util.ts +++ b/packages/client/test/rpc/util.ts @@ -1,17 +1,15 @@ -import { isFalsy, isTruthy } from '@ethereumjs/util' - import type * as tape from 'tape' export function checkError(t: tape.Test, expectedCode: number, expectedMessage?: string) { return (res: any) => { - if (isFalsy(res.body.error)) { + if (res.body.error === undefined) { throw new Error('should return an error object') } if (res.body.error.code !== expectedCode) { throw new Error(`should have an error code ${expectedCode}, got ${res.body.error.code}`) } if ( - isTruthy(expectedMessage) && + expectedMessage !== undefined && !(res.body.error.message as string).includes(expectedMessage) ) { throw new Error( diff --git a/packages/client/test/sync/txpool.spec.ts b/packages/client/test/sync/txpool.spec.ts index 28bad3efaf..43b13cc63d 100644 --- a/packages/client/test/sync/txpool.spec.ts +++ b/packages/client/test/sync/txpool.spec.ts @@ -1,7 +1,7 @@ import { Block } from '@ethereumjs/block' import { Chain, Common, Hardfork } from '@ethereumjs/common' import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' -import { Account, isFalsy, isTruthy, privateToAddress } from '@ethereumjs/util' +import { Account, privateToAddress } from '@ethereumjs/util' import * as tape from 'tape' import { Config } from '../../lib/config' @@ -36,11 +36,11 @@ const handleTxs = async ( stateManager?: StateManager, pool?: TxPool ) => { - if (isFalsy(pool)) { + if (pool === undefined) { pool = setup().pool } try { - if (isTruthy(stateManager)) { + if (stateManager !== undefined) { ;(pool).service.execution.vm.stateManager = stateManager } From 6946b617a419c3460ac3ee2c7e3628735609a129 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Fri, 26 Aug 2022 17:25:51 -0400 Subject: [PATCH 42/56] util: remove isTruthy/isFalsy from utils --- packages/util/test/types.spec.ts | 34 -------------------------------- 1 file changed, 34 deletions(-) diff --git a/packages/util/test/types.spec.ts b/packages/util/test/types.spec.ts index 57d703a388..fe1988586a 100644 --- a/packages/util/test/types.spec.ts +++ b/packages/util/test/types.spec.ts @@ -8,8 +8,6 @@ import { bufferToHex, intToBuffer, intToHex, - isFalsy, - isTruthy, toBuffer, toType, } from '../src' @@ -137,35 +135,3 @@ tape('toType', function (t) { }) }) }) - -tape('isFalsy and isTruthy', function (t) { - const falsyValues = [false, '', 0, NaN, null, undefined, BigInt(0)] - const truthyValues = [true, 'test', -1, 1, BigInt(1), [], {}] - t.test('isFalsy should return true for all falsy values', function (st) { - for (const falsyValue of falsyValues) { - st.ok(isFalsy(falsyValue) === true) - } - st.end() - }) - - t.test('isFalsy should return false for truthy values', function (st) { - for (const truthyValue of truthyValues) { - st.ok(isFalsy(truthyValue) === false) - } - st.end() - }) - - t.test('isTruthy should return false for all falsy values', function (st) { - for (const falsyValue of falsyValues) { - st.ok(isTruthy(falsyValue) === false) - } - st.end() - }) - - t.test('isTruthy should return true for truthy values', function (st) { - for (const truthyValue of truthyValues) { - st.ok(isTruthy(truthyValue) === true) - } - st.end() - }) -}) From 16ac33cbf79d89019ca8edc334b9556870b151bf Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 19:49:30 -0400 Subject: [PATCH 43/56] block: refactor JsonRpcBlock to block and remove unnecessary transactions undefined check --- packages/block/src/from-rpc.ts | 20 +++++----- packages/block/src/header-from-rpc.ts | 9 +++-- packages/block/src/types.ts | 29 +++++++++++++++ packages/client/lib/rpc/modules/eth.ts | 51 +------------------------- packages/tx/src/types.ts | 27 +++++++++++++- 5 files changed, 74 insertions(+), 62 deletions(-) diff --git a/packages/block/src/from-rpc.ts b/packages/block/src/from-rpc.ts index e6ba69edde..cc4178f276 100644 --- a/packages/block/src/from-rpc.ts +++ b/packages/block/src/from-rpc.ts @@ -6,7 +6,7 @@ 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) { @@ -41,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 (blockParams.transactions !== undefined) { - 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)) diff --git a/packages/block/src/header-from-rpc.ts b/packages/block/src/header-from-rpc.ts index 0012cd3061..3da0e739e9 100644 --- a/packages/block/src/header-from-rpc.ts +++ b/packages/block/src/header-from-rpc.ts @@ -1,7 +1,7 @@ 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. @@ -9,14 +9,17 @@ import type { BlockOptions } from './types' * @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: Omit & { receiptRoot?: string; receiptsRoot?: string }, + options?: BlockOptions +) { const { parentHash, sha3Uncles, miner, stateRoot, transactionsRoot, - receiptRoot, + receiptRoot, // TODO: Investigate dual receiptRoot/receiptsRoot usage. receiptsRoot, logsBloom, difficulty, diff --git a/packages/block/src/types.ts b/packages/block/src/types.ts index 3365efd46a..58cdd141cc 100644 --- a/packages/block/src/types.ts +++ b/packages/block/src/types.ts @@ -3,6 +3,7 @@ import type { Common } from '@ethereumjs/common' import type { AccessListEIP2930TxData, FeeMarketEIP1559TxData, + JsonRpcTx, JsonTx, TxData, } from '@ethereumjs/tx' @@ -150,3 +151,31 @@ 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. + receiptRoot?: string // the root of the receipts 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 // 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 +} diff --git a/packages/client/lib/rpc/modules/eth.ts b/packages/client/lib/rpc/modules/eth.ts index a6d8c61a70..f65af33335 100644 --- a/packages/client/lib/rpc/modules/eth.ts +++ b/packages/client/lib/rpc/modules/eth.ts @@ -21,10 +21,10 @@ import type { ReceiptsManager } from '../../execution/receipt' import type { EthProtocol } from '../../net/protocol' import type { EthereumService, FullEthereumService } from '../../service' import type { RpcTx } from '../types' -import type { Block } from '@ethereumjs/block' +import type { Block, JsonRpcBlock } from '@ethereumjs/block' import type { Log } from '@ethereumjs/evm' import type { Proof } from '@ethereumjs/statemanager' -import type { FeeMarketEIP1559Transaction, JsonTx, TypedTransaction } from '@ethereumjs/tx' +import type { FeeMarketEIP1559Transaction, JsonRpcTx, TypedTransaction } from '@ethereumjs/tx' import type { Account } from '@ethereumjs/util' import type { PostByzantiumTxReceipt, PreByzantiumTxReceipt, TxReceipt, VM } from '@ethereumjs/vm' @@ -41,53 +41,6 @@ type GetLogsParams = { // neither fromBlock nor toBlock are allowed. } -/* - * Based on https://eth.wiki/json-rpc/API - */ -type 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 // 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 -} -type JsonRpcTx = { - blockHash: string | null // DATA, 32 Bytes - hash of the block where this transaction was in. null when it's pending. - blockNumber: string | null // QUANTITY - block number where this transaction was in. null when it's pending. - from: string // DATA, 20 Bytes - address of the sender. - gas: string // QUANTITY - gas provided by the sender. - gasPrice: string // QUANTITY - gas price provided by the sender in wei. If EIP-1559 tx, defaults to maxFeePerGas. - maxFeePerGas?: string // QUANTITY - max total fee per gas provided by the sender in wei. - maxPriorityFeePerGas?: string // QUANTITY - max priority fee per gas provided by the sender in wei. - type: string // QUANTITY - EIP-2718 Typed Transaction type - accessList?: JsonTx['accessList'] // EIP-2930 access list - chainId?: string // Chain ID that this transaction is valid on. - hash: string // DATA, 32 Bytes - hash of the transaction. - input: string // DATA - the data send along with the transaction. - nonce: string // QUANTITY - the number of transactions made by the sender prior to this one. - to: string | null /// DATA, 20 Bytes - address of the receiver. null when it's a contract creation transaction. - transactionIndex: string | null // QUANTITY - integer of the transactions index position in the block. null when it's pending. - value: string // QUANTITY - value transferred in Wei. - v: string // QUANTITY - ECDSA recovery id - r: string // DATA, 32 Bytes - ECDSA signature r - s: string // DATA, 32 Bytes - ECDSA signature s -} type JsonRpcReceipt = { transactionHash: string // DATA, 32 Bytes - hash of the transaction. transactionIndex: string // QUANTITY - integer of the transactions index position in the block. diff --git a/packages/tx/src/types.ts b/packages/tx/src/types.ts index cdadf6eca1..f0cf7fc25b 100644 --- a/packages/tx/src/types.ts +++ b/packages/tx/src/types.ts @@ -16,7 +16,7 @@ export enum Capability { EIP155ReplayProtection = 155, /** - * Tx supports EIP-1559 gas fee market mechansim + * Tx supports EIP-1559 gas fee market mechanism * See: [1559](https://eips.ethereum.org/EIPS/eip-1559) Fee Market EIP */ EIP1559FeeMarket = 1559, @@ -263,3 +263,28 @@ export interface JsonTx { maxPriorityFeePerGas?: string maxFeePerGas?: string } + +/* + * Based on https://ethereum.org/en/developers/docs/apis/json-rpc/ + */ +export interface JsonRpcTx { + blockHash: string | null // DATA, 32 Bytes - hash of the block where this transaction was in. null when it's pending. + blockNumber: string | null // QUANTITY - block number where this transaction was in. null when it's pending. + from: string // DATA, 20 Bytes - address of the sender. + gas: string // QUANTITY - gas provided by the sender. + gasPrice: string // QUANTITY - gas price provided by the sender in wei. If EIP-1559 tx, defaults to maxFeePerGas. + maxFeePerGas?: string // QUANTITY - max total fee per gas provided by the sender in wei. + maxPriorityFeePerGas?: string // QUANTITY - max priority fee per gas provided by the sender in wei. + type: string // QUANTITY - EIP-2718 Typed Transaction type + accessList?: JsonTx['accessList'] // EIP-2930 access list + chainId?: string // Chain ID that this transaction is valid on. + hash: string // DATA, 32 Bytes - hash of the transaction. + input: string // DATA - the data send along with the transaction. + nonce: string // QUANTITY - the number of transactions made by the sender prior to this one. + to: string | null /// DATA, 20 Bytes - address of the receiver. null when it's a contract creation transaction. + transactionIndex: string | null // QUANTITY - integer of the transactions index position in the block. null when it's pending. + value: string // QUANTITY - value transferred in Wei. + v: string // QUANTITY - ECDSA recovery id + r: string // DATA, 32 Bytes - ECDSA signature r + s: string // DATA, 32 Bytes - ECDSA signature s +} From 73775e66723a004a9ff4b14eee4a53997999f6fd Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 20:19:40 -0400 Subject: [PATCH 44/56] block: fix from-rpc test types --- packages/block/test/from-rpc.spec.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/block/test/from-rpc.spec.ts b/packages/block/test/from-rpc.spec.ts index 7cba2bfda0..ab14c32570 100644 --- a/packages/block/test/from-rpc.spec.ts +++ b/packages/block/test/from-rpc.spec.ts @@ -16,14 +16,14 @@ 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 any, [], { 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 any, { common }) const hash = Buffer.from(blockData.hash.slice(2), 'hex') st.ok(block.hash().equals(hash)) st.end() @@ -45,7 +45,7 @@ tape('[fromRPC]:', function (t) { const blockDataTransactionValueAsInteger = blockData blockDataTransactionValueAsInteger.transactions[0].value = valueAsIntegerString const blockFromTransactionValueAsInteger = blockFromRpc( - blockDataTransactionValueAsInteger, + blockDataTransactionValueAsInteger as any, undefined, { common } ) @@ -66,7 +66,7 @@ tape('[fromRPC]:', function (t) { const blockDataTransactionGasPriceAsInteger = blockData blockDataTransactionGasPriceAsInteger.transactions[0].gasPrice = gasPriceAsIntegerString const blockFromTransactionGasPriceAsInteger = blockFromRpc( - blockDataTransactionGasPriceAsInteger, + blockDataTransactionGasPriceAsInteger as any, undefined, { common } ) @@ -83,9 +83,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 any, + undefined, + { + common, + } + ) st.equal( blockDifficultyAsInteger.header.difficulty.toString(), blockDataDifficultyAsInteger.difficulty From 5931e3fee97c29907d07bf60dd5d320fd85c34a4 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 20:35:30 -0400 Subject: [PATCH 45/56] block: fix type issue in blockFromRpc test --- packages/block/test/block.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index 60ba7e802b..1ac920f962 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -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 any, [], { common }) st.pass('does not throw') } catch (error: any) { st.fail('error thrown') From 1babc1ffdd33492075b2d3229887202830f9423f Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 20:40:35 -0400 Subject: [PATCH 46/56] StateManager: simplify flush method logic --- packages/statemanager/src/cache.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/statemanager/src/cache.ts b/packages/statemanager/src/cache.ts index 3633f82f28..50b9e65970 100644 --- a/packages/statemanager/src/cache.ts +++ b/packages/statemanager/src/cache.ts @@ -111,14 +111,13 @@ export class Cache { const it = this._cache.begin let next = true while (next) { - if (it.value !== undefined && it.value.modified === true) { + if (it.value?.modified === true) { it.value.modified = false const keyBuf = Buffer.from(it.key, 'hex') if (it.value.deleted === false) { const accountRlp = it.value.val await this._putCb(keyBuf, accountRlp) } else { - it.value.modified = false it.value.deleted = true it.value.virtual = true it.value.val = new Account().serialize() From 69235f8b7cbb8b6acd84b0eb99e0a601651b0b9c Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 20:52:21 -0400 Subject: [PATCH 47/56] blockchain: remove unnecessary undefined check --- packages/blockchain/src/blockchain.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/blockchain/src/blockchain.ts b/packages/blockchain/src/blockchain.ts index 8157523315..b321d877e7 100644 --- a/packages/blockchain/src/blockchain.ts +++ b/packages/blockchain/src/blockchain.ts @@ -546,9 +546,6 @@ export class Blockchain implements BlockchainInterface { return } const parentHeader = (await this.getBlock(header.parentHash)).header - if (parentHeader === undefined) { - throw new Error(`could not find parent header ${header.errorStr()}`) - } const { number } = header if (number !== parentHeader.number + BigInt(1)) { From af6cc197b488b39eea482469e0bcc3e2f4950df0 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 21:00:19 -0400 Subject: [PATCH 48/56] client: fix cli startBlock undefined check --- packages/client/bin/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 695819ceb4..df90c296ed 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -347,7 +347,7 @@ async function executeBlocks(client: EthereumClient) { * Note: this is destructive and removes blocks from the blockchain. Please back up your datadir. */ async function startBlock(client: EthereumClient) { - if (typeof args.startBlock === 'number') return + if (args.startBlock === undefined) return const startBlock = BigInt(args.startBlock) const { blockchain } = client.chain const height = (await blockchain.getCanonicalHeadHeader()).number From 1eb89c264c4831147041da1128908925dcd05c31 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 21:05:25 -0400 Subject: [PATCH 49/56] evm: remove unnecessary precompiles undefined check --- packages/evm/src/precompiles/01-ecrecover.ts | 2 -- packages/evm/src/precompiles/02-sha256.ts | 2 -- packages/evm/src/precompiles/03-ripemd160.ts | 2 -- packages/evm/src/precompiles/04-identity.ts | 2 -- packages/evm/src/precompiles/05-modexp.ts | 2 -- packages/evm/src/precompiles/06-ecadd.ts | 2 -- packages/evm/src/precompiles/07-ecmul.ts | 2 -- packages/evm/src/precompiles/08-ecpairing.ts | 2 -- packages/evm/src/precompiles/09-blake2f.ts | 2 -- packages/evm/src/precompiles/0a-bls12-g1add.ts | 2 -- packages/evm/src/precompiles/0b-bls12-g1mul.ts | 2 -- packages/evm/src/precompiles/0c-bls12-g1multiexp.ts | 2 -- packages/evm/src/precompiles/0d-bls12-g2add.ts | 2 -- packages/evm/src/precompiles/0e-bls12-g2mul.ts | 2 -- packages/evm/src/precompiles/0f-bls12-g2multiexp.ts | 2 -- packages/evm/src/precompiles/10-bls12-pairing.ts | 2 -- packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts | 2 -- packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts | 2 -- 18 files changed, 36 deletions(-) diff --git a/packages/evm/src/precompiles/01-ecrecover.ts b/packages/evm/src/precompiles/01-ecrecover.ts index 9c7da88a6f..a431481b73 100644 --- a/packages/evm/src/precompiles/01-ecrecover.ts +++ b/packages/evm/src/precompiles/01-ecrecover.ts @@ -12,8 +12,6 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile01(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const gasUsed = opts._common.param('gasPrices', 'ecRecover') if (opts.gasLimit < gasUsed) { diff --git a/packages/evm/src/precompiles/02-sha256.ts b/packages/evm/src/precompiles/02-sha256.ts index 0e61aa4ff5..e4c0b45b7c 100644 --- a/packages/evm/src/precompiles/02-sha256.ts +++ b/packages/evm/src/precompiles/02-sha256.ts @@ -7,8 +7,6 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile02(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const data = opts.data let gasUsed = opts._common.param('gasPrices', 'sha256') diff --git a/packages/evm/src/precompiles/03-ripemd160.ts b/packages/evm/src/precompiles/03-ripemd160.ts index 13086a4f3c..729f43d12b 100644 --- a/packages/evm/src/precompiles/03-ripemd160.ts +++ b/packages/evm/src/precompiles/03-ripemd160.ts @@ -7,8 +7,6 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile03(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const data = opts.data let gasUsed = opts._common.param('gasPrices', 'ripemd160') diff --git a/packages/evm/src/precompiles/04-identity.ts b/packages/evm/src/precompiles/04-identity.ts index 17af5276c9..48cc02be63 100644 --- a/packages/evm/src/precompiles/04-identity.ts +++ b/packages/evm/src/precompiles/04-identity.ts @@ -4,8 +4,6 @@ import type { ExecResult } from '../evm' import type { PrecompileInput } from './types' export function precompile04(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const data = opts.data let gasUsed = opts._common.param('gasPrices', 'identity') diff --git a/packages/evm/src/precompiles/05-modexp.ts b/packages/evm/src/precompiles/05-modexp.ts index 80b83f7159..5167060c30 100644 --- a/packages/evm/src/precompiles/05-modexp.ts +++ b/packages/evm/src/precompiles/05-modexp.ts @@ -77,8 +77,6 @@ export function expmod(a: bigint, power: bigint, modulo: bigint) { } export function precompile05(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const data = opts.data let adjustedELen = getAdjustedExponentLength(data) diff --git a/packages/evm/src/precompiles/06-ecadd.ts b/packages/evm/src/precompiles/06-ecadd.ts index 5a415d9d45..ee89bcb8b6 100644 --- a/packages/evm/src/precompiles/06-ecadd.ts +++ b/packages/evm/src/precompiles/06-ecadd.ts @@ -6,8 +6,6 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile06(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const inputData = opts.data const gasUsed = opts._common.param('gasPrices', 'ecAdd') diff --git a/packages/evm/src/precompiles/07-ecmul.ts b/packages/evm/src/precompiles/07-ecmul.ts index a8f7cf34ff..24ca637ae7 100644 --- a/packages/evm/src/precompiles/07-ecmul.ts +++ b/packages/evm/src/precompiles/07-ecmul.ts @@ -6,8 +6,6 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile07(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const inputData = opts.data const gasUsed = opts._common.param('gasPrices', 'ecMul') diff --git a/packages/evm/src/precompiles/08-ecpairing.ts b/packages/evm/src/precompiles/08-ecpairing.ts index c0355cc6bc..97d7ae0b0d 100644 --- a/packages/evm/src/precompiles/08-ecpairing.ts +++ b/packages/evm/src/precompiles/08-ecpairing.ts @@ -6,8 +6,6 @@ import type { PrecompileInput } from './types' const bn128 = require('rustbn.js') export function precompile08(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const inputData = opts.data // no need to care about non-divisible-by-192, because bn128.pairing will properly fail in that case const inputDataSize = BigInt(Math.floor(inputData.length / 192)) diff --git a/packages/evm/src/precompiles/09-blake2f.ts b/packages/evm/src/precompiles/09-blake2f.ts index 66b67b4e3a..4a3e9b08b4 100644 --- a/packages/evm/src/precompiles/09-blake2f.ts +++ b/packages/evm/src/precompiles/09-blake2f.ts @@ -156,8 +156,6 @@ export function F(h: Uint32Array, m: Uint32Array, t: Uint32Array, f: boolean, ro } export function precompile09(opts: PrecompileInput): ExecResult { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const data = opts.data if (data.length !== 213) { return { diff --git a/packages/evm/src/precompiles/0a-bls12-g1add.ts b/packages/evm/src/precompiles/0a-bls12-g1add.ts index f944957406..bd52f40312 100644 --- a/packages/evm/src/precompiles/0a-bls12-g1add.ts +++ b/packages/evm/src/precompiles/0a-bls12-g1add.ts @@ -7,8 +7,6 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToG1Point, BLS12_381_FromG1Point } = require('./util/bls12_381') export async function precompile0a(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/0b-bls12-g1mul.ts b/packages/evm/src/precompiles/0b-bls12-g1mul.ts index 33c6be1241..9a3d850dd5 100644 --- a/packages/evm/src/precompiles/0b-bls12-g1mul.ts +++ b/packages/evm/src/precompiles/0b-bls12-g1mul.ts @@ -11,8 +11,6 @@ const { } = require('./util/bls12_381') export async function precompile0b(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts b/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts index 458269cf88..cbfb29f41b 100644 --- a/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts +++ b/packages/evm/src/precompiles/0c-bls12-g1multiexp.ts @@ -11,8 +11,6 @@ const { } = require('./util/bls12_381') export async function precompile0c(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/0d-bls12-g2add.ts b/packages/evm/src/precompiles/0d-bls12-g2add.ts index 78af41b78b..f851b6c2a3 100644 --- a/packages/evm/src/precompiles/0d-bls12-g2add.ts +++ b/packages/evm/src/precompiles/0d-bls12-g2add.ts @@ -7,8 +7,6 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToG2Point, BLS12_381_FromG2Point } = require('./util/bls12_381') export async function precompile0d(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/0e-bls12-g2mul.ts b/packages/evm/src/precompiles/0e-bls12-g2mul.ts index cdb73062f2..6de254dcab 100644 --- a/packages/evm/src/precompiles/0e-bls12-g2mul.ts +++ b/packages/evm/src/precompiles/0e-bls12-g2mul.ts @@ -11,8 +11,6 @@ const { } = require('./util/bls12_381') export async function precompile0e(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts b/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts index 7b3807aa44..6d25856457 100644 --- a/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts +++ b/packages/evm/src/precompiles/0f-bls12-g2multiexp.ts @@ -13,8 +13,6 @@ const { } = require('./util/bls12_381') export async function precompile0f(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/10-bls12-pairing.ts b/packages/evm/src/precompiles/10-bls12-pairing.ts index a9bbb72c83..4fe3fa5ef9 100644 --- a/packages/evm/src/precompiles/10-bls12-pairing.ts +++ b/packages/evm/src/precompiles/10-bls12-pairing.ts @@ -10,8 +10,6 @@ const zeroBuffer = Buffer.alloc(32, 0) const oneBuffer = Buffer.concat([Buffer.alloc(31, 0), Buffer.from('01', 'hex')]) export async function precompile10(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts b/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts index be7fc93d35..e34a6ca1b8 100644 --- a/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts +++ b/packages/evm/src/precompiles/11-bls12-map-fp-to-g1.ts @@ -7,8 +7,6 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToFpPoint, BLS12_381_FromG1Point } = require('./util/bls12_381') export async function precompile11(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data diff --git a/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts b/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts index 89f41dbde2..b53a798eea 100644 --- a/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts +++ b/packages/evm/src/precompiles/12-bls12-map-fp2-to-g2.ts @@ -7,8 +7,6 @@ import type { PrecompileInput } from './types' const { BLS12_381_ToFp2Point, BLS12_381_FromG2Point } = require('./util/bls12_381') export async function precompile12(opts: PrecompileInput): Promise { - if (opts.data === undefined) throw new Error('opts.data missing but required') - const mcl = (opts._EVM)._mcl! const inputData = opts.data From ad0567c3c2e7922432b058bcab5af7002d7d47d1 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 21:06:40 -0400 Subject: [PATCH 50/56] util: remove isFalsy and isTruthy utils --- packages/util/src/types.ts | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/packages/util/src/types.ts b/packages/util/src/types.ts index ddfe78d8ab..6c007c0fe2 100644 --- a/packages/util/src/types.ts +++ b/packages/util/src/types.ts @@ -120,35 +120,3 @@ export function toType( throw new Error('unknown outputType') } } - -type Falsy = false | '' | 0 | null | undefined | 0n - -/** - * Returns true if a value is falsy - * - * @param value - Value to check for falseness - * - * @deprecated This helper function should only be used temporarily until the monorepo types are explicit enough - */ -export function isFalsy(value: unknown): value is Falsy { - return !!( - value === false || - value === '' || - value === 0 || - Number.isNaN(value) || - value === null || - typeof value === 'undefined' || - value === BigInt(0) - ) -} - -/** - * Returns true if a value is truthy - * - * @param value - Value to check for truthiness - * - * @deprecated This helper function should only be used temporarily until the monorepo types are explicit enough - */ -export function isTruthy(value: T | Falsy): value is T { - return !isFalsy(value) -} From e53fb70580bb1dd2021f15f1fa79b90654ef3ba6 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 21:07:56 -0400 Subject: [PATCH 51/56] vm: remove unnecessary undefined check from runTx --- packages/vm/src/runTx.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/vm/src/runTx.ts b/packages/vm/src/runTx.ts index 3fbbb638cd..5afa3f7be7 100644 --- a/packages/vm/src/runTx.ts +++ b/packages/vm/src/runTx.ts @@ -30,11 +30,6 @@ const debugGas = createDebugLogger('vm:tx:gas') * @ignore */ export async function runTx(this: VM, opts: RunTxOpts): Promise { - // tx is required - if (opts.tx === undefined) { - throw new Error('invalid input, tx is required') - } - // create a reasonable default if no block is given opts.block = opts.block ?? Block.fromBlockData({}, { common: opts.tx.common }) From 3a0a1d65c266143c512ba849a6f46dc1f1574d9e Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Sun, 28 Aug 2022 21:12:53 -0400 Subject: [PATCH 52/56] common: remove ttd !== BigInt(0) check --- packages/common/src/common.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index e734a9b9a2..7c67d4a35c 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -285,10 +285,7 @@ export class Common extends EventEmitter { if (blockNumber >= BigInt(hf.block)) { hardfork = hf.name as Hardfork } - if ( - td && - (typeof hf.ttd === 'string' || (typeof hf.ttd === 'bigint' && hf.ttd !== BigInt(0))) - ) { + if (td && (typeof hf.ttd === 'string' || typeof hf.ttd === 'bigint')) { if (td >= BigInt(hf.ttd)) { minTdHF = hf.name } else { From 28a81d1850cf7aa2070bb3450f435e927c75a894 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Mon, 29 Aug 2022 22:53:54 -0400 Subject: [PATCH 53/56] client: remove unnecessary true equality --- packages/client/lib/miner/miner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/lib/miner/miner.ts b/packages/client/lib/miner/miner.ts index 3af2fd527a..5f744138b3 100644 --- a/packages/client/lib/miner/miner.ts +++ b/packages/client/lib/miner/miner.ts @@ -228,7 +228,7 @@ export class Miner { inTurn = await (vmCopy.blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress ) - difficulty = inTurn === true ? 2 : 1 + difficulty = inTurn ? 2 : 1 } let baseFeePerGas From a173bb511c0be1c3274c135d38d3e7d854fcb0a7 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Mon, 29 Aug 2022 23:20:31 -0400 Subject: [PATCH 54/56] client: simplify get logic and add comment --- packages/client/lib/execution/level.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/client/lib/execution/level.ts b/packages/client/lib/execution/level.ts index d8e2f45710..a336f4513e 100644 --- a/packages/client/lib/execution/level.ts +++ b/packages/client/lib/execution/level.ts @@ -31,13 +31,14 @@ export class LevelDB implements DB { try { value = await this._leveldb.get(key, ENCODING_OPTS) } catch (error: any) { - if (error.notFound !== undefined) { - // not found, returning null - } else { + // https://github.com/Level/abstract-level/blob/915ad1317694d0ce8c580b5ab85d81e1e78a3137/abstract-level.js#L309 + // This should be `true` if the error came from LevelDB + // so we can check for `NOT true` to identify any non-404 errors + if (error.notFound !== true) { throw error } } - return value as Buffer + return value as Buffer | null } /** From 1c8538ef28e4bd6228cbd106b0846d06fe762e76 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Mon, 29 Aug 2022 23:27:35 -0400 Subject: [PATCH 55/56] devp2p: address review, simplify some types --- packages/devp2p/src/dns/dns.ts | 2 +- packages/devp2p/src/dpt/server.ts | 2 +- packages/devp2p/src/protocol/eth.ts | 2 +- packages/devp2p/src/protocol/protocol.ts | 6 +++--- packages/devp2p/src/rlpx/peer.ts | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/devp2p/src/dns/dns.ts b/packages/devp2p/src/dns/dns.ts index e3fc319f6d..1a391a7a92 100644 --- a/packages/devp2p/src/dns/dns.ts +++ b/packages/devp2p/src/dns/dns.ts @@ -36,7 +36,7 @@ export class DNS { constructor(options: DNSOptions = {}) { this._DNSTreeCache = {} - if (options.dnsServerAddress !== undefined) { + if (typeof options.dnsServerAddress === 'string') { dns.setServers([options.dnsServerAddress]) } } diff --git a/packages/devp2p/src/dpt/server.ts b/packages/devp2p/src/dpt/server.ts index 4ebc28d055..ae273cc04f 100644 --- a/packages/devp2p/src/dpt/server.ts +++ b/packages/devp2p/src/dpt/server.ts @@ -203,7 +203,7 @@ export class Server extends EventEmitter { case 'pong': { let rkey = info.data.hash.toString('hex') const rkeyParity = this._parityRequestMap.get(rkey) - if (rkeyParity !== undefined) { + if (typeof rkeyParity === 'string') { rkey = rkeyParity this._parityRequestMap.delete(rkeyParity) } diff --git a/packages/devp2p/src/protocol/eth.ts b/packages/devp2p/src/protocol/eth.ts index 51e7fd26dd..95dec575a0 100644 --- a/packages/devp2p/src/protocol/eth.ts +++ b/packages/devp2p/src/protocol/eth.ts @@ -319,7 +319,7 @@ export class ETH extends Protocol { payload = Buffer.from(RLP.encode(bufArrToArr(payload))) // Use snappy compression if peer supports DevP2P >=v5 - if (this._peer._hello !== null && this._peer._hello?.protocolVersion >= 5) { + if (this._peer._hello !== null && this._peer._hello.protocolVersion >= 5) { payload = snappy.compress(payload) } diff --git a/packages/devp2p/src/protocol/protocol.ts b/packages/devp2p/src/protocol/protocol.ts index 9cfc811069..5f239ed963 100644 --- a/packages/devp2p/src/protocol/protocol.ts +++ b/packages/devp2p/src/protocol/protocol.ts @@ -71,7 +71,7 @@ export class Protocol extends EventEmitter { // Remote Peer IP logger const ip = this._peer._socket.remoteAddress - if (ip !== undefined) { + if (typeof ip === 'string') { this.msgDebuggers[ip] = devp2pDebug.extend(ip) } } @@ -84,7 +84,7 @@ export class Protocol extends EventEmitter { */ _addFirstPeerDebugger() { const ip = this._peer._socket.remoteAddress - if (ip !== undefined) { + if (typeof ip === 'string') { this.msgDebuggers[ip] = devp2pDebug.extend('FIRST_PEER') this._peer._addFirstPeerDebugger() this._firstPeer = ip @@ -103,7 +103,7 @@ export class Protocol extends EventEmitter { this.msgDebuggers[messageName](msg) } const ip = this._peer._socket.remoteAddress - if (ip !== undefined && this.msgDebuggers[ip] !== undefined) { + if (typeof ip === 'string' && this.msgDebuggers[ip] !== undefined) { this.msgDebuggers[ip](msg) } } diff --git a/packages/devp2p/src/rlpx/peer.ts b/packages/devp2p/src/rlpx/peer.ts index 1bca1155ba..7a67194df5 100644 --- a/packages/devp2p/src/rlpx/peer.ts +++ b/packages/devp2p/src/rlpx/peer.ts @@ -562,7 +562,7 @@ export class Peer extends EventEmitter { // Use snappy uncompression if peer supports DevP2P >=v5 let compressed = false const origPayload = payload - if (this._hello !== null && this._hello?.protocolVersion >= 5) { + if (this._hello !== null && this._hello.protocolVersion >= 5) { payload = snappy.uncompress(payload) compressed = true } @@ -691,7 +691,7 @@ export class Peer extends EventEmitter { */ _addFirstPeerDebugger() { const ip = this._socket.remoteAddress - if (ip !== undefined) { + if (typeof ip === 'string') { this._logger = devp2pDebug.extend(ip).extend(`FIRST_PEER`).extend(DEBUG_BASE_NAME) } } From 70bdc5ab60d0e311bed741c5d42abb60429af331 Mon Sep 17 00:00:00 2001 From: Gabriel Rocheleau Date: Mon, 29 Aug 2022 23:27:54 -0400 Subject: [PATCH 56/56] common: check for bigint instead of undefined --- packages/common/src/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts index 7c67d4a35c..605fd7b88b 100644 --- a/packages/common/src/common.ts +++ b/packages/common/src/common.ts @@ -408,7 +408,7 @@ export class Common extends EventEmitter { const hfEIPs = hfChanges[1]['eips'] for (const eip of hfEIPs) { const valueEIP = this.paramByEIP(topic, name, eip) - value = valueEIP !== undefined ? valueEIP : value + value = typeof valueEIP === 'bigint' ? valueEIP : value } // Parameter-inlining HF file (e.g. istanbul.json) } else {