Skip to content

Index Ethereum transactions submitted through revive.ethTransact - #342

Open
F-OBrien wants to merge 5 commits into
alphafrom
ethTransact
Open

Index Ethereum transactions submitted through revive.ethTransact#342
F-OBrien wants to merge 5 commits into
alphafrom
ethTransact

Conversation

@F-OBrien

@F-OBrien F-OBrien commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Description

revive.ethTransact is included as an unsigned extrinsic wrapping an RLP encoded Ethereum
transaction. The indexer recorded it with address: null, so nothing could be attributed to the
Ethereum-derived account that sent it, breaking downstream transaction-history reads.

Changes

  • Sender recovery (src/utils/ethTransaction.ts, src/utils/eth.ts): RLP-decode legacy
    (pre-EIP-155 & EIP-155), EIP-2930 and EIP-1559 payloads, reconstruct the signing payload,
    recover the signer via secp256k1Recover, and map the H160 to its 0xEE-padded SS58 account.
    All failure modes log-and-skip; handlers never throw into the pipeline.
  • Attribution: Extrinsic.address now carries the recovered account (signed stays 0,
    marking an ECDSA-recovered sender), plus new ethAddress / ethTxHash columns. Runtime calls
    targeting modlpy/paddr are normalised to the pallet/call actually dispatched, and reverted
    transactions are marked unsuccessful via revive.EthExtrinsicRevert.
  • New entities: EvmTransaction (full decoded transaction incl. calldata, gas fields,
    revert state) and EvmAccountMapping (H160 → AccountId32 mappings from revive.mapAccount
    extrinsics and genesis config). Account gains keyType / evmAddress.
  • Backfill (scripts/backfill/eth-transact-senders.ts): recovers historical senders offline
    from stored payloads and upserts accounts. Dry-run by default, --apply to write.

Deployment notes

  • New tables/columns are auto-created by the node; migration 20_evm_transactions.sql only adds
    indexes/backfills columns for existing tables.
  • Run the backfill once after deploying the forward fix:
    yarn ts-node scripts/backfill/eth-transact-senders.ts (dry run first, then --apply).

Testing

  • New unit suites cover all three transaction formats (incl. access-list re-encoding),
    malformed-payload handling, revert flagging and account indexing.
  • yarn lint && yarn build && yarn test:unit green (178 tests).

Breaking Changes

JIRA Link

Checklist

  • Updated the Readme.md (if required) ?

@F-OBrien
F-OBrien requested a review from a team as a code owner August 24, 2026 13:24
@socket-security

socket-security Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​ethereumjs/​rlp@​5.0.2100100989070

View full report

`eth_transact` is an unsigned extrinsic wrapping an RLP encoded Ethereum
transaction, so its sender was never recorded. Decode the payload, recover
the signing key with secp256k1 and attribute the extrinsic to the derived
`0xEE` padded account, alongside a new EvmTransaction entity capturing the
decoded transaction and an EvmAccountMapping entity for `revive.mapAccount`.
Includes an offline backfill script for historical rows.
…bles

- only read/write current revisions (upper(_block_range) is null); closed
  revisions untouched so point-in-time queries keep their era
- keyset pagination on _id (id is not unique under historical mode)
- account insert supplies _id/_block_range explicitly and replaces ON CONFLICT
  (no unique constraint on id) with an existence check, counted via returning id
- batched transactions, precise --limit, DB creds via DB_* env only
- extract the constraints into a shared scripts/backfill/historical.ts helper
Migration 20 defaulted every pre-existing account to `substrate`, but Ethereum
keys were attributed long before eth_transact was indexed - registering a DID or
joining an identity emits the 0xEE padded SS58 like any other key. Postgres
cannot tell them apart, so the backfill decodes every account offline: all get
the evm_address pallet_revive addresses them by, and the 0xEE padded ones get
key_type = 'ethereum'.
Three call sites repeated `isEthTransact(x) ? resolveEthTransact(x) : undefined`.
Moving the check inside the resolver collapses them to a plain call, drops a
nested conditional in handleExtrinsic, and skips the memo for non-eth extrinsics.
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant