Open cmwaters opened 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.
It's not part of state. It's persisted to disk and memory
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?
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
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?
Yeah it would have to be integrated with state sync. Maybe then we would need to add it to state.
What happens if demand grows to the point where the "dictionary" reaches its limit and no more users can send unordered txs?
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
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