celestiaorg / celestia-app

Celestia consensus node
https://celestiaorg.github.io/celestia-app/
Apache License 2.0
345 stars 286 forks source link

Tx Lifetimes - an alternative replay protection mechanism #2900

Open cmwaters opened 11 months ago

cmwaters commented 11 months ago

Summary

This issue presents an alternative to the current replay protection mechanism: nonces. Nonces should remain but become an optional feature for those wanting serialisability of their transactions. Instead to avoid the same transaction from executing twice we have lifetimes: A network-wide agreed upon duration in blocks that a transaction can be submitted in before it becomes invalid. Users then include either the start height or the end height. The network uses the caching of hashes to ensure within the agreed upon lifetime that only one transaction can be submitted.

Problem Definition

Nonces are the current solution to replay protection but this has drawbacks. Most users don't care about the serialisability of transactions. The usage of nonces makes it difficult to have multiple transactions in flight as they could get reordered and the failure of a single transactions (either through validity or simply not enough gas price) means all following transactions are left hanging.

Proposal

Transactions already have a concept of a TTL, a height at which the transaction no longer becomes valid.

What happens then is that the network agrees upon a certain transaction lifetime, say 10 blocks. When a user submits a transaction they include either the start or end height (the other can be deduced). Across this range, the network ensures uniqueness by persisting the hashes of past transactions. A fraud proof can easily be created if this property is broken. Outside the range, the transaction can not be committed in a chain because it is invalid hence we achieve replay protection.

We already have local TTLs for mempools which are currently set to 5

References

https://docs.solana.com/developing/transaction_confirmation#what-is-a-blockhash

https://github.com/cosmos/cosmos-sdk/pull/18553/files

For Admin Use

Wondertan commented 11 months ago

How does persisting/caching work? Is it in memory or the state? I assume state because you mention the FraudProof, but the Cosmos's proposal mentions an in-mem map.

cmwaters commented 11 months ago

It's not part of state. It's persisted to disk and memory

evan-forbes commented 11 months ago

It's not part of state. It's persisted to disk and memory

are they committed to elsewhere? I'm assuming that the cache is consensus critical, therefore do we sync these when we state sync?

cmwaters commented 11 months ago

It doesn't need to be committed to state until we have fraud proofs. You can think of it as a block validity rule. The fraud proof might even be able to be constructed off the data_root instead of the app_hash in which case it doesn't need to be in state at all

evan-forbes commented 11 months ago

My understanding of this was that it was a tx/block validity rule in which case we'd vote nil firing process proposal and halt if a tx was committed to twice.

Avoiding halts would therefore require the cache, so my question is what are planning to do if a node doesn't sync from scratch.

Do we require that X blocks be downloaded before a block can be produced/verified, or do we commit to the cache somehow and check that the cache matches that commit during state sync?

cmwaters commented 11 months ago

Yeah it would have to be integrated with state sync. Maybe then we would need to add it to state.

Wondertan commented 11 months ago

What happens if demand grows to the point where the "dictionary" reaches its limit and no more users can send unordered txs?

cmwaters commented 11 months ago

What is this limit? You have 32 bytes for a hash and 10 blocks to maintain the cache for. With 10k transactions per block, it's 3.2mb of memory. That's not great but it's not really problematic. Additionally, the economics of PFBs and the presence of shared sequencers incentivise fewer large transactions.

Granted, checking nonces is cheaper. Perhaps the user can define a number instead of using the hash. Thus you'd have a map of address to a slice of integers

rootulp commented 2 weeks ago

A similar idea to tx lifetimes is proposed in Cosmos SDK ADR-070 and included in Cosmos SDK v0.52.x. One small difference between tx lifetimes and unordered transactions included in Cosmos SDK is how TTLs are determined:

parameter tx lifetimes unordered transactions
TTL block-based time-based