Skip to content

Forbid transactions without chain ID by default#1815

Merged
librelois merged 3 commits intomasterfrom
elois/unprotected-txs
Feb 19, 2026
Merged

Forbid transactions without chain ID by default#1815
librelois merged 3 commits intomasterfrom
elois/unprotected-txs

Conversation

@librelois
Copy link
Member

@librelois librelois commented Feb 10, 2026

⚠️ Breaking changes ⚠️

  • Legacy Ethereum transactions without an EIP-155 chain_id are now rejected by default in transactional paths.
  • This impacts callers that still sign legacy txs with v in {27,28} (no replay protection), including eth_sendRawTransaction / eth_sendTransaction flows and runtime transaction validation.
  • Migration actions:
    • Update signers/tooling to include EIP-155 chain_id.
    • If you need temporary compatibility, opt in explicitly:
      • Runtime: set pallet_ethereum::Config::AllowUnprotectedTxs = true.
      • RPC/template node: start with --rpc-allow-unprotected-txs (RPC submission policy only).

Goal of the changes

Disallow unprotected legacy Ethereum transactions by default, while providing explicit opt-in switches for chains or nodes that still need compatibility.

What reviewers need to know

  • Core validation change:

    • CheckEvmTransactionConfig now includes allow_unprotected_txs.
    • with_chain_id() now rejects chain_id == None when is_transactional == true and allow_unprotected_txs == false.
    • Non-transactional execution (dry-run style paths) remains permissive.
  • Runtime wiring:

    • pallet_ethereum::Config gains AllowUnprotectedTxs: Get<bool> and threads it into transactional checks.
    • Default config is false (secure-by-default).
    • Template runtime sets AllowUnprotectedTxs to false.
  • RPC policy:

    • Added RPC-side guard to reject unprotected legacy tx submission unless explicitly allowed.
    • New template node CLI flag: --rpc-allow-unprotected-txs (default false).
    • This RPC policy is additive; runtime validation remains authoritative for tx validity.
  • Coverage:

    • Added validation tests for chain-id missing behavior under transactional/non-transactional and allow/disallow combinations.
    • Added RPC unit tests for unprotected legacy detection and policy decision.
    • Added pallet legacy tx tests for both reject (default) and allow (opt-in) paths.
    • Includes follow-up formatting-only commit (rustfmt).

@librelois
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

Adds an opt-in flag to allow unprotected (no EIP‑155 chain id) legacy Ethereum transactions and wires it through RPC, runtime/pallet configuration, EVM validation, mocks, and tests. Also adds runtime RPC enforcement helpers and tests for rejecting/accepting unprotected legacy transactions.

Changes

Cohort / File(s) Summary
RPC core
client/rpc/src/eth/mod.rs, client/rpc/src/eth/submit.rs
Adds rpc_allow_unprotected_txs: bool to Eth; new helpers is_unprotected_legacy_tx, should_reject_unprotected_legacy_tx, and ensure_unprotected_legacy_tx_allowed; calls to enforce policy in send_transaction and send_raw_transaction; unit tests added.
Pallet / Runtime config
frame/ethereum/src/lib.rs, template/runtime/src/lib.rs
Introduces AllowUnprotectedTxs config/associated type and threads it into EVM transaction validation paths.
Pallet test & mock utilities
frame/ethereum/src/mock.rs, frame/ethereum/src/tests/legacy.rs
Adds test parameter AllowUnprotectedTxs; adds unprotected signing helpers (unprotected_signing_hash, sign_without_chain_id) and tests exercising allowed/denied unprotected legacy tx flows.
EVM validation logic
primitives/evm/src/validation.rs
Adds allow_unprotected_txs to CheckEvmTransactionConfig; replaces simple chain_id equality check with match-based logic to permit None when allowed; updates tests and builders to include the new flag.
Runner / node wiring
frame/evm/src/runner/stack.rs, template/node/src/eth.rs, template/node/src/rpc/eth.rs, template/node/src/service.rs
Propagates rpc_allow_unprotected_txs into node/RPC deps and passes allow_unprotected_txs into CheckEvmTransactionConfig at runner call sites; adds CLI/config field in template.
TS test update
ts-tests/tests/test-transaction-cost.ts
Reformats raw transaction hex literal and updates test description to reflect a protected (EIP‑155) legacy transaction.

Sequence Diagram

sequenceDiagram
    participant Client
    participant RPC_Handler as RPC Handler
    participant Validator as EVM Validator
    participant Pallet as Ethereum Pallet
    participant EVM as EVM Engine

    Client->>RPC_Handler: send_raw_transaction(bytes)
    RPC_Handler->>RPC_Handler: deserialize & parse tx
    RPC_Handler->>RPC_Handler: is_unprotected_legacy_tx?
    alt Unprotected & rpc disallowed
        RPC_Handler-->>Client: Error (InvalidChainId)
    else Allowed or Protected
        RPC_Handler->>Validator: validate(tx, allow_unprotected_txs)
        Validator->>Validator: match on chain_id (Some/None) and config
        alt Validation fails
            Validator-->>RPC_Handler: InvalidChainId
            RPC_Handler-->>Client: Error
        else Validation ok
            RPC_Handler->>Pallet: submit transaction
            Pallet->>EVM: execute (uses AllowUnprotectedTxs config)
            EVM-->>Pallet: execution result
            Pallet-->>RPC_Handler: tx hash
            RPC_Handler-->>Client: tx hash
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing a default rejection policy for Ethereum transactions without a chain ID.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering breaking changes, goals, migration paths, core validation changes, runtime wiring, RPC policy, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch elois/unprotected-txs

No actionable comments were generated in the recent review. 🎉


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Collaborator

@arturgontijo arturgontijo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@librelois librelois added this pull request to the merge queue Feb 19, 2026
Merged via the queue into master with commit 9f94a15 Feb 19, 2026
7 checks passed
@librelois librelois deleted the elois/unprotected-txs branch February 19, 2026 15:34
librelois added a commit to moonbeam-foundation/frontier that referenced this pull request Feb 19, 2026
* forbid txs without chain id by default

* fix ts-test test-transaction-cost
librelois added a commit to moonbeam-foundation/frontier that referenced this pull request Feb 19, 2026
* forbid txs without chain id by default

* fix ts-test test-transaction-cost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants