UNPKG

ox

Version:

Ethereum Standard Library

286 lines (277 loc) 8.72 kB
import { describe, expect, test } from 'vp/test' import * as z_Block from '../Block.js' import * as z from 'zod/mini' const address = '0x0000000000000000000000000000000000000000' const hash = `0x${'11'.repeat(32)}` as const const hash2 = `0x${'22'.repeat(32)}` as const const r = `0x${'33'.repeat(32)}` as const const s = `0x${'44'.repeat(32)}` as const const blockRpc = { baseFeePerGas: '0x1', blobGasUsed: '0x2', difficulty: '0x3', excessBlobGas: '0x4', extraData: '0x', gasLimit: '0x5', gasUsed: '0x6', hash, logsBloom: '0x', miner: address, mixHash: hash, nonce: '0x0000000000000000', number: '0x7', parentBeaconBlockRoot: hash, parentHash: hash, receiptsRoot: hash, sealFields: [hash, '0x0000000000000000'], sha3Uncles: hash, size: '0x8', stateRoot: hash, timestamp: '0x9', totalDifficulty: '0xa', transactions: [hash2], transactionsRoot: hash, uncles: [hash2], withdrawals: [ { address, amount: '0xb', index: '0xc', validatorIndex: '0xd' }, ], withdrawalsRoot: hash, } as const describe('Block', () => { test('decodes and encodes blocks with transaction hashes', () => { expect(z.decode(z_Block.Block, blockRpc)).toMatchInlineSnapshot(` { "baseFeePerGas": 1n, "blobGasUsed": 2n, "difficulty": 3n, "excessBlobGas": 4n, "extraData": "0x", "gasLimit": 5n, "gasUsed": 6n, "hash": "0x1111111111111111111111111111111111111111111111111111111111111111", "logsBloom": "0x", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x1111111111111111111111111111111111111111111111111111111111111111", "nonce": "0x0000000000000000", "number": 7n, "parentBeaconBlockRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111", "receiptsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "sealFields": [ "0x1111111111111111111111111111111111111111111111111111111111111111", "0x0000000000000000", ], "sha3Uncles": "0x1111111111111111111111111111111111111111111111111111111111111111", "size": 8n, "stateRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "timestamp": 9n, "totalDifficulty": 10n, "transactions": [ "0x2222222222222222222222222222222222222222222222222222222222222222", ], "transactionsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "uncles": [ "0x2222222222222222222222222222222222222222222222222222222222222222", ], "withdrawals": [ { "address": "0x0000000000000000000000000000000000000000", "amount": 11n, "index": 12, "validatorIndex": 13, }, ], "withdrawalsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", } `) expect( z.encode(z_Block.Block, { baseFeePerGas: 1n, blobGasUsed: 2n, difficulty: 3n, excessBlobGas: 4n, extraData: '0x', gasLimit: 5n, gasUsed: 6n, hash, logsBloom: '0x', miner: address, mixHash: hash, nonce: '0x0000000000000000', number: 7n, parentBeaconBlockRoot: hash, parentHash: hash, receiptsRoot: hash, sealFields: [hash, '0x0000000000000000'], sha3Uncles: hash, size: 8n, stateRoot: hash, timestamp: 9n, totalDifficulty: 10n, transactions: [hash2], transactionsRoot: hash, uncles: [hash2], withdrawals: [{ address, amount: 11n, index: 12, validatorIndex: 13 }], withdrawalsRoot: hash, }), ).toMatchInlineSnapshot(` { "baseFeePerGas": "0x1", "blobGasUsed": "0x2", "difficulty": "0x3", "excessBlobGas": "0x4", "extraData": "0x", "gasLimit": "0x5", "gasUsed": "0x6", "hash": "0x1111111111111111111111111111111111111111111111111111111111111111", "logsBloom": "0x", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x1111111111111111111111111111111111111111111111111111111111111111", "nonce": "0x0000000000000000", "number": "0x7", "parentBeaconBlockRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "parentHash": "0x1111111111111111111111111111111111111111111111111111111111111111", "receiptsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "sealFields": [ "0x1111111111111111111111111111111111111111111111111111111111111111", "0x0000000000000000", ], "sha3Uncles": "0x1111111111111111111111111111111111111111111111111111111111111111", "size": "0x8", "stateRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "timestamp": "0x9", "totalDifficulty": "0xa", "transactions": [ "0x2222222222222222222222222222222222222222222222222222222222222222", ], "transactionsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", "uncles": [ "0x2222222222222222222222222222222222222222222222222222222222222222", ], "withdrawals": [ { "address": "0x0000000000000000000000000000000000000000", "amount": "0xb", "index": "0xc", "validatorIndex": "0xd", }, ], "withdrawalsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111", } `) }) test('decodes blocks with full transactions and pending blocks', () => { const transaction = { accessList: [], blockHash: hash, blockNumber: '0x7', chainId: '0x1', from: address, gas: '0x5208', hash, input: '0x', maxFeePerGas: '0x2', maxPriorityFeePerGas: '0x1', nonce: '0x0', r, s, to: address, transactionIndex: '0x0', type: '0x2', value: '0x0', yParity: '0x1', } as const expect( z.decode(z_Block.WithTransactions, { ...blockRpc, transactions: [transaction], }), ).toMatchObject({ transactions: [{ type: 'eip1559' }] }) expect( z.decode(z_Block.Pending, { ...blockRpc, hash: null, logsBloom: null, nonce: null, number: null, }), ).toMatchObject({ hash: null, number: null }) }) test('BlockToRpc accepts numberish encode inputs', () => { const decoded = { baseFeePerGas: 1n, blobGasUsed: 2n, difficulty: 3n, excessBlobGas: 4n, extraData: '0x', gasLimit: 5n, gasUsed: 6n, hash, logsBloom: '0x', miner: address, mixHash: hash, nonce: '0x0000000000000000', number: 7n, parentBeaconBlockRoot: hash, parentHash: hash, receiptsRoot: hash, sealFields: [hash, '0x0000000000000000'], sha3Uncles: hash, size: 8n, stateRoot: hash, timestamp: 9n, totalDifficulty: 10n, transactions: [hash2], transactionsRoot: hash, uncles: [hash2], withdrawals: [{ address, amount: 11n, index: 12, validatorIndex: 13 }], withdrawalsRoot: hash, } as const const expected = z.encode(z_Block.Block, decoded) expect( z.encode(z_Block.BlockToRpc, { ...decoded, baseFeePerGas: 1, gasLimit: 5, number: 7, size: 8, timestamp: 9, totalDifficulty: 10, withdrawals: [{ address, amount: 11, index: 12, validatorIndex: 13 }], }), ).toEqual(expected) expect( z.encode(z_Block.BlockToRpc, { ...decoded, baseFeePerGas: '0x1', gasLimit: '0x5', number: '0x7', }), ).toEqual(expected) }) test('decodes identifiers and rejects invalid blocks', () => { expect( z.decode(z_Block.Identifier, { blockNumber: '0x1', requireCanonical: true, }), ).toMatchInlineSnapshot(` { "blockNumber": 1n, "requireCanonical": true, } `) expect( z.safeDecode(z_Block.Identifier, { blockHash: hash, blockNumber: '0x1', } as never).success, ).toBe(false) expect( z.safeDecode(z_Block.Block, { ...blockRpc, gasLimit: '0x', } as never).success, ).toBe(false) }) })