Transaction Lifecycle

This page walks through what happens to a transaction from the moment you hit "send" to when it's permanently finalized on-chain. Understanding this flow is helpful for debugging, optimizing, and building reliable dApps.

Overview

User signs transaction (ML-DSA44)


Transaction submitted via JSON-RPC


Node validates and adds to mempool


Validator includes in DAG event


Event gossiped to network


Lachesis determines event order


Event transactions assembled into block


EVM executes transactions


Block finalized (INSTANT - no rollbacks)


Transaction receipt available via RPC

Phase 1: Transaction Creation

Constructing the Transaction

A user constructs a transaction with these fields:

Signing with ML-DSA44

The transaction is signed using the sender's ML-DSA44 private key:

  1. Serialize the transaction fields using RLP encoding

  2. Compute the signing hash: keccak256(0x03 || RLP(fields))

  3. Sign the hash with the ML-DSA44 private key

  4. Construct the signature blob (raw signature + public key)

  5. Append the signature blob to the transaction

The signed transaction uses a typed envelope format (EIP-2718):

Total transaction size: ~3,930 bytes for a simple transfer (vs ~200 bytes with ECDSA). The additional size comes from the post-quantum signature.

Phase 2: Submission and Validation

RPC Submission

The signed transaction is submitted to a node via JSON-RPC:

Node Validation

The receiving node performs these checks:

Check
Description

Type validation

Transaction type must be 3 (PQC)

Signature validation

ML-DSA44 signature must be valid for the transaction hash

Signature size

Signature blob must be exactly 3,732 bytes

Address derivation

Sender address derived from public key in signature

Nonce check

Nonce must match sender's current nonce

Balance check

Sender must have sufficient ARM for value + gas

Gas price check

Gas price must meet the minimum (1 Gwei)

Gas limit check

Gas limit must be within block gas limit

Chain ID

Must match the network's chain ID

Mempool (Transaction Pool)

Valid transactions enter the mempool, organized as:

  • Pending: Ready for inclusion (correct nonce, sufficient balance)

  • Queued: Waiting for earlier nonces to be processed

You can inspect the mempool:

Phase 3: Event Inclusion

Validator Selection

Any active validator with available gas power can include the transaction:

  1. Validator selects transactions from its local mempool (by gas price, highest first)

  2. Validator creates a DAG event containing these transactions

  3. The event includes references to parent events (up to 10 parents)

  4. Validator signs the event with its ML-DSA44 validator key

Event Structure

Phase 4: Gossip and Consensus

P2P Gossip

Events are propagated through the network using the devp2p gossip protocol:

Default P2P port: 5050 (TCP/UDP).

Lachesis Consensus

The Lachesis aBFT algorithm processes the growing DAG to determine a total ordering of events:

  1. Root detection: Identify events that are "roots": events forkless-caused by ≥ 2/3 of validator weight from the previous frame

  2. Atropos election: Root events in frame F+1 vote on candidate events in frame F. Votes are weighted by validator stake. When a candidate reaches quorum ((TotalWeight × 2/3) + 1), it is decided.

  3. Atropos selection: Validators are iterated by weight (descending). The first validator whose candidate has a decided "YES" vote becomes the Atropos for that frame.

  4. Block assignment: The Atropos event maps 1:1 to a block. All confirmed events from the frame are included.

This process is asynchronous: it does not require rounds, timeouts, or leader election. See Consensus for a detailed worked example.

Phase 5: EVM Execution

Block Execution

Once events are ordered into a block:

  1. Transactions are executed sequentially through the EVM

  2. Each transaction updates the state trie

  3. Events (logs) are emitted for contract interactions

  4. Gas is consumed and fees are calculated

  5. A state root is computed for the block

Transaction Receipt

After execution, a receipt is generated:

Phase 6: Finality

Instant and Irreversible

Once the block is sealed, the transaction is final:

  • No waiting for confirmations: 1 confirmation = absolute finality

  • No rollbacks: The aBFT guarantee means the block will never be reverted

  • No chain reorganizations: The DAG structure prevents forks

  • Deterministic: Every honest node will agree on the same final state

Confirming Finality

Transaction Size Comparison

Transaction Type
Typical Size
Signature Size
Notes

Type 0 (Legacy)

~200 bytes

65 bytes (ECDSA)

No access list

Type 2 (EIP-1559)

~250 bytes

65 bytes (ECDSA)

Dynamic fees

Type 3 (PQC)

~3,930 bytes

3,732 bytes (ML-DSA44)

Post-quantum secure

The ~57x increase in signature blob size (65 → 3,732 bytes) drives the overall ~36x increase in transaction size (~110 → ~3,930 bytes). This is factored into Armchain's block gas limits and network parameters.

Error Handling

Common transaction errors:

Error
Cause
Solution

nonce too low

Transaction nonce already used

Get latest nonce from eth_getTransactionCount

insufficient funds

Not enough ARM for value + gas

Check balance with eth_getBalance

gas too low

Gas limit below minimum

Use eth_estimateGas to get estimate

invalid signature

Malformed ML-DSA44 signature

Ensure signing with @armchain-ethersv6/ethers

invalid sender

Can't derive address from signature

Verify key generation and signing process

transaction type not supported

Non-Type 3 transaction

Set type: 3 in transaction object

Further Reading

Last updated