diff --git a/packages/client/bin/cli.ts b/packages/client/bin/cli.ts index 5e9e843b5b7..ff3a4a42d9b 100755 --- a/packages/client/bin/cli.ts +++ b/packages/client/bin/cli.ts @@ -19,7 +19,7 @@ import { EthereumClient } from '../lib/client' import { Config, DataDirectory, SyncMode } from '../lib/config' import { Logger, getLogger } from '../lib/logging' import { startRPCServers, helprpc } from './startRpc' -import type { FullEthereumService } from '../lib/service' +import { FullEthereumService } from '../lib/service' import { GenesisState } from '@ethereumjs/blockchain/dist/genesisStates' import { Level } from 'level' import { AbstractLevel } from 'abstract-level' @@ -327,9 +327,9 @@ async function executeBlocks(client: EthereumClient) { ) process.exit() } - const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService - if (!execution) throw new Error('executeBlocks requires execution') - await execution.executeBlocks(first, last, txHashes) + const service = client.services.find((s) => s.name === 'eth') + if (!(service instanceof FullEthereumService)) throw new Error('executeBlocks requires execution') + await service.execution.executeBlocks(first, last, txHashes) } /** @@ -337,7 +337,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) return + if (typeof args.startBlock !== 'number' || args.startBlock === 0) return const startBlock = BigInt(args.startBlock) const { blockchain } = client.chain const height = (await blockchain.getCanonicalHeadHeader()).number @@ -369,7 +369,7 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { const dbs = initDBs(config) let blockchain - if (customGenesisState) { + if (typeof customGenesisState !== 'undefined') { const validateConsensus = config.chainCommon.consensusAlgorithm() === ConsensusAlgorithm.Clique blockchain = await Blockchain.create({ db: dbs.chainDB, @@ -388,13 +388,13 @@ async function startClient(config: Config, customGenesisState?: GenesisState) { ...dbs, }) - if (args.startBlock) { + if (typeof args.startBlock === 'number' && args.startBlock > 0) { await startBlock(client) } await client.open() - if (args.executeBlocks) { + if (typeof args.executeBlocks === 'string' && args.executeBlocks !== '') { // Special block execution debug mode (does not change any state) await executeBlocks(client) } else { @@ -546,7 +546,7 @@ function generateAccount(): Account { * Main entry point to start a client */ async function run() { - if (args.helprpc) { + if (typeof args.helprpc !== 'undefined') { // Output RPC help and exit return helprpc() } @@ -556,14 +556,14 @@ async function run() { // Configure accounts for mining and prefunding in a local devnet const accounts: Account[] = [] - if (args.unlock) { + if (typeof args.unlock !== 'undefined') { accounts.push(...(await inputAccounts())) } let customGenesisState: GenesisState | undefined let common = new Common({ chain, hardfork: Hardfork.Chainstart }) - if (args.dev) { + if (typeof args.dev !== 'undefined') { args.discDns = false if (accounts.length === 0) { // If generating new keys delete old chain data to prevent genesis block mismatch @@ -577,15 +577,17 @@ async function run() { // Configure common based on args given if ( - (args.customChainParams || args.customGenesisState || args.gethGenesis) && - (args.network !== 'mainnet' || args.networkId) + (typeof args.customChainParams !== 'undefined' || + typeof args.customGenesisState !== 'undefined' || + typeof args.gethGenesis !== 'undefined') && + (args.network !== 'mainnet' || typeof 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 (args.customChain) { - if (!args.customGenesisState) { + if (typeof args.customChain !== 'undefined') { + if (args.customGenesisState === 'undedefined') { console.error('cannot have custom chain parameters without genesis state') process.exit() } @@ -600,7 +602,7 @@ async function run() { console.error(`invalid chain parameters: ${err.message}`) process.exit() } - } else if (args.gethGenesis) { + } else if (typeof args.gethGenesis !== 'undefined') { // 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] @@ -612,7 +614,7 @@ async function run() { customGenesisState = await parseGenesisState(genesisFile) } - if (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' ) @@ -624,8 +626,10 @@ async function run() { ensureDirSync(configDirectory) const key = await Config.getClientKey(datadir, common) logger = getLogger(args) - const bootnodes = args.bootnodes ? parseMultiaddrs(args.bootnodes) : undefined - const multiaddrs = args.multiaddrs ? parseMultiaddrs(args.multiaddrs) : undefined + const bootnodes = + typeof args.bootnodes !== 'undefined' ? parseMultiaddrs(args.bootnodes) : undefined + const multiaddrs = + typeof args.multiaddrs !== 'undefined' ? parseMultiaddrs(args.multiaddrs) : undefined const config = new Config({ accounts, bootnodes, @@ -643,7 +647,7 @@ async function run() { maxPeers: args.maxPeers, maxPerRequest: args.maxPerRequest, maxFetcherJobs: args.maxFetcherJobs, - mine: args.mine || args.dev, + mine: args.mine ?? args.dev, minerCoinbase: args.minerCoinbase, minPeers: args.minPeers, multiaddrs, @@ -657,7 +661,7 @@ async function run() { config.events.setMaxListeners(50) const client = await startClient(config, customGenesisState) - const servers = args.rpc || 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...') diff --git a/packages/client/bin/startRpc.ts b/packages/client/bin/startRpc.ts index 62483f1c257..563a232415f 100644 --- a/packages/client/bin/startRpc.ts +++ b/packages/client/bin/startRpc.ts @@ -35,11 +35,11 @@ type RPCArgs = { */ function parseJwtSecret(config: Config, jwtFilePath?: string): Buffer { let jwtSecret - if (jwtFilePath) { + if (typeof jwtFilePath === 'string') { 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 (!jwtSecretHex || jwtSecretHex.length != 64) { + if (typeof 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}`) @@ -103,8 +103,8 @@ export function startRPCServers(client: EthereumClient, args: RPCArgs) { jwtSecret, unlessFn: (req: any) => Array.isArray(req.body) - ? !req.body.some((r: any) => r.method.includes('engine_')) - : !req.body.method.includes('engine_'), + ? req.body.some((r: any) => r.method.includes('engine_')) === false + : req.body.method.includes('engine_') === false, } : undefined, }) diff --git a/packages/client/browser/index.ts b/packages/client/browser/index.ts index 1c9dd548190..ee0ef08b7ce 100644 --- a/packages/client/browser/index.ts +++ b/packages/client/browser/index.ts @@ -50,7 +50,8 @@ export async function createClient(args: any) { const datadir = args.datadir ?? Config.DATADIR_DEFAULT const common = new Common({ chain: args.network ?? Chain.Mainnet }) const key = await Config.getClientKey(datadir, common) - const bootnodes = args.bootnodes ? parseMultiaddrs(args.bootnodes) : undefined + const bootnodes = + typeof args.bootnodes !== 'undefined' ? parseMultiaddrs(args.bootnodes) : undefined const config = new Config({ common, key, diff --git a/packages/client/lib/execution/receipt.ts b/packages/client/lib/execution/receipt.ts index 1e705848f53..6262d769ee0 100644 --- a/packages/client/lib/execution/receipt.ts +++ b/packages/client/lib/execution/receipt.ts @@ -111,12 +111,12 @@ export class ReceiptsManager extends MetaDBManager { */ async getReceipts( blockHash: Buffer, - calcBloom?: Boolean, + calcBloom?: boolean, includeTxType?: true ): Promise async getReceipts( blockHash: Buffer, - calcBloom?: Boolean, + calcBloom?: boolean, includeTxType?: false ): Promise async getReceipts( diff --git a/packages/client/lib/execution/vmexecution.ts b/packages/client/lib/execution/vmexecution.ts index f74571a4cea..0f0a7fdb616 100644 --- a/packages/client/lib/execution/vmexecution.ts +++ b/packages/client/lib/execution/vmexecution.ts @@ -34,7 +34,7 @@ export class VMExecution extends Execution { constructor(options: ExecutionOptions) { super(options) - if (!this.config.vm) { + if (typeof this.config.vm === 'undefined') { const trie = new Trie({ db: new LevelDB(this.stateDB) }) const stateManager = new DefaultStateManager({ @@ -92,7 +92,7 @@ export class VMExecution extends Execution { const result = await this.vm.runBlock(opts) receipts = result.receipts } - if (receipts) { + if (typeof receipts !== 'undefined') { // Save receipts this.pendingReceipts?.set(block.hash().toString('hex'), receipts) } @@ -147,7 +147,7 @@ export class VMExecution extends Execution { while ( (numExecuted === undefined || (loop && numExecuted === this.NUM_BLOCKS_PER_ITERATION)) && - !startHeadBlock.hash().equals(canonicalHead.hash()) + startHeadBlock.hash().equals(canonicalHead.hash()) === false ) { let txCounter = 0 headBlock = undefined @@ -242,23 +242,25 @@ export class VMExecution extends Execution { ) numExecuted = await this.vmPromise - if (errorBlock) { + if (typeof errorBlock !== 'undefined') { await this.chain.blockchain.setIteratorHead('vm', (errorBlock as Block).header.parentHash) return 0 } const endHeadBlock = await this.vm.blockchain.getIteratorHead('vm') - if (numExecuted && numExecuted > 0) { + if (typeof numExecuted === 'number' && numExecuted > 0) { const firstNumber = startHeadBlock.header.number const firstHash = short(startHeadBlock.hash()) const lastNumber = endHeadBlock.header.number const lastHash = short(endHeadBlock.hash()) - const baseFeeAdd = this.config.execCommon.gteHardfork(Hardfork.London) - ? `baseFee=${endHeadBlock.header.baseFeePerGas} ` - : '' - const tdAdd = this.config.execCommon.gteHardfork(Hardfork.Merge) - ? '' - : `td=${this.chain.blocks.td} ` + const baseFeeAdd = + this.config.execCommon.gteHardfork(Hardfork.London) === true + ? `baseFee=${endHeadBlock.header.baseFeePerGas} ` + : '' + const tdAdd = + this.config.execCommon.gteHardfork(Hardfork.Merge) === true + ? '' + : `td=${this.chain.blocks.td} ` this.config.logger.info( `Executed blocks count=${numExecuted} first=${firstNumber} hash=${firstHash} ${tdAdd}${baseFeeAdd}hardfork=${this.hardfork} last=${lastNumber} hash=${lastHash} txs=${txCounter}` ) diff --git a/packages/client/lib/logging.ts b/packages/client/lib/logging.ts index be59b88787f..e9cc936eb97 100644 --- a/packages/client/lib/logging.ts +++ b/packages/client/lib/logging.ts @@ -28,10 +28,10 @@ enum LevelColors { * Adds stack trace to error message if included */ const errorFormat = format((info: any) => { - if (info.message instanceof Error && info.message.stack) { + if (info.message instanceof Error && typeof info.message.stack !== 'undefined') { return { ...info, message: info.message.stack } } - if (info instanceof Error && info.stack) { + if (info instanceof Error && typeof info.stack !== 'undefined') { return { ...info, message: info.stack } } return info @@ -51,7 +51,7 @@ function logFormat(colors = false) { return printf((info: any) => { let level = info.level.toUpperCase() - if (!info.message) info.message = '(empty message)' + if (typeof info.message === 'undefined') info.message = '(empty message)' if (colors) { const colorLevel = LevelColors[info.level as keyof typeof LevelColors] @@ -61,8 +61,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 (info.attentionCL) info.attentionCL = info.attentionCL.replace(regex, replaceFn) - if (info.attentionHF) info.attentionHF = info.attentionHF.replace(regex, replaceFn) + if (typeof info.attentionCL !== 'undefined') + info.attentionCL = info.attentionCL.replace(regex, replaceFn) + if (typeof info.attentionHF !== 'undefined') + info.attentionHF = info.attentionHF.replace(regex, replaceFn) } if (info.attentionCL !== undefined) attentionCL = info.attentionCL @@ -97,7 +99,7 @@ function logFileTransport(args: any) { level: args.logLevelFile, format: formatConfig(), } - if (!args.logRotate) { + if (args.logRotate !== true) { return new wTransports.File({ ...opts, filename, @@ -125,7 +127,7 @@ export function getLogger(args: { [key: string]: any } = { loglevel: 'info' }) { format: formatConfig(true), }), ] - if (args.logFile) { + if (args.logFile === true) { transports.push(logFileTransport(args)) } const logger = createLogger({ diff --git a/packages/client/lib/miner/miner.ts b/packages/client/lib/miner/miner.ts index 29e565910ec..54bc31293b7 100644 --- a/packages/client/lib/miner/miner.ts +++ b/packages/client/lib/miner/miner.ts @@ -75,7 +75,7 @@ export class Miner { if (!this.running) { return } - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { this.config.logger.info('Miner: reached merge hardfork - stopping') this.stop() return @@ -91,7 +91,7 @@ export class Miner { const inTurn = await (blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress ) - if (!inTurn) { + if (inTurn === false) { const signerCount = (blockchain.consensus as CliqueConsensus).cliqueActiveSigners().length timeout += Math.random() * signerCount * 500 } @@ -109,7 +109,7 @@ export class Miner { * Finds the next PoW solution. */ private async findNextSolution() { - if (!this.ethash) { + if (typeof this.ethash === 'undefined') { return } this.config.logger.info('Miner: Finding next PoW solution 🔨') @@ -190,7 +190,9 @@ export class Miner { { number }, { common: this.config.chainCommon, cliqueSigner } ) - if ((this.service.chain.blockchain as any).consensus.cliqueCheckRecentlySigned(header)) { + if ( + (this.service.chain.blockchain as any).consensus.cliqueCheckRecentlySigned(header) === true + ) { this.config.logger.info(`Miner: We have too recently signed, waiting for next block`) this.assembling = false return @@ -198,7 +200,7 @@ export class Miner { } if (this.config.chainCommon.consensusType() === ConsensusType.ProofOfWork) { - while (!this.nextSolution) { + while (typeof this.nextSolution === 'undefined') { this.config.logger.info(`Miner: Waiting to find next PoW solution 🔨`) await new Promise((r) => setTimeout(r, 1000)) } @@ -223,19 +225,18 @@ export class Miner { inTurn = await (vmCopy.blockchain.consensus as CliqueConsensus).cliqueSignerInTurn( signerAddress ) - difficulty = inTurn ? 2 : 1 + difficulty = inTurn === true ? 2 : 1 } let baseFeePerGas const londonHardforkBlock = this.config.chainCommon.hardforkBlock(Hardfork.London) - const isInitialEIP1559Block = londonHardforkBlock && number === londonHardforkBlock - if (isInitialEIP1559Block) { + if (number === londonHardforkBlock) { // Get baseFeePerGas from `paramByEIP` since 1559 not currently active on common baseFeePerGas = this.config.chainCommon.paramByEIP('gasConfig', 'initialBaseFee', 1559) ?? BigInt(0) // Set initial EIP1559 block gas limit to 2x parent gas limit per logic in `block.validateGasLimit` gasLimit = gasLimit * BigInt(2) - } else if (this.config.chainCommon.isActivatedEIP(1559)) { + } else if (this.config.chainCommon.isActivatedEIP(1559) === true) { baseFeePerGas = parentBlock.header.calcNextBaseFee() } @@ -266,7 +267,7 @@ export class Miner { const txs = await this.service.txPool.txsByPriceAndNonce(baseFeePerGas) this.config.logger.info( `Miner: Assembling block from ${txs.length} eligible txs ${ - baseFeePerGas ? `(baseFee: ${baseFeePerGas})` : '' + typeof baseFeePerGas === 'bigint' ? `(baseFee: ${baseFeePerGas})` : '' }` ) let index = 0 @@ -300,7 +301,7 @@ export class Miner { `Miner: Sealed block with ${block.transactions.length} txs ${ this.config.chainCommon.consensusType() === ConsensusType.ProofOfWork ? `(difficulty: ${block.header.difficulty})` - : `(${inTurn ? 'in turn' : 'not in turn'})` + : `(${inTurn === true ? 'in turn' : 'not in turn'})` }` ) this.assembling = false diff --git a/packages/client/lib/miner/pendingBlock.ts b/packages/client/lib/miner/pendingBlock.ts index 8a697098eb2..c0ca0babf1f 100644 --- a/packages/client/lib/miner/pendingBlock.ts +++ b/packages/client/lib/miner/pendingBlock.ts @@ -39,9 +39,8 @@ export class PendingBlock { async start(vm: VM, parentBlock: Block, headerData: Partial = {}) { const number = parentBlock.header.number + BigInt(1) const { gasLimit } = parentBlock.header - const baseFeePerGas = vm._common.isActivatedEIP(1559) - ? parentBlock.header.calcNextBaseFee() - : undefined + const baseFeePerGas = + vm._common.isActivatedEIP(1559) === true ? parentBlock.header.calcNextBaseFee() : undefined // Set the state root to ensure the resulting state // is based on the parent block's state @@ -124,9 +123,10 @@ export class PendingBlock { // Add new txs that the pool received const txs = ( await this.txPool.txsByPriceAndNonce((builder as any).headerData.baseFeePerGas) - ).filter( - (tx) => - !(builder as any).transactions.some((t: TypedTransaction) => t.hash().equals(tx.hash())) + ).filter((tx) => + (builder as any).transactions.some( + (t: TypedTransaction) => t.hash().equals(tx.hash()) === false + ) ) this.config.logger.info(`Pending: Adding ${txs.length} additional eligible txs`) let index = 0 diff --git a/packages/client/lib/net/peer/rlpxpeer.ts b/packages/client/lib/net/peer/rlpxpeer.ts index 2b40d256fa4..122a0626ecf 100644 --- a/packages/client/lib/net/peer/rlpxpeer.ts +++ b/packages/client/lib/net/peer/rlpxpeer.ts @@ -83,7 +83,7 @@ export class RlpxPeer extends Peer { const keys = versions.map((v: number) => name + String(v)) keys.forEach((key: any) => { const capability = devp2pCapabilities[key] - if (capability) { + if (typeof capability !== 'undefined') { capabilities.push(capability) } }) diff --git a/packages/client/lib/net/protocol/boundprotocol.ts b/packages/client/lib/net/protocol/boundprotocol.ts index 537e4eb8201..c742567144d 100644 --- a/packages/client/lib/net/protocol/boundprotocol.ts +++ b/packages/client/lib/net/protocol/boundprotocol.ts @@ -98,7 +98,7 @@ export class BoundProtocol { error = new Error(`Could not decode message ${message.name}: ${e}`) } const resolver = this.resolvers.get(incoming.code) - if (resolver) { + if (typeof resolver !== 'undefined') { clearTimeout(resolver.timeout) this.resolvers.delete(incoming.code) if (error) { @@ -159,7 +159,7 @@ export class BoundProtocol { resolve: null, reject: null, } - if (this.resolvers.get(message.response!)) { + if (typeof 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/net/protocol/flowcontrol.ts b/packages/client/lib/net/protocol/flowcontrol.ts index d548fc4a663..ebd24de5a25 100644 --- a/packages/client/lib/net/protocol/flowcontrol.ts +++ b/packages/client/lib/net/protocol/flowcontrol.ts @@ -1,4 +1,5 @@ import { Peer } from '../peer/peer' +import { isTruthy } from '@ethereumjs/util' interface Mrc { [key: string]: { @@ -66,7 +67,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 (params.last) { + if (isTruthy(params.last)) { // recharge BLE at rate of MRR when less than BL params.ble = Math.min(params.ble! + mrr * (now - params.last), bl) } @@ -88,7 +89,7 @@ export class FlowControl { handleRequest(peer: Peer, messageName: string, count: number): number { const now = Date.now() const params = this.out.get(peer.id) ?? {} - if (params.bv && params.last) { + if (isTruthy(params.bv) && isTruthy(params.last)) { 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 941e25887b0..6967e4e5218 100644 --- a/packages/client/lib/net/protocol/lesprotocol.ts +++ b/packages/client/lib/net/protocol/lesprotocol.ts @@ -1,4 +1,10 @@ -import { bigIntToBuffer, bufferToBigInt, bufferToInt, intToBuffer } from '@ethereumjs/util' +import { + bigIntToBuffer, + bufferToBigInt, + bufferToInt, + intToBuffer, + isTruthy, +} from '@ethereumjs/util' import { BlockHeader, BlockHeaderBuffer } from '@ethereumjs/block' import { Chain } from './../../blockchain' import { Message, Protocol, ProtocolOptions } from './protocol' @@ -174,7 +180,9 @@ export class LesProtocol extends Protocol { const nextFork = this.config.chainCommon.nextHardforkBlock(this.config.chainCommon.hardfork()) const forkID = [ Buffer.from(forkHash.slice(2), 'hex'), - nextFork ? bigIntToBuffer(nextFork) : Buffer.from([]), + typeof nextFork === 'bigint' && nextFork !== BigInt(0) + ? bigIntToBuffer(nextFork) + : Buffer.from([]), ] return { @@ -194,9 +202,9 @@ export class LesProtocol extends Protocol { * @param status status message payload */ decodeStatus(status: any): any { - this.isServer = !!status.serveHeaders + this.isServer = isTruthy(status.serveHeaders) const mrc: any = {} - if (status['flowControl/MRC']) { + if (isTruthy(status['flowControl/MRC'])) { for (let entry of status['flowControl/MRC']) { entry = entry.map((e: any) => bufferToInt(e)) mrc[entry[0]] = { base: entry[1], req: entry[2] } @@ -217,9 +225,9 @@ export class LesProtocol extends Protocol { serveHeaders: this.isServer, serveChainSince: status.serveChainSince ?? 0, serveStateSince: status.serveStateSince ?? 0, - txRelay: !!status.txRelay, - bl: status['flowControl/BL'] ? bufferToInt(status['flowControl/BL']) : undefined, - mrr: status['flowControl/MRR'] ? bufferToInt(status['flowControl/MRR']) : undefined, + txRelay: isTruthy(status.txRelay), + bl: isTruthy(status['flowControl/BL']) ? bufferToInt(status['flowControl/BL']) : undefined, + mrr: isTruthy(status['flowControl/MRR']) ? bufferToInt(status['flowControl/MRR']) : undefined, mrc: mrc, } } diff --git a/packages/client/lib/net/protocol/protocol.ts b/packages/client/lib/net/protocol/protocol.ts index d992db1221f..19fc756d9aa 100644 --- a/packages/client/lib/net/protocol/protocol.ts +++ b/packages/client/lib/net/protocol/protocol.ts @@ -1,3 +1,4 @@ +import { isTruthy } from '@ethereumjs/util' import { Config } from '../../config' import { Peer } from '../peer/peer' import { BoundProtocol } from './boundprotocol' @@ -71,12 +72,12 @@ export class Protocol { reject(new Error(`Handshake timed out after ${this.timeout}ms`)) }, this.timeout) const handleStatus = (status: any) => { - if (timeout) { + if (isTruthy(timeout) === true) { clearTimeout(timeout) resolve(this.decodeStatus(status)) } } - if (sender.status) { + if (isTruthy(sender.status) === true) { 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 556e5e8dfd2..25e64246ae1 100644 --- a/packages/client/lib/net/server/libp2pserver.ts +++ b/packages/client/lib/net/server/libp2pserver.ts @@ -135,7 +135,7 @@ export class Libp2pServer extends Server { */ isBanned(peerId: string): boolean { const expireTime = this.banned.get(peerId) - if (expireTime && expireTime > Date.now()) { + if (typeof expireTime === 'number' && expireTime > Date.now()) { return true } this.banned.delete(peerId) diff --git a/packages/client/lib/net/server/rlpxserver.ts b/packages/client/lib/net/server/rlpxserver.ts index 1493851c0c1..8fa0f287895 100644 --- a/packages/client/lib/net/server/rlpxserver.ts +++ b/packages/client/lib/net/server/rlpxserver.ts @@ -84,7 +84,7 @@ export class RlpxServer extends Server { */ getRlpxInfo() { // TODO: return undefined? note that this.rlpx might be undefined if called before initRlpx - if (!this.rlpx) { + if (this.rlpx === null || typeof this.rlpx === 'undefined') { return { enode: undefined, id: undefined, @@ -216,7 +216,7 @@ export class RlpxServer extends Server { resolve() }) - if (this.config.port) { + if (typeof this.config.port === 'number') { this.dpt.bind(this.config.port, '0.0.0.0') } }) @@ -245,7 +245,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: !!rlpxPeer._socket.server, + inbound: typeof rlpxPeer._socket?.server !== 'undefined', }) try { await peer.accept(rlpxPeer, this) @@ -270,8 +270,7 @@ export class RlpxServer extends Server { }) this.rlpx.on('peer:error', (rlpxPeer: any, error: Error) => { - const peerId = rlpxPeer && rlpxPeer.getId() - if (!peerId) { + if (typeof rlpxPeer?.getId() === 'undefined') { return this.error(error) } this.error(error) @@ -287,7 +286,7 @@ export class RlpxServer extends Server { resolve() }) - if (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/net/server/server.ts b/packages/client/lib/net/server/server.ts index fb48ee9f97e..f1f888be262 100644 --- a/packages/client/lib/net/server/server.ts +++ b/packages/client/lib/net/server/server.ts @@ -41,8 +41,9 @@ export class Server { */ constructor(options: ServerOptions) { this.config = options.config - this.key = options.key ? parseKey(options.key) : this.config.key - this.bootnodes = options.bootnodes ? parseMultiaddrs(options.bootnodes) : [] + this.key = typeof options.key !== 'undefined' ? parseKey(options.key) : this.config.key + this.bootnodes = + typeof 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 a8672551237..0a39f576222 100644 --- a/packages/client/lib/rpc/modules/engine.ts +++ b/packages/client/lib/rpc/modules/engine.ts @@ -1,6 +1,6 @@ import { Block, HeaderData } from '@ethereumjs/block' import { TransactionFactory, TypedTransaction } from '@ethereumjs/tx' -import { bufferToHex, toBuffer, zeros } from '@ethereumjs/util' +import { bufferToHex, isFalsy, toBuffer, zeros } from '@ethereumjs/util' import { RLP } from 'rlp' import { Trie } from '@ethereumjs/trie' import { Hardfork } from '@ethereumjs/common' @@ -270,7 +270,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 (!this.service.execution) { + if (isFalsy(this.service.execution)) { throw Error('execution required for engine module') } this.execution = this.service.execution @@ -372,8 +372,8 @@ export class Engine { const blockExists = await validBlock(toBuffer(blockHash), this.chain) if (blockExists) { - const isBlockExecuted = await this.vm.stateManager.hasStateRoot!(blockExists.header.stateRoot) - if (isBlockExecuted) { + const isBlockExecuted = await this.vm.stateManager.hasStateRoot(blockExists.header.stateRoot) + if (isBlockExecuted === true) { const response = { status: Status.VALID, latestValidHash: blockHash, @@ -386,9 +386,9 @@ export class Engine { try { const parent = await this.chain.getBlock(toBuffer(parentHash)) - const isBlockExecuted = await this.vm.stateManager.hasStateRoot!(parent.header.stateRoot) + 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 === false) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } if (!parent._common.gteHardfork(Hardfork.Merge)) { @@ -407,9 +407,10 @@ export class Engine { if (!this.service.beaconSync && !this.config.disableBeaconSync) { await this.service.switchToBeaconSync() } - const status = (await this.service.beaconSync?.extendChain(block)) - ? Status.SYNCING - : Status.ACCEPTED + const status = + (await this.service.beaconSync?.extendChain(block)) === true + ? Status.SYNCING + : Status.ACCEPTED if (status === Status.ACCEPTED) { // Stash the block for a potential forced forkchoice update to it later. this.remoteBlocks.set(block.hash().toString('hex'), block) @@ -488,7 +489,7 @@ export class Engine { headBlock = (await this.service.beaconSync?.skeleton.getBlockByHash(toBuffer(headBlockHash))) ?? (this.remoteBlocks.get(headBlockHash.slice(2)) as Block) - if (!headBlock) { + if (isFalsy(headBlock)) { this.config.logger.debug(`Forkchoice requested unknown head hash=${short(headBlockHash)}`) const payloadStatus = { status: Status.SYNCING, @@ -540,8 +541,8 @@ export class Engine { if (this.chain.headers.latest && this.chain.headers.latest.number < headBlock.header.number) { try { const parent = await this.chain.getBlock(toBuffer(headBlock.header.parentHash)) - const isBlockExecuted = await this.vm.stateManager.hasStateRoot!(parent.header.stateRoot) - if (!isBlockExecuted) { + const isBlockExecuted = await this.vm.stateManager.hasStateRoot(parent.header.stateRoot) + if (isBlockExecuted === false) { throw new Error(`Parent block not yet executed number=${parent.header.number}`) } parentBlocks = await recursivelyFindParents( @@ -570,7 +571,9 @@ export class Engine { const timeDiff = new Date().getTime() / 1000 - Number(headBlock.header.timestamp) if ( - (!this.config.syncTargetHeight || this.config.syncTargetHeight < headBlock.header.number) && + (typeof this.config.syncTargetHeight === 'undefined' || + this.config.syncTargetHeight === BigInt(0) || + this.config.syncTargetHeight < headBlock.header.number) && timeDiff < 30 ) { this.config.synchronized = true diff --git a/packages/client/lib/rpc/modules/eth.ts b/packages/client/lib/rpc/modules/eth.ts index 4389b147aff..bf1f393349f 100644 --- a/packages/client/lib/rpc/modules/eth.ts +++ b/packages/client/lib/rpc/modules/eth.ts @@ -239,10 +239,10 @@ const jsonRpcReceipt = async ( receipt.logs.map((l, i) => jsonRpcLog(l, block, tx, txIndex, logIndex + i)) ), logsBloom: bufferToHex(receipt.bitvector), - root: (receipt as PreByzantiumTxReceipt).stateRoot + root: Buffer.isBuffer((receipt as PreByzantiumTxReceipt).stateRoot) ? bufferToHex((receipt as PreByzantiumTxReceipt).stateRoot) : undefined, - status: (receipt as PostByzantiumTxReceipt).status + status: Buffer.isBuffer((receipt as PostByzantiumTxReceipt).status) ? intToHex((receipt as PostByzantiumTxReceipt).status) : undefined, }) @@ -433,7 +433,7 @@ export class Eth { const [transaction, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -444,12 +444,12 @@ export class Eth { try { const runCallOpts = { - caller: from ? Address.fromString(from) : undefined, - to: to ? Address.fromString(to) : undefined, + caller: typeof from === 'string' ? Address.fromString(from) : undefined, + to: typeof to === 'string' ? Address.fromString(to) : undefined, gasLimit: toType(gasLimit, TypeOutput.BigInt), gasPrice: toType(gasPrice, TypeOutput.BigInt), value: toType(value, TypeOutput.BigInt), - data: data ? toBuffer(data) : undefined, + data: typeof data === 'string' ? toBuffer(data) : undefined, } const { execResult } = await vm.evm.runCall(runCallOpts) return bufferToHex(execResult.returnValue) @@ -491,14 +491,14 @@ export class Eth { const [transaction, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } const vm = await this._vm.copy() await vm.stateManager.setStateRoot(block.header.stateRoot) - if (!transaction.gas) { + if (typeof 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 @@ -508,7 +508,8 @@ export class Eth { const tx = Transaction.fromTxData(txData, { common: vm._common, freeze: false }) // set from address - const from = transaction.from ? Address.fromString(transaction.from) : Address.zero() + const from = + typeof transaction.from === 'string' ? Address.fromString(transaction.from) : Address.zero() tx.getSenderAddress = () => { return from } @@ -540,7 +541,7 @@ export class Eth { const address = Address.fromString(addressHex) const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -609,7 +610,7 @@ export class Eth { const [addressHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -632,7 +633,7 @@ export class Eth { const [addressHex, positionHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -643,7 +644,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 storage + return typeof storage !== 'undefined' && storage !== null ? bufferToHex( setLengthLeft(Buffer.from(RLP.decode(Uint8Array.from(storage)) as Uint8Array), 32) ) @@ -684,7 +685,7 @@ export class Eth { const [addressHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -797,7 +798,7 @@ export class Eth { } } let from: Block, to: Block - if (blockHash) { + if (typeof blockHash === 'string') { try { from = to = await this._chain.getBlock(toBuffer(blockHash)) } catch (error: any) { @@ -856,7 +857,7 @@ export class Eth { } }) let addrs - if (address) { + if (typeof address === 'string') { if (Array.isArray(address)) { addrs = address.map((a) => toBuffer(a)) } else { @@ -888,7 +889,10 @@ export class Eth { const common = this.client.config.chainCommon.copy() const { syncTargetHeight } = this.client.config - if (!syncTargetHeight && !this.client.config.mine) { + if ( + (typeof 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)`, @@ -896,7 +900,7 @@ export class Eth { } // Set the tx common to an appropriate HF to create a tx // with matching HF rules - if (syncTargetHeight) { + if (typeof syncTargetHeight === 'bigint' && syncTargetHeight > BigInt(0)) { common.setHardforkByBlockNumber(syncTargetHeight) } @@ -957,7 +961,7 @@ export class Eth { const [addressHex, slotsHex, blockOpt] = params const block = await getBlockByOption(blockOpt, this._chain) - if (!this._vm) { + if (typeof this._vm === 'undefined') { throw new Error('missing vm') } @@ -996,7 +1000,7 @@ export class Eth { const startingBlock = bigIntToHex(synchronizer.startingBlock) let highestBlock - if (syncTargetHeight) { + if (typeof syncTargetHeight === 'bigint' && syncTargetHeight > BigInt(0)) { highestBlock = bigIntToHex(syncTargetHeight) } else { const bestPeer = await synchronizer.best() diff --git a/packages/client/lib/rpc/util/CLConnectionManager.ts b/packages/client/lib/rpc/util/CLConnectionManager.ts index c31a8f07d6c..630e3374d99 100644 --- a/packages/client/lib/rpc/util/CLConnectionManager.ts +++ b/packages/client/lib/rpc/util/CLConnectionManager.ts @@ -79,11 +79,11 @@ export class CLConnectionManager { maximumFractionDigits: 1, }) - if (this.config.chainCommon.gteHardfork(Hardfork.MergeForkIdTransition)) { + if (this.config.chainCommon.gteHardfork(Hardfork.MergeForkIdTransition) === true) { this.start() } else { this.config.events.on(Event.CHAIN_UPDATED, () => { - if (this.config.chainCommon.gteHardfork(Hardfork.MergeForkIdTransition)) { + if (this.config.chainCommon.gteHardfork(Hardfork.MergeForkIdTransition) === true) { this.start() } }) @@ -149,7 +149,7 @@ export class CLConnectionManager { if (update.headBlock) { msg += ` timestampDiff=${this.timeDiffStr(update.headBlock)}` } - if (update.error) { + if (typeof update.error !== 'undefined') { msg += ` error=${update.error}` } return msg diff --git a/packages/client/lib/rpc/validation.ts b/packages/client/lib/rpc/validation.ts index df0e192414a..3113d2cf25f 100644 --- a/packages/client/lib/rpc/validation.ts +++ b/packages/client/lib/rpc/validation.ts @@ -1,4 +1,5 @@ import { INVALID_PARAMS } from './error-code' +import { isFalsy, isTruthy } from '@ethereumjs/util' /** * middleware for parameters validation @@ -19,10 +20,10 @@ export function middleware(method: any, requiredParamsCount: number, validators: } for (let i = 0; i < validators.length; i++) { - if (validators[i]) { + if (typeof validators[i] !== 'undefined') { for (let j = 0; j < validators[i].length; j++) { const error = validators[i][j](params, i) - if (error) { + if (typeof error !== 'undefined') { return reject(error) } } @@ -196,7 +197,7 @@ export const validators = { const tx = params[index] for (const field of requiredFields) { - if (!tx[field]) { + if (typeof tx[field] === 'undefined') { return { code: INVALID_PARAMS, message: `invalid argument ${index}: required field ${field}`, @@ -205,21 +206,21 @@ export const validators = { } const validate = (field: any, validator: Function) => { - if (!field) return + if (isFalsy(field) === true) return const v = validator([field], 0) - if (v) return v + if (isTruthy(v) === true) return v } // validate addresses for (const field of [tx.to, tx.from]) { const v = validate(field, this.address) - if (v) return v + if (isTruthy(v) === true) return v } - // valdiate hex + // validate hex for (const field of [tx.gas, tx.gasPrice, tx.value, tx.data]) { const v = validate(field, this.hex) - if (v) return v + if (isTruthy(v) === true) return v } } } @@ -245,7 +246,7 @@ export const validators = { for (const [key, validator] of Object.entries(form)) { const value = params[index][key] const result = validator([value], 0) - if (result) { + if (typeof result !== 'undefined') { // add key to message for context const originalMessage = result.message.split(':') const message = `invalid argument ${index} for key '${key}':${originalMessage[1]}` @@ -275,7 +276,7 @@ export const validators = { } for (const value of params[index]) { const result = validator([value], 0) - if (result) return result + if (typeof result !== 'undefined') return result } } } @@ -312,7 +313,7 @@ export const validators = { get optional() { return (validator: any) => { return (params: any, index: number) => { - if (!params[index]) { + if (isFalsy(params[index]) === true) { return } return validator(params, index) @@ -330,7 +331,7 @@ export const validators = { get either() { return (...validators: any) => { return (params: any, index: number) => { - if (!params[index]) { + if (isFalsy(params[index]) === true) { 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 baed08efaaa..ded061ac141 100644 --- a/packages/client/lib/service/fullethereumservice.ts +++ b/packages/client/lib/service/fullethereumservice.ts @@ -12,6 +12,7 @@ import { Miner } from '../miner' import { VMExecution } from '../execution' import type { Block } from '@ethereumjs/block' +import { isFalsy, isTruthy } from '@ethereumjs/util' interface FullEthereumServiceOptions extends EthereumServiceOptions { /** Serve LES requests (default: false) */ @@ -51,7 +52,7 @@ export class FullEthereumService extends EthereumService { service: this, }) - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { if (!this.config.disableBeaconSync) { void this.switchToBeaconSync() } @@ -209,8 +210,8 @@ export class FullEthereumService extends EthereumService { const { reqId, block, max, skip, reverse } = message.data if (typeof block === 'bigint') { if ( - (reverse && block > this.chain.headers.height) || - (!reverse && block + BigInt(max * skip) > this.chain.headers.height) + (isTruthy(reverse) && block > this.chain.headers.height) || + (isFalsy(reverse) && block + BigInt(max * skip) > this.chain.headers.height) ) { // Don't respond to requests greater than the current height return @@ -226,7 +227,7 @@ export class FullEthereumService extends EthereumService { const bodies = blocks.map((block) => block.raw().slice(1)) peer.eth!.send('BlockBodies', { reqId, bodies }) } else if (message.name === 'NewBlockHashes') { - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { this.config.logger.debug( `Dropping peer ${peer.id} for sending NewBlockHashes after merge (EIP-3675)` ) @@ -237,7 +238,7 @@ export class FullEthereumService extends EthereumService { } else if (message.name === 'Transactions') { await this.txPool.handleAnnouncedTxs(message.data, peer, this.pool) } else if (message.name === 'NewBlock') { - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { this.config.logger.debug( `Dropping peer ${peer.id} for sending NewBlock after merge (EIP-3675)` ) @@ -260,7 +261,7 @@ export class FullEthereumService extends EthereumService { let receiptsSize = 0 for (const hash of hashes) { const blockReceipts = await receiptsManager.getReceipts(hash, true, true) - if (!blockReceipts) continue + if (isFalsy(blockReceipts)) continue receipts.push(...blockReceipts) const receiptsBuffer = Buffer.concat(receipts.map((r) => encodeReceipt(r, r.txType))) receiptsSize += Buffer.byteLength(receiptsBuffer) @@ -288,8 +289,8 @@ export class FullEthereumService extends EthereumService { } else { if (typeof block === 'bigint') { if ( - (reverse && block > this.chain.headers.height) || - (!reverse && block + BigInt(max * skip) > this.chain.headers.height) + (isTruthy(reverse) && block > this.chain.headers.height) || + (isFalsy(reverse) && 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 4ca194bf3bc..be6cfe1c3db 100644 --- a/packages/client/lib/service/txpool.ts +++ b/packages/client/lib/service/txpool.ts @@ -5,7 +5,7 @@ import { Transaction, TypedTransaction, } from '@ethereumjs/tx' -import { Address, bufferToHex } from '@ethereumjs/util' +import { Address, bufferToHex, isFalsy, isTruthy } from '@ethereumjs/util' import { Config } from '../config' import { Peer } from '../net/peer' import type { VM } from '@ethereumjs/vm' @@ -193,7 +193,7 @@ export class TxPool { * Checks if tx pool should be started */ checkRunState() { - if (this.running || !this.config.syncTargetHeight) return + if (this.running || isFalsy(this.config.syncTargetHeight)) return // If height gte target, we are close enough to the // head of the chain that the tx pool can be started const target = @@ -264,7 +264,7 @@ export class TxPool { } } const block = await this.service.chain.getCanonicalHeadHeader() - if (block.baseFeePerGas) { + if (isTruthy(block.baseFeePerGas)) { 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)` @@ -502,7 +502,9 @@ export class TxPool { // Remove from pending list regardless if tx is in result this.pending = this.pending.filter((hash) => !reqHashesStr.includes(hash)) - if (!getPooledTxs) return + if (isFalsy(getPooledTxs)) { + return + } const [_, txs] = getPooledTxs this.config.logger.debug(`TxPool: received requested txs number=${txs.length}`) @@ -573,7 +575,7 @@ export class TxPool { */ private normalizedGasPrice(tx: TypedTransaction, baseFee?: bigint) { const supports1559 = tx.supports(Capability.EIP1559FeeMarket) - if (baseFee) { + if (isTruthy(baseFee)) { if (supports1559) { return (tx as FeeMarketEIP1559Transaction).maxPriorityFeePerGas } else { @@ -645,7 +647,7 @@ export class TxPool { // therefore no txs from this address are currently executable continue } - if (baseFee) { + if (isTruthy(baseFee)) { // 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 876417fe069..0f71e3d02ed 100644 --- a/packages/client/lib/sync/beaconsync.ts +++ b/packages/client/lib/sync/beaconsync.ts @@ -6,6 +6,7 @@ import type { Block } from '@ethereumjs/block' import type { Peer } from '../net/peer/peer' import { errSyncReorged, Skeleton } from './skeleton' import type { VMExecution } from '../execution' +import { isTruthy } from '@ethereumjs/util' interface BeaconSynchronizerOptions extends SynchronizerOptions { /** Skeleton chain */ @@ -55,7 +56,7 @@ export class BeaconSynchronizer extends Synchronizer { this.config.events.on(Event.CHAIN_UPDATED, this.runExecution) const subchain = this.skeleton.bounds() - if (subchain) { + if (isTruthy(subchain) === true) { const { head, tail, next } = subchain this.config.logger.info(`Resuming beacon sync head=${head} tail=${tail} next=${short(next)}`) } @@ -196,7 +197,10 @@ export class BeaconSynchronizer extends Synchronizer { if (!latest) return false const height = latest.number - if (!this.config.syncTargetHeight || this.config.syncTargetHeight < latest.number) { + if ( + typeof this.config.syncTargetHeight === 'undefined' || + this.config.syncTargetHeight < latest.number + ) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } @@ -204,11 +208,10 @@ export class BeaconSynchronizer extends Synchronizer { const { tail } = this.skeleton.bounds() const first = tail - BigInt(1) // Sync from tail to next subchain or chain height + const subChainHead = (this.skeleton as any).status.progress.subchains[1]?.head const count = first - - ((this.skeleton as any).status.progress.subchains[1]?.head - ? (this.skeleton as any).status.progress.subchains[1].head - BigInt(1) - : this.chain.blocks.height) + (isTruthy(subChainHead) === true ? subChainHead - BigInt(1) : this.chain.blocks.height) if (count > BigInt(0) && (!this.fetcher || this.fetcher.errored)) { this.fetcher = new ReverseBlockFetcher({ config: this.config, @@ -249,7 +252,7 @@ export class BeaconSynchronizer extends Synchronizer { // Execute single block when within 50 blocks of head, // otherwise run execution in batch of 50 blocks when filling canonical chain. if ( - (this.skeleton.bounds() && + (isTruthy(this.skeleton.bounds()) === true && this.chain.blocks.height > this.skeleton.bounds().head - BigInt(50)) || this.chain.blocks.height % BigInt(50) === BigInt(0) ) { diff --git a/packages/client/lib/sync/fetcher/blockfetcher.ts b/packages/client/lib/sync/fetcher/blockfetcher.ts index 230aa2b6981..c9a08831894 100644 --- a/packages/client/lib/sync/fetcher/blockfetcher.ts +++ b/packages/client/lib/sync/fetcher/blockfetcher.ts @@ -1,5 +1,5 @@ import { Block, BlockBuffer } from '@ethereumjs/block' -import { KECCAK256_RLP, KECCAK256_RLP_ARRAY } from '@ethereumjs/util' +import { isFalsy, KECCAK256_RLP, KECCAK256_RLP_ARRAY } from '@ethereumjs/util' import { Peer } from '../../net/peer' import { Job } from './types' import { BlockFetcherBase, JobTask, BlockFetcherOptions } from './blockfetcherbase' @@ -40,14 +40,14 @@ export class BlockFetcher extends BlockFetcherBase { max: count, reverse: this.reverse, }) - if (!headersResult || headersResult[1].length === 0) { + if (isFalsy(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 (!bodiesResult || bodiesResult[1].length === 0) { + if (isFalsy(bodiesResult) || 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 9b4d0e02a6d..d97352a5c34 100644 --- a/packages/client/lib/sync/fetcher/fetcher.ts +++ b/packages/client/lib/sync/fetcher/fetcher.ts @@ -7,6 +7,7 @@ import { Config } from '../../config' import { Event } from '../../types' import { Job } from './types' import { JobTask as BlockFetcherJobTask } from './blockfetcherbase' +import { isTruthy } from '@ethereumjs/util' export interface FetcherOptions { /* Common chain config*/ @@ -146,7 +147,7 @@ export abstract class Fetcher extends Readable if (this.running) { // If the job was already dequeued, for example coming from writer pipe, processed // needs to be decreased - if (dequeued) this.processed-- + if (dequeued === true) this.processed-- this.in.insert({ ...job, @@ -261,7 +262,7 @@ export abstract class Fetcher extends Readable dequeued?: boolean ) { const jobItems = job instanceof Array ? job : [job] - if (irrecoverable) { + if (irrecoverable === true) { this.pool.ban(jobItems[0].peer!, this.banTime) } else { void this.wait().then(() => { @@ -368,7 +369,7 @@ export abstract class Fetcher extends Readable if (this.running) { this.config.events.emit(Event.SYNC_FETCHER_ERROR, error, job?.task, job?.peer) } - if (irrecoverable) { + if (irrecoverable === true) { this.running = false this.errored = error this.clear() @@ -395,7 +396,7 @@ export abstract class Fetcher extends Readable } catch (error: any) { this.config.logger.warn(`Error storing received block or header result: ${error}`) if ( - error.message.includes('could not find parent header') && + (error.message as string).includes('could not find parent header') && this.isBlockFetcherJobTask(jobItems[0].task) ) { // Non-fatal error: ban peer and re-enqueue job. @@ -460,7 +461,7 @@ export abstract class Fetcher extends Readable this.nextTasks() while (this.running) { - if (!this.next()) { + if (this.next() === false) { if (this.finished === this.total && this.destroyWhenDone) { this.push(null) } @@ -532,6 +533,6 @@ export abstract class Fetcher extends Readable * @param task */ private isBlockFetcherJobTask(task: JobTask | BlockFetcherJobTask): task is BlockFetcherJobTask { - return task && 'first' in task && 'count' in task + return isTruthy(task) && 'first' in task && 'count' in task } } diff --git a/packages/client/lib/sync/fullsync.ts b/packages/client/lib/sync/fullsync.ts index 64f589a5328..4d539a616a0 100644 --- a/packages/client/lib/sync/fullsync.ts +++ b/packages/client/lib/sync/fullsync.ts @@ -7,6 +7,7 @@ import { BlockFetcher } from './fetcher' import { VMExecution } from '../execution' import type { Block } from '@ethereumjs/block' import type { TxPool } from '../service/txpool' +import { isFalsy, isTruthy } from '@ethereumjs/util' interface FullSynchronizerOptions extends SynchronizerOptions { /** Tx Pool */ @@ -87,7 +88,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 (peer.eth?.status) { + if (typeof peer.eth !== 'undefined' && isTruthy(peer.eth.status)) { const td = peer.eth.status.td if ( (!best && td >= this.chain.blocks.td) || @@ -115,7 +116,7 @@ export class FullSynchronizer extends Synchronizer { * Checks if tx pool should be started */ checkTxPoolState() { - if (!this.config.syncTargetHeight || this.txPool.running) { + if (isFalsy(this.config.syncTargetHeight) || this.txPool.running) { return } // If height gte target, we are close enough to the @@ -137,7 +138,7 @@ export class FullSynchronizer extends Synchronizer { if (!latest) return false const height = latest.number - if (!this.config.syncTargetHeight || this.config.syncTargetHeight < latest.number) { + if (isFalsy(this.config.syncTargetHeight) || this.config.syncTargetHeight < latest.number) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } @@ -174,7 +175,7 @@ export class FullSynchronizer extends Synchronizer { * Process blocks fetched from the fetcher. */ async processBlocks(blocks: Block[]) { - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { if (this.fetcher !== null) { // If we are beyond the merge block we should stop the fetcher this.config.logger.info('Merge hardfork reached, stopping block fetcher') @@ -192,9 +193,10 @@ export class FullSynchronizer extends Synchronizer { const first = BigInt(blocks[0].header.number) const last = BigInt(blocks[blocks.length - 1].header.number) const hash = short(blocks[0].hash()) - const baseFeeAdd = this.config.chainCommon.gteHardfork(Hardfork.London) - ? `baseFee=${blocks[0].header.baseFeePerGas} ` - : '' + const baseFeeAdd = + this.config.chainCommon.gteHardfork(Hardfork.London) === true + ? `baseFee=${blocks[0].header.baseFeePerGas} ` + : '' let attentionHF: string | null = null const nextHFBlockNum = this.config.chainCommon.nextHardforkBlock() @@ -207,7 +209,7 @@ export class FullSynchronizer extends Synchronizer { } else { if ( this.config.chainCommon.hardfork() === Hardfork.MergeForkIdTransition && - !this.config.chainCommon.gteHardfork(Hardfork.Merge) + this.config.chainCommon.gteHardfork(Hardfork.Merge) === false ) { const mergeTD = this.config.chainCommon.hardforkTD(Hardfork.Merge)! const td = this.chain.blocks.td @@ -294,12 +296,12 @@ export class FullSynchronizer extends Synchronizer { // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#block-propagation const numPeersToShareWith = Math.floor(Math.sqrt(this.pool.peers.length)) await this.sendNewBlock(block, this.pool.peers.slice(0, numPeersToShareWith)) - if (this.chain.blocks.latest?.hash().equals(block.header.parentHash)) { + if (this.chain.blocks.latest?.hash().equals(block.header.parentHash) === true) { // If new block is child of current chain tip, insert new block into chain await this.chain.putBlocks([block]) // Check if new sync target height can be set const blockNumber = block.header.number - if (!this.config.syncTargetHeight || blockNumber > this.config.syncTargetHeight) { + if (isFalsy(this.config.syncTargetHeight) || blockNumber > this.config.syncTargetHeight) { this.config.syncTargetHeight = blockNumber } } else { @@ -332,7 +334,8 @@ export class FullSynchronizer extends Synchronizer { } // Check if new sync target height can be set if (newSyncHeight && blockNumber <= newSyncHeight[1]) continue - if (this.config.syncTargetHeight && blockNumber <= this.config.syncTargetHeight) continue + if (isTruthy(this.config.syncTargetHeight) && blockNumber <= this.config.syncTargetHeight) + continue newSyncHeight = value } diff --git a/packages/client/lib/sync/lightsync.ts b/packages/client/lib/sync/lightsync.ts index 01654cd9281..147792f2876 100644 --- a/packages/client/lib/sync/lightsync.ts +++ b/packages/client/lib/sync/lightsync.ts @@ -5,6 +5,7 @@ import { Synchronizer, SynchronizerOptions } from './sync' import { HeaderFetcher } from './fetcher' import { Event } from '../types' import type { BlockHeader } from '@ethereumjs/block' +import { isFalsy } from '@ethereumjs/util' /** * Implements an ethereum light sync synchronizer @@ -89,7 +90,7 @@ export class LightSynchronizer extends Synchronizer { if (!latest) return false const height = peer!.les!.status.headNum - if (!this.config.syncTargetHeight || this.config.syncTargetHeight < height) { + if (isFalsy(this.config.syncTargetHeight) || this.config.syncTargetHeight < height) { this.config.syncTargetHeight = height this.config.logger.info(`New sync target height=${height} hash=${short(latest.hash())}`) } @@ -133,9 +134,10 @@ export class LightSynchronizer extends Synchronizer { } const first = headers[0].number const hash = short(headers[0].hash()) - const baseFeeAdd = this.config.chainCommon.gteHardfork(Hardfork.London) - ? `baseFee=${headers[0].baseFeePerGas} ` - : '' + const baseFeeAdd = + this.config.chainCommon.gteHardfork(Hardfork.London) === true + ? `baseFee=${headers[0].baseFeePerGas} ` + : '' this.config.logger.info( `Imported headers count=${headers.length} number=${first} hash=${hash} ${baseFeeAdd}peers=${this.pool.size}` ) diff --git a/packages/client/lib/sync/skeleton.ts b/packages/client/lib/sync/skeleton.ts index 4210787e92c..e6822bf6715 100644 --- a/packages/client/lib/sync/skeleton.ts +++ b/packages/client/lib/sync/skeleton.ts @@ -165,7 +165,7 @@ export class Skeleton extends MetaDBManager { const lastchain = this.status.progress.subchains[0] if (lastchain.head === headchain.tail - BigInt(1)) { const lasthead = await this.getBlock(lastchain.head) - if (lasthead?.hash().equals(head.header.parentHash)) { + if (lasthead?.hash().equals(head.header.parentHash) === true) { this.config.logger.debug( `Extended skeleton subchain with new head=${headchain.tail} tail=${lastchain.tail}` ) @@ -208,7 +208,7 @@ export class Skeleton extends MetaDBManager { // once more, ignore it instead of tearing down sync for a noop. if (lastchain.head === lastchain.tail) { const block = await this.getBlock(number) - if (block?.hash().equals(head.hash())) { + if (block?.hash().equals(head.hash()) === true) { return false } } @@ -326,7 +326,7 @@ export class Skeleton extends MetaDBManager { if ( (await this.getBlock(this.status.progress.subchains[1].head)) ?.hash() - .equals(this.status.progress.subchains[0].next) + .equals(this.status.progress.subchains[0].next) === true ) { this.config.logger.debug( `Previous subchain merged head=${head} tail=${tail} next=${short(next)}` diff --git a/packages/client/lib/sync/sync.ts b/packages/client/lib/sync/sync.ts index fb81f471591..b35a4c0d3b3 100644 --- a/packages/client/lib/sync/sync.ts +++ b/packages/client/lib/sync/sync.ts @@ -7,6 +7,7 @@ import { Chain } from '../blockchain' import { Event } from '../types' import { BlockFetcher, HeaderFetcher, ReverseBlockFetcher } from './fetcher' import { short } from '../util' +import { isFalsy, isTruthy } from '@ethereumjs/util' export interface SynchronizerOptions { /* Config */ @@ -100,7 +101,7 @@ export abstract class Synchronizer { * Start synchronization */ async start(): Promise { - if (this.running || this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.running || this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { return false } this.running = true @@ -113,7 +114,7 @@ export abstract class Synchronizer { const timeout = setTimeout(() => { this.forceSync = true }, this.interval * 30) - while (this.running && !this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + while (this.running && this.config.chainCommon.gteHardfork(Hardfork.Merge) === false) { try { await this.sync() } catch (error: any) { @@ -134,7 +135,7 @@ export abstract class Synchronizer { * @emits {@link Event.SYNC_SYNCHRONIZED} */ updateSynchronizedState() { - if (!this.config.syncTargetHeight) { + if (isFalsy(this.config.syncTargetHeight)) { return } if (this.chain.headers.height >= this.config.syncTargetHeight) { @@ -172,7 +173,7 @@ export abstract class Synchronizer { const resolveSync = (height?: number) => { this.clearFetcher() resolve(true) - const heightStr = height ? ` height=${height}` : '' + const heightStr = isTruthy(height) ? ` height=${height}` : '' this.config.logger.debug( `Finishing up sync with the current fetcher${heightStr} }` @@ -231,7 +232,7 @@ export abstract class Synchronizer { * Reset synced status after a certain time with no chain updates */ _syncedStatusCheck() { - if (this.config.chainCommon.gteHardfork(Hardfork.Merge)) { + if (this.config.chainCommon.gteHardfork(Hardfork.Merge) === true) { return } diff --git a/packages/client/lib/util/index.ts b/packages/client/lib/util/index.ts index 630c14cad63..03304134a46 100644 --- a/packages/client/lib/util/index.ts +++ b/packages/client/lib/util/index.ts @@ -1,6 +1,7 @@ /** * @module util */ +import { isFalsy } from '@ethereumjs/util' import { platform } from 'os' import { version as packageVersion } from '../../package.json' @@ -8,7 +9,7 @@ export * from './parse' export * from './rpc' export function short(buf: Buffer | string): string { - if (!buf) return '' + if (isFalsy(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/util/parse.ts b/packages/client/lib/util/parse.ts index be6bb9f24f4..32a811bccf8 100644 --- a/packages/client/lib/util/parse.ts +++ b/packages/client/lib/util/parse.ts @@ -5,7 +5,9 @@ import { addHexPrefix, bigIntToHex, intToHex, + isFalsy, isHexPrefixed, + isTruthy, stripHexPrefix, } from '@ethereumjs/util' import type { MultiaddrLike } from '../types' @@ -17,7 +19,7 @@ import type { Common } from '@ethereumjs/common' * @param input comma separated string */ export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] { - if (!input) { + if (isFalsy(input)) { return [] } if (!Array.isArray(input) && typeof input === 'object') { @@ -43,7 +45,7 @@ export function parseMultiaddrs(input: MultiaddrLike): Multiaddr[] { // parse as object if (typeof s === 'object') { const { ip, port } = s as any - if (ip && port) { + if (isTruthy(ip) && isTruthy(port)) { return multiaddr(`/ip4/${ip}/tcp/${port}`) } } @@ -143,7 +145,7 @@ async function parseGethParams(json: any) { baseFeePerGas, }, bootstrapNodes: [], - consensus: config.clique + consensus: isTruthy(config.clique) ? { type: 'poa', algorithm: 'clique', @@ -200,7 +202,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 (name) { + if (typeof name !== 'undefined') { json.name = name } return parseGethParams(json) @@ -219,8 +221,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 = code ? addHexPrefix(code) : undefined - storage = storage ? Object.entries(storage) : undefined + code = isTruthy(code) ? addHexPrefix(code) : undefined + storage = isTruthy(storage) ? Object.entries(storage) : undefined state[address] = [balance, code, storage] as any } return state @@ -244,7 +246,11 @@ export function parseKey(input: string | Buffer) { */ export function setCommonForkHashes(common: Common, genesisHash: Buffer) { for (const hf of (common as any)._chainParams.hardforks) { - if (!hf.forkHash && hf.block !== undefined && (hf.block !== null || hf.td !== undefined)) { + if ( + isFalsy(hf.forkHash) && + typeof hf.block !== 'undefined' && + (hf.block !== null || typeof hf.td !== 'undefined') + ) { hf.forkHash = common.forkHash(hf.name, genesisHash) } } diff --git a/packages/client/lib/util/rpc.ts b/packages/client/lib/util/rpc.ts index 41252547ff2..9b660a8900e 100644 --- a/packages/client/lib/util/rpc.ts +++ b/packages/client/lib/util/rpc.ts @@ -7,6 +7,7 @@ import * as cors from 'cors' import { inspect } from 'util' import { RPCManager } from '../rpc' import { Logger } from '../logging' +import { isTruthy } from '@ethereumjs/util' type IncomingMessage = Connect.IncomingMessage const algorithm: TAlgorithm = 'HS256' @@ -43,7 +44,7 @@ export function inspectParams(params: any, shorten?: number) { colors: true, maxStringLength: 100, } as any) - if (shorten) { + if (isTruthy(shorten)) { inspected = inspected.replace(/\n/g, '').replace(/ {2}/g, ' ') if (inspected.length > shorten) { inspected = inspected.slice(0, shorten) + '...' @@ -74,10 +75,10 @@ export function createRPCServer( msg = `${request.method}${batchAddOn} responded with:\n${inspectParams(response)}` } else { msg = `${request.method}${batchAddOn} responded with: ` - if (response.result) { + if (isTruthy(response.result)) { msg += inspectParams(response, 125) } - if (response.error) { + if (isTruthy(response.error)) { msg += `error: ${response.error.message}` } } @@ -127,7 +128,7 @@ export function createRPCServer( ] const ethEngineSubsetMethods: { [key: string]: Function } = {} for (const method of ethMethodsToBeIncluded) { - if (ethMethods[method]) ethEngineSubsetMethods[method] = ethMethods[method] + if (isTruthy(ethMethods[method])) ethEngineSubsetMethods[method] = ethMethods[method] } methods = { ...ethEngineSubsetMethods, ...manager.getMethods(true) } break @@ -157,7 +158,7 @@ export function createRPCServerListener(opts: CreateRPCServerListenerOpts): Http const { server, withEngineMiddleware, rpcCors } = opts const app = Connect() - if (rpcCors) app.use(cors({ origin: rpcCors })) + if (isTruthy(rpcCors)) app.use(cors({ origin: rpcCors })) // GOSSIP_MAX_SIZE_BELLATRIX is proposed to be 10MiB app.use(jsonParser({ limit: '11mb' })) @@ -193,7 +194,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 (rpcCors) app.use(cors({ origin: rpcCors })) + if (isTruthy(rpcCors)) app.use(cors({ origin: rpcCors })) httpServer = createServer(app) } diff --git a/packages/client/test/cli/cli-libp2p.spec.ts b/packages/client/test/cli/cli-libp2p.spec.ts index dda5b43f384..30aefcdcbed 100644 --- a/packages/client/test/cli/cli-libp2p.spec.ts +++ b/packages/client/test/cli/cli-libp2p.spec.ts @@ -27,7 +27,7 @@ tape('[CLI] rpc', (t) => { const hasEnded = false child.stdout.on('data', async (data) => { - const message = data.toString() + const message: string = data.toString() if (message.includes('transport=libp2p')) { st.pass('libp2p server started') @@ -50,7 +50,7 @@ tape('[CLI] rpc', (t) => { ], ]) child2.stdout.on('data', async (data) => { - const message = data.toString() + const message: string = data.toString() if (message.includes('Peer added')) { st.pass('connected to peer over libp2p') child2.kill('SIGINT') @@ -62,13 +62,13 @@ tape('[CLI] rpc', (t) => { }) child.stderr.on('data', (data) => { - const message = data.toString() + const message: string = data.toString() st.fail(`stderr: ${message}`) end(child, hasEnded, st) }) child.on('close', (code) => { - if (code && code > 0) { + if (typeof code === 'number' && code > 0) { st.fail(`child process exited with code ${code}`) end(child, hasEnded, st) } diff --git a/packages/client/test/cli/cli-rpc.spec.ts b/packages/client/test/cli/cli-rpc.spec.ts index 242d152e59f..616f22b8d95 100644 --- a/packages/client/test/cli/cli-rpc.spec.ts +++ b/packages/client/test/cli/cli-rpc.spec.ts @@ -21,7 +21,7 @@ tape('[CLI] rpc', (t) => { const hasEnded = false child.stdout.on('data', async (data) => { - const message = data.toString() + const message: string = data.toString() if (message.includes('http://')) { // if http endpoint startup message detected, call http endpoint with RPC method const client = Client.http({ port: 8545 }) @@ -42,13 +42,13 @@ tape('[CLI] rpc', (t) => { }) child.stderr.on('data', (data) => { - const message = data.toString() + const message: string = data.toString() st.fail(`stderr: ${message}`) end(child, hasEnded, st) }) child.on('close', (code) => { - if (code && code > 0) { + if (typeof code === 'number' && code > 0) { st.fail(`child process exited with code ${code}`) end(child, hasEnded, st) } @@ -62,7 +62,7 @@ tape('[CLI] rpc', (t) => { const hasEnded = false child.stdout.on('data', async (data) => { - const message = data.toString() + const message: string = data.toString() if (message.includes('address=http://')) { st.fail('http endpoint should not be enabled') } @@ -76,13 +76,13 @@ tape('[CLI] rpc', (t) => { }) child.stderr.on('data', (data) => { - const message = data.toString() + const message: string = data.toString() st.fail(`stderr: ${message}`) end(child, hasEnded, st) }) child.on('close', (code) => { - if (code && code > 0) { + if (typeof code === 'number' && code > 0) { st.fail(`child process exited with code ${code}`) end(child, hasEnded, st) } diff --git a/packages/client/test/cli/cli-sync.spec.ts b/packages/client/test/cli/cli-sync.spec.ts index eb155a77f22..0b51d85e08f 100644 --- a/packages/client/test/cli/cli-sync.spec.ts +++ b/packages/client/test/cli/cli-sync.spec.ts @@ -22,7 +22,7 @@ tape('[CLI] sync', (t) => { } child.stdout.on('data', (data) => { - const message = data.toString() + const message: string = data.toString() // log message for easier debugging // eslint-disable-next-line no-console @@ -39,7 +39,7 @@ tape('[CLI] sync', (t) => { }) child.stderr.on('data', (data) => { - const message = data.toString() + const message: string = data.toString() if (message.includes('Possible EventEmitter memory leak detected')) { // This is okay. return @@ -49,7 +49,7 @@ tape('[CLI] sync', (t) => { }) child.on('close', (code) => { - if (code && code > 0) { + if (typeof code === 'number' && code > 0) { st.fail(`child process exited with code ${code}`) end() } diff --git a/packages/client/test/integration/merge.spec.ts b/packages/client/test/integration/merge.spec.ts index e101431ac05..bffe1dbae8c 100644 --- a/packages/client/test/integration/merge.spec.ts +++ b/packages/client/test/integration/merge.spec.ts @@ -7,7 +7,7 @@ import { ConsensusAlgorithm, Hardfork, } from '@ethereumjs/common' -import { Address } from '@ethereumjs/util' +import { Address, isFalsy, isTruthy } from '@ethereumjs/util' import { Config } from '../../lib/config' import { Chain } from '../../lib/blockchain' import { FullEthereumService } from '../../lib/service' @@ -141,7 +141,7 @@ tape('[Integration:Merge]', async (t) => { remoteService.config.events.on(Event.CHAIN_UPDATED, async () => { const { height, td } = remoteService.chain.headers if (td > targetTTD) { - if (!terminalHeight) { + if (isFalsy(terminalHeight)) { terminalHeight = height } t.equal( @@ -155,7 +155,7 @@ tape('[Integration:Merge]', async (t) => { await destroy(remoteServer, remoteService) t.end() } - if (terminalHeight && terminalHeight < height) { + if (isTruthy(terminalHeight) && terminalHeight < height) { t.fail('chain should not exceed merge terminal block') } }) diff --git a/packages/client/test/integration/mocks/mockpeer.ts b/packages/client/test/integration/mocks/mockpeer.ts index e898b2c4c5d..355cdcf1b5d 100644 --- a/packages/client/test/integration/mocks/mockpeer.ts +++ b/packages/client/test/integration/mocks/mockpeer.ts @@ -63,7 +63,7 @@ export class MockPeer extends Peer { }) await Promise.all( this.protocols.map(async (p) => { - if (!stream.protocols.includes(`${p.name}/${p.versions[0]}`)) return + if (!(stream.protocols as string[]).includes(`${p.name}/${p.versions[0]}`)) return await p.open() await this.bindProtocol(p, new MockSender(p.name, pushableFn, receiver)) }) diff --git a/packages/client/test/integration/mocks/mockserver.ts b/packages/client/test/integration/mocks/mockserver.ts index c5ca7bc3f08..3c2c5e12f7c 100644 --- a/packages/client/test/integration/mocks/mockserver.ts +++ b/packages/client/test/integration/mocks/mockserver.ts @@ -1,3 +1,4 @@ +import { isTruthy } from '@ethereumjs/util' import { Server, ServerOptions } from '../../../lib/net/server' import { Event } from '../../../lib/types' import { MockPeer } from './mockpeer' @@ -45,7 +46,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 (servers[this.location]) { + while (isTruthy(servers[this.location])) { await destroyServer(this.location) } await super.stop() @@ -84,7 +85,7 @@ export class MockServer extends Server { disconnect(id: string) { const peer = this.peers[id] - if (peer) this.config.events.emit(Event.PEER_DISCONNECTED, peer) + if (isTruthy(peer)) this.config.events.emit(Event.PEER_DISCONNECTED, peer) } async wait(delay?: number) { diff --git a/packages/client/test/integration/mocks/network.ts b/packages/client/test/integration/mocks/network.ts index cc40429c9ad..a5354f2a926 100644 --- a/packages/client/test/integration/mocks/network.ts +++ b/packages/client/test/integration/mocks/network.ts @@ -1,3 +1,4 @@ +import { isTruthy } from '@ethereumjs/util' import { EventEmitter } from 'events' const DuplexPair = require('it-pair/duplex') @@ -24,7 +25,7 @@ interface ServerDetails { export const servers: ServerDetails = {} export function createServer(location: string) { - if (servers[location]) { + if (isTruthy(servers[location])) { throw new Error(`Already running a server at ${location}`) } servers[location] = { @@ -37,9 +38,9 @@ export function createServer(location: string) { } export function destroyStream(id: string, location: string) { - if (servers[location]) { + if (isTruthy(servers[location])) { const stream = servers[location].streams[id] - if (stream) { + if (isTruthy(stream)) { delete servers[location].streams[id] } } @@ -56,7 +57,7 @@ export async function destroyServer(location: string) { } export function createStream(id: string, location: string, protocols: string[]) { - if (!servers[location]) { + if (isTruthy(servers[location])) { throw new Error(`There is no server at ${location}`) } const stream = Stream(protocols) diff --git a/packages/client/test/logging.spec.ts b/packages/client/test/logging.spec.ts index cea4e374a01..543becb65d7 100644 --- a/packages/client/test/logging.spec.ts +++ b/packages/client/test/logging.spec.ts @@ -1,3 +1,4 @@ +import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { getLogger } from '../lib/logging' @@ -23,7 +24,7 @@ tape('[Logging]', (t) => { }) t.test('should colorize key=value pairs', (st) => { - if (process.env.GITHUB_ACTION) { + if (isTruthy(process.env.GITHUB_ACTION)) { 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 470ac00d9b9..f45ffcc1555 100644 --- a/packages/client/test/rpc/admin/nodeInfo.spec.ts +++ b/packages/client/test/rpc/admin/nodeInfo.spec.ts @@ -1,3 +1,4 @@ +import { isTruthy } from '@ethereumjs/util' import * as tape from 'tape' import { startRPC, createManager, createClient, params, baseRequest } from '../helpers' @@ -11,7 +12,7 @@ tape(method, async (t) => { const expectRes = (res: any) => { const { result } = res.body - if (result) { + if (isTruthy(result)) { t.pass('admin_nodeInfo returns a value') } else { throw new Error('no return value') diff --git a/packages/client/test/rpc/eth/getLogs.spec.ts b/packages/client/test/rpc/eth/getLogs.spec.ts index 57195d7bb63..fc2a7698576 100644 --- a/packages/client/test/rpc/eth/getLogs.spec.ts +++ b/packages/client/test/rpc/eth/getLogs.spec.ts @@ -116,7 +116,7 @@ tape(`${method}: call with valid arguments`, async (t) => { const msg = 'should return the correct logs (filter by single address)' if ( res.body.result.length === 10 && - res.body.result.every((r: any) => r.address === contractAddr1.toString()) + res.body.result.every((r: any) => r.address === contractAddr1.toString()) === true ) { t.pass(msg) } else { @@ -132,7 +132,7 @@ tape(`${method}: call with valid arguments`, async (t) => { const msg = 'should return the correct logs (filter by multiple addresses)' if ( res.body.result.length === 20 && - res.body.result.every((r: any) => addresses.includes(r.address)) + res.body.result.every((r: any) => addresses.includes(r.address)) === true ) { t.pass(msg) } else { diff --git a/packages/client/test/rpc/helpers.ts b/packages/client/test/rpc/helpers.ts index 5073c090745..a31557d5227 100644 --- a/packages/client/test/rpc/helpers.ts +++ b/packages/client/test/rpc/helpers.ts @@ -3,7 +3,7 @@ import { Server as RPCServer, HttpServer } from 'jayson/promise' import { BlockHeader } from '@ethereumjs/block' import { Blockchain } from '@ethereumjs/blockchain' import { Chain as ChainEnum, Common } from '@ethereumjs/common' -import { Address } from '@ethereumjs/util' +import { Address, isTruthy } from '@ethereumjs/util' import { RPCManager as Manager } from '../../lib/rpc' import { getLogger } from '../../lib/logging' import { Config } from '../../lib/config' @@ -35,11 +35,12 @@ export function startRPC( ) { const { port, wsServer } = opts const server = new RPCServer(methods) - const httpServer = 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 (port) httpServer.listen(port) + if (isTruthy(port)) httpServer.listen(port) return httpServer } @@ -71,7 +72,7 @@ export function createClient(clientOpts: any = {}) { const clientConfig = { ...defaultClientConfig, ...clientOpts } chain.getTd = async (_hash: Buffer, _num: bigint) => BigInt(1000) - if (chain._headers) { + if (isTruthy(chain._headers)) { chain._headers.latest = BlockHeader.fromHeaderData({}, { common }) } @@ -98,8 +99,8 @@ export function createClient(clientOpts: any = {}) { } let execution - if (clientOpts.includeVM) { - const metaDB: any = clientOpts.enableMetaDB ? new MemoryLevel() : undefined + if (clientOpts.includeVM === true) { + const metaDB: any = clientOpts.enableMetaDB === true ? new MemoryLevel() : undefined execution = new VMExecution({ config, chain, metaDB }) } @@ -137,7 +138,7 @@ export function createClient(clientOpts: any = {}) { }, } - if (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 8731c265e8e..2d9dd1523d5 100644 --- a/packages/client/test/rpc/rpc.spec.ts +++ b/packages/client/test/rpc/rpc.spec.ts @@ -2,6 +2,7 @@ import * as tape from 'tape' import { encode, TAlgorithm } from 'jwt-simple' import { startRPC, closeRPC } from './helpers' import { METHOD_NOT_FOUND } from '../../lib/rpc/error-code' +import { isFalsy } from '@ethereumjs/util' const request = require('supertest') const jwtSecret = Buffer.from(Array.from({ length: 32 }, () => Math.round(Math.random() * 255))) @@ -128,7 +129,7 @@ tape('call JSON RPC with nonexistent method', (t) => { .set('Content-Type', 'application/json') .send(req) .expect((res: any) => { - if (!res.body.error) { + if (isFalsy(res.body.error)) { throw new Error('should return an error object') } if (res.body.error.code !== METHOD_NOT_FOUND) { @@ -168,7 +169,7 @@ tape('call JSON-RPC auth protected server with unprotected method without token' tape('call JSON-RPC auth protected server with protected method without token', (t) => { const server = startRPC({}, undefined, { jwtSecret, - unlessFn: (req: any) => !req.body.method.includes('protected_'), + unlessFn: (req: any) => !(req.body.method as string).includes('protected_'), }) const req = { @@ -192,7 +193,7 @@ tape('call JSON-RPC auth protected server with protected method without token', tape('call JSON-RPC auth protected server with protected method with token', (t) => { const server = startRPC({}, undefined, { jwtSecret, - unlessFn: (req: any) => !req.body.method.includes('protected_'), + unlessFn: (req: any) => !(req.body.method as string).includes('protected_'), }) const req = { diff --git a/packages/client/test/rpc/util.ts b/packages/client/test/rpc/util.ts index b5f827de2bd..a39fff97451 100644 --- a/packages/client/test/rpc/util.ts +++ b/packages/client/test/rpc/util.ts @@ -1,14 +1,18 @@ +import { isFalsy } from '@ethereumjs/util' import * as tape from 'tape' -export function checkError(t: tape.Test, expectedCode: any, expectedMessage?: any) { +export function checkError(t: tape.Test, expectedCode: number, expectedMessage?: string) { return (res: any) => { - if (!res.body.error) { + if (isFalsy(res.body.error)) { 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 (expectedMessage && !res.body.error.message.includes(expectedMessage)) { + if ( + typeof expectedMessage === 'string' && + !(res.body.error.message as string).includes(expectedMessage) + ) { throw new Error( `should have an error message "${expectedMessage}", got "${res.body.error.message}"` ) diff --git a/packages/client/test/rpc/util/CLConnectionManager.spec.ts b/packages/client/test/rpc/util/CLConnectionManager.spec.ts index 8365f54481d..63bd7c0a75b 100644 --- a/packages/client/test/rpc/util/CLConnectionManager.spec.ts +++ b/packages/client/test/rpc/util/CLConnectionManager.spec.ts @@ -76,10 +76,10 @@ tape('[CLConnectionManager]', (t) => { const config = new Config() const manager = new CLConnectionManager({ config: config }) config.logger.on('data', (chunk) => { - if (chunk.message.includes('consensus forkchoice update head=0x67b9')) { + if ((chunk.message as string).includes('consensus forkchoice update head=0x67b9')) { st.pass('received last fork choice message') } - if (chunk.message.includes('consensus payload received number=55504')) { + if ((chunk.message as string).includes('consensus payload received number=55504')) { st.pass('received last payload message') manager.stop() config.logger.removeAllListeners() diff --git a/packages/client/test/sync/lightsync.spec.ts b/packages/client/test/sync/lightsync.spec.ts index 7e4097f80b4..64aea9cbfb8 100644 --- a/packages/client/test/sync/lightsync.spec.ts +++ b/packages/client/test/sync/lightsync.spec.ts @@ -119,7 +119,7 @@ tape('[LightSynchronizer]', async (t) => { config.events.emit(Event.SYNC_FETCHED_HEADERS, [BlockHeader.fromHeaderData({})]) ) config.logger.on('data', async (data) => { - if (data.message.includes('Imported headers count=1')) { + if ((data.message as string).includes('Imported headers count=1')) { st.pass('successfully imported new header') config.logger.removeAllListeners() await sync.stop() @@ -153,7 +153,7 @@ tape('[LightSynchronizer]', async (t) => { config.events.emit(Event.SYNC_FETCHED_HEADERS, [] as BlockHeader[]) ) config.logger.on('data', async (data) => { - if (data.message.includes('No headers fetched are applicable for import')) { + if ((data.message as string).includes('No headers fetched are applicable for import')) { st.pass('generated correct warning message when no headers received') config.logger.removeAllListeners() await sync.stop() diff --git a/packages/client/test/sync/skeleton.spec.ts b/packages/client/test/sync/skeleton.spec.ts index 6a3b772b048..8c81381aa8c 100644 --- a/packages/client/test/sync/skeleton.spec.ts +++ b/packages/client/test/sync/skeleton.spec.ts @@ -269,7 +269,10 @@ tape('[Skeleton]', async (t) => { st.pass(`test ${testCaseIndex}: successfully passed`) } } catch (error: any) { - if (error.message.includes(testCase.err?.message)) { + if ( + typeof testCase.err?.message === 'string' && + (error.message as string).includes(testCase.err.message) + ) { st.pass(`test ${testCaseIndex}: passed with correct error`) } else { st.fail(`test ${testCaseIndex}: received wrong error`) diff --git a/packages/client/test/sync/txpool.spec.ts b/packages/client/test/sync/txpool.spec.ts index c06b4f1c4b5..c7328e44718 100644 --- a/packages/client/test/sync/txpool.spec.ts +++ b/packages/client/test/sync/txpool.spec.ts @@ -3,6 +3,7 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common' import { AccessListEIP2930Transaction, FeeMarketEIP1559Transaction } from '@ethereumjs/tx' import { Block } from '@ethereumjs/block' import { Account, privateToAddress } from '@ethereumjs/util' +import { StateManager } from '@ethereumjs/statemanager' import { PeerPool } from '../../lib/net/peerpool' import { TxPool } from '../../lib/service/txpool' import { Config } from '../../lib/config' @@ -27,12 +28,17 @@ const setup = () => { const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) const config = new Config({ transports: [] }) -const handleTxs = async (txs: any[], failMessage: string, stateManager?: any, pool?: any) => { - if (!pool) { +const handleTxs = async ( + txs: any[], + failMessage: string, + stateManager?: StateManager, + pool?: TxPool +) => { + if (typeof pool === 'undefined') { pool = setup().pool } try { - if (stateManager) { + if (typeof stateManager !== 'undefined') { ;(pool).service.execution.vm.stateManager = stateManager } @@ -64,7 +70,7 @@ const handleTxs = async (txs: any[], failMessage: string, stateManager?: any, po pool.stop() pool.close() // Return false if the error message contains the fail message - return !e.message.includes(failMessage) + return !(e.message as string).includes(failMessage) } } @@ -409,7 +415,7 @@ tape('[TxPool]', async (t) => { t.notOk( await handleTxs(txs, 'tx nonce too low', { getAccount: () => new Account(BigInt(1), BigInt('50000000000000000000')), - }), + } as any), 'successfully rejected tx with invalid nonce' ) }) @@ -429,7 +435,7 @@ tape('[TxPool]', async (t) => { t.notOk( await handleTxs(txs, 'exceeds the max data size', { getAccount: () => new Account(BigInt(0), BigInt('50000000000000000000000')), - }), + } as any), 'successfully rejected tx with too much data' ) }) @@ -449,7 +455,7 @@ tape('[TxPool]', async (t) => { t.notOk( await handleTxs(txs, 'insufficient balance', { getAccount: () => new Account(BigInt(0), BigInt('0')), - }), + } as any), 'successfully rejected account with too low balance' ) }) diff --git a/packages/client/test/util/rpc.spec.ts b/packages/client/test/util/rpc.spec.ts index 6465c845f2c..f2cbbc15899 100644 --- a/packages/client/test/util/rpc.spec.ts +++ b/packages/client/test/util/rpc.spec.ts @@ -9,6 +9,7 @@ import { import { EthereumClient } from '../../lib/client' import { Config } from '../../lib/config' import { METHOD_NOT_FOUND } from '../../lib/rpc/error-code' +import { isTruthy } from '@ethereumjs/util' const request = require('supertest') tape('[Util/RPC]', (t) => { @@ -40,7 +41,7 @@ tape('[Util/RPC]', (t) => { server.emit('response', req, []) // empty server.emit('response', [req], respBulk) // mismatch length - st.ok(httpServer && wsServer, 'should return http and ws servers') + st.ok(isTruthy(httpServer) && isTruthy(wsServer), 'should return http and ws servers') } } st.end() @@ -80,7 +81,7 @@ tape('[Util/RPC/Engine eth methods]', async (t) => { .set('Content-Type', 'application/json') .send(req) .expect((res: any) => { - if (res.body.error && res.body.error.code === METHOD_NOT_FOUND) { + if (res.body.error?.code === METHOD_NOT_FOUND) { throw new Error(`should have an error code ${METHOD_NOT_FOUND}`) } })