Test Vectors & Reference Implementation

Istora Mandiri
Research TODO

TODO

This article is a placeholder and is subject to change as research continues.

Abstract

Successful deployment of ECIP-1120 across multiple clients (Core-Geth, Besu) requires rigorous verification through standardized test vectors. This research develops comprehensive test cases covering basefee calculation, fee distribution, transaction validation, and edge cases. Test vectors enable client developers to verify their implementations match the specification exactly, ensuring consensus compatibility at fork activation.

Research Objectives

  1. What test vectors are needed to fully verify ECIP-1120 implementation correctness?
  2. How should test vectors be structured for maximum utility across client implementations?
  3. What edge cases and boundary conditions must be tested?
  4. How can we verify cross-client consensus compatibility before mainnet deployment?

Background

Why Test Vectors Matter

Hard forks require all clients to implement identical consensus rules. Even small discrepancies can cause:

  • Chain splits: Clients disagree on valid blocks
  • Consensus failures: Network fragments into incompatible forks
  • Fund losses: Transactions valid on one chain, invalid on another

Test vectors are the primary defense against these failures.

EIP-1559 Test Vector Precedent

Ethereum's EIP-1559 deployment included extensive test vectors:

  • Basefee calculation tests
  • Transaction validation tests
  • Block validation tests
  • State transition tests

ECIP-1120 extends these with fee distribution-specific tests.

Test Categories Required

Category Purpose Complexity
Basefee calculation Verify basefee adjustment algorithm Medium
Transaction validation Verify Type 2 transaction handling Medium
Fee distribution Verify ℓ-smoothing implementation High
Block validation Verify header and block acceptance Medium
State transition Verify miner balance updates High
Edge cases Verify behavior at boundaries High

Methodology

Approach

  1. Specification Analysis: Identify all consensus-critical calculations
  2. Vector Generation: Create test cases for each calculation
  3. Cross-Client Validation: Verify vectors produce identical results in all clients
  4. Edge Case Enumeration: Systematically identify boundary conditions
  5. Regression Suite: Package vectors for ongoing CI/CD use

Test Vector Format

Test vectors will use a standardized JSON format compatible with existing Ethereum test infrastructure:

interface TestVector {
  name: string;
  description: string;
  category: 'basefee' | 'transaction' | 'distribution' | 'block' | 'state';

  // Input state
  pre: {
    blocks: BlockHeader[];
    accounts: Record<Address, AccountState>;
  };

  // Operation to test
  input: {
    block?: Block;
    transaction?: Transaction;
  };

  // Expected output
  expected: {
    baseFee?: bigint;
    valid?: boolean;
    distributedFees?: bigint;
    minerBalance?: bigint;
    error?: string;
  };
}

Coverage Goals

  • 100% of specification pseudocode paths covered
  • All boundary conditions tested (min, max, overflow)
  • All error conditions tested (invalid transactions, malformed blocks)
  • Realistic scenarios from historical ETC data

Research Plan

Phase 1: Basefee Calculation Vectors

  • Test basefee at exactly target gas (should remain unchanged)
  • Test basefee with empty block (should decrease)
  • Test basefee with full block (should increase)
  • Test maximum basefee increase (+12.5%)
  • Test maximum basefee decrease (-12.5%)
  • Test basefee floor (minimum 1 wei)
  • Test first block after fork (INITIAL_BASE_FEE)
  • Test basefee with varying parent gas used

Phase 2: Transaction Validation Vectors

  • Test valid Type 2 transaction
  • Test Type 2 with maxFeePerGas < baseFee (should reject)
  • Test Type 2 with maxFeePerGas < maxPriorityFeePerGas (should reject)
  • Test Type 2 with insufficient balance (should reject)
  • Test effective gas price calculation
  • Test priority fee calculation when maxFee >> baseFee
  • Test priority fee calculation when maxFee ≈ baseFee
  • Test legacy (Type 0) transaction handling
  • Test Type 1 transaction handling

Phase 3: Fee Distribution Vectors

  • Test distribution from single ancestor block
  • Test distribution across full BACKWARD_FEES_BLOCK_COUNT window
  • Test distribution with empty blocks in window
  • Test distribution at chain start (fewer ancestors than window)
  • Test distribution with varying basefees across window
  • Test distribution with varying gas used across window
  • Test uniform distribution calculation
  • Test decay curve distribution (if applicable)
  • Test total fees distributed equals fees collected (conservation)

Phase 4: Block Validation Vectors

  • Test valid block with correct baseFeePerGas header field
  • Test block with incorrect baseFeePerGas (should reject)
  • Test block exceeding max gas limit (should reject)
  • Test block at exactly max gas limit (should accept)
  • Test block gas used < gas target
  • Test block gas used > gas target
  • Test RLP encoding of new header field (256-bit integer appended to existing structure)
  • Test block hash includes baseFeePerGas field

Phase 4.5: BASEFEE Opcode Vectors (EIP-3198)

  • Test BASEFEE opcode (0x48) returns current block's basefee
  • Test BASEFEE in contract context returns correct value
  • Test BASEFEE gas cost (2 gas as per EIP-3198)
  • Test BASEFEE stack behavior (pushes 256-bit value)
  • Test BASEFEE during first post-fork block (returns INITIAL_BASE_FEE)

Phase 5: State Transition Vectors

  • Test miner balance after block with fees
  • Test miner balance includes distributed fees from ancestors
  • Test miner balance includes priority fees
  • Test multiple transactions in single block
  • Test fee refund to sender (gasUsed < gasLimit)
  • Test exact balance changes (before/after comparison)

Phase 6: Edge Case Vectors

  • Test integer overflow protection in basefee calculation
  • Test integer overflow protection in fee distribution
  • Test maximum possible basefee value
  • Test maximum possible gas used
  • Test empty transaction pool scenarios
  • Test reorg scenarios (fee redistribution correctness)
  • Test fork boundary (last pre-fork block, first post-fork block)

Phase 7: Integration & Packaging

  • Package all vectors in standardized format
  • Create test runner for Core-Geth
  • Create test runner for Besu
  • Verify all vectors pass on reference implementation
  • Document any implementation-specific behaviors
  • Publish vectors for community review

Expected Outcomes

  1. Test Vector Suite: Complete JSON test vectors covering all ECIP-1120 consensus rules
  2. Test Runners: Scripts to run vectors against Core-Geth and Besu
  3. Coverage Report: Documentation of what each vector tests
  4. Edge Case Catalog: Comprehensive list of boundary conditions
  5. Reference Implementation: Canonical implementation for vector validation

Success Criteria

  • 100% of ECIP-1120 specification paths covered by tests
  • All vectors produce identical results in Core-Geth and Besu
  • No consensus-critical edge cases missing from test suite
  • Test suite integrated into client CI/CD pipelines
  • Community review completed with no issues found

Dependencies

Current Status

Status: TODO

Progress Log

  • 2025-12-03: Initial research plan drafted
  • Pending: Begin Phase 1 basefee calculation vectors

Appendix: Example Test Vectors

Basefee Calculation Example

{
  "name": "basefee_increase_full_block",
  "description": "Basefee should increase by 12.5% when parent block is at max gas",
  "category": "basefee",
  "pre": {
    "blocks": [
      {
        "number": 100,
        "baseFeePerGas": "1000000000",
        "gasUsed": "16000000",
        "gasLimit": "16000000"
      }
    ]
  },
  "input": {
    "parentHash": "0x..."
  },
  "expected": {
    "baseFee": "1125000000"
  }
}

Fee Distribution Example

{
  "name": "distribution_uniform_window",
  "description": "Distributed fees should sum portions from all ancestors",
  "category": "distribution",
  "pre": {
    "blocks": [
      { "number": 97, "baseFeePerGas": "1000000000", "gasUsed": "8000000" },
      { "number": 98, "baseFeePerGas": "1000000000", "gasUsed": "8000000" },
      { "number": 99, "baseFeePerGas": "1000000000", "gasUsed": "8000000" },
      { "number": 100, "baseFeePerGas": "1000000000", "gasUsed": "8000000" }
    ]
  },
  "input": {
    "blockNumber": 101,
    "BACKWARD_FEES_BLOCK_COUNT": 4
  },
  "expected": {
    "distributedFees": "8000000000000000"
  }
}

Transaction Validation Example

{
  "name": "type2_valid_transaction",
  "description": "Valid Type 2 transaction should be accepted",
  "category": "transaction",
  "pre": {
    "blocks": [{ "baseFeePerGas": "1000000000" }],
    "accounts": {
      "0xsender": { "balance": "10000000000000000000", "nonce": 0 }
    }
  },
  "input": {
    "transaction": {
      "type": 2,
      "maxFeePerGas": "2000000000",
      "maxPriorityFeePerGas": "500000000",
      "gasLimit": "21000",
      "to": "0xrecipient",
      "value": "1000000000000000000"
    }
  },
  "expected": {
    "valid": true,
    "effectiveGasPrice": "1500000000"
  }
}

References