Skip to content

Preconfirmations

Preconfirmations are a Fiber consensus primitive that enable sub-20 ms transaction finality while preserving decentralization and validator accountability.

Validators provide instant, cryptographically signed receipts for transactions as they build the next block.
Each receipt contains:

  • a recursive sequencing hash (ordering proof), and
  • a SECP256K1 ECDSA signature that covers the full receipt data, preventing tampering.

If a validator’s block later diverges from these commitments by changing order, omitting a transaction, or falsifying a receipt, it can be provably slashed.

Overview

Latency~20 ms per miniblock
SecurityRecursive proofs + ECDSA signatures over full receipt
Proof size~97 B (32 B hash + 65 B signature)
SlashingConflicting proofs, wrong position, missing tx, or falsified receipt
RPCfiber_sendRawTransactionSync

Concept

Each validator maintains a running hash chain representing the in-progress block’s transaction order.

For every new transaction:

  1. Execute the tx and produce a receipt (execution result, logs, gas, etc.).
  2. Compute a sequencing hash that commits to:
    • all previous transactions, and
    • the serialized receipt data of the new transaction.
  3. Sign the resulting hash using the validator’s SECP256K1 private key.
  4. Return a preconfirmation receipt containing:
    • execution results,
    • recursive proof (sequencing hash), and
    • validator signature.

This binds the validator to both the transaction order and the receipt content.

Sequencing Proof

A sequencing proof commits to every previous transaction and its receipt.
It includes a recursive sequencing hash and an ECDSA signature over that hash.

Recursive Definition

Let:

  • receipt[i] = serialized receipt of transaction i
  • tx[i] = hash of transaction i
  • block_number = current block
  • H() = Keccak-256
  • Sign(sk, x) = SECP256K1 ECDSA signature

Then:

proof[0].hash = H(block_number || tx[0])
proof[0].sig = Sign(validator_sk, proof[0].hash)
 
proof[i].hash = H(proof[i-1].hash || tx[i])
proof[i].sig = Sign(validator_sk, proof[i].hash) 

Only the first proof is explicitly tied to block_number.
All subsequent proofs inherit that context through recursion.

Proof Structure

FieldTypeSizeDescription
sequencing_hashbytes3232 BRecursive hash of all previous transactions
validator_signaturebytes6565 BSECP256K1 ECDSA compact signature (r + s + v)
block_numberuint648 BPresent only in the first proof of the block

Total proof size: 97 B (typical)

RPC Interface

Preconfirmations are exposed via eth_sendRawTransactionSync, preconfirmations are applied to all transactions, but receipt are only returned for transactions sent via eth_sendRawTransactionSync.

Example Request

{
  "jsonrpc": "2.0",
  "method": "eth_sendRawTransactionSync",
  "params": [
    "0x02f8f1830186b4824c9380843b9aca01830186a0945fa9912d6c6815039e2bd7f5b271fdf0a1988fd080b88489ce05be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001eb0000000000000000000000000000000000000000000000000000000000000000c001a0a1012f6a296bbf4488f94098be5fae988b0b03c64ab954d9e94cec03bd0b4ad2a049dba1e112b05f3719763fb596c5c25e6326da366335c1dbfbb2613b9adf928e"
  ],
  "id": 1
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "hash": "0x082735b25aa0ca3be8621c593af97eb6e91db4efbea4751839e0cf2b7f0dd531",
    "from": "0x8626f6940e2eb28930efb4cef49b2d1f2c9c1199",
    "to": "0x5fa9912d6c6815039e2bd7f5b271fdf0a1988fd0",
    "value": "0x0",
    "gas_used": 22560,
    "status": true,
    "logs": [],
    "block_number": 12045,
    "reject_reason": null,
    "proof": "0x02f8f1830186b4824c9380843b9aca018301....." // concatenated sequencing hash and validator signature
  }
}

Receipt schema

FieldTypeDescription
hashbytes32Transaction hash
statusbooltrue if executed successfully
logsarrayEmitted logs
gas_useduint64Gas consumed
reject_reasonstringError message if rejected
proofbytesConcatenated sequencing_hash and validator_signature

Slashing Mechanism

Slashable Offenses

A validator v is slashable if it issues any proof or block inconsistent with its signed preconfirmations:

Conflicting proofs:

  • Signed two different sequencing_hash values for the same block_number.

Wrong position:

  • A preconfirmed transaction appears at a different index than implied by the recursive proof chain.

Missing transaction:

  • A preconfirmed transaction is absent from the final sealed block.

Falsified receipt:

  • The transaction appears, but the executed receipt differs from the signed one (gas, logs, or output mismatch).
preconfirmed_tx ∉ final_block
OR
position(preconfirmed_tx) ≠ position_from_proof
OR
receipt(preconfirmed_tx) ≠ signed_receipt(preconfirmed_tx)

On-Chain Slashing Proof

Any node may submit conflicting proofs or missing-tx evidence to the Slashing Contract. If signatures verify and proofs or receipts differ, the validator is immediately slashed.

Penalty & Recovery

ComponentDescription
Penalty100 % of stake for the current epoch
Reward to Reporter50 % of slashed stake
Burned50 % permanently destroyed
LockoutValidator disabled for remainder of epoch
RecoveryRequires re-registration and staking in next epoch
Copyright © 2025-present Merkle Software Inc.