cosmos-sdk: Slash block proposer polluting the state
Summary
In SDK we don’t have a slashing logic for a validator putting rubbish transactions in a block.
Problem Definition
There are many types of invalid transaction. We can group them into 2 categories:
- Category A: tx which don’t pass the initial checks through
CheckTx: unmarshaling (check if transaction is properly serialized), signatures… without running the transaction. - Category B: tx is invalidated only during transaction execution (double spend, insufficient funds etc…).
Transactions from Category A are completely rubbish because nobody will pay for them. These transaction will pollute the blockchain (both the block space and long term storage) and the processing power of the whole network (validators will still need to process the block).
Transaction author will still need to pay a fee for processing an invalid transaction of Category B. These transaction won’t make any effect except being recorded as a part of a block and fee charging. They also pollute a chain and at least someone is paying for them.
Related problem: voters don’t see transactions when voting on a block.
In Tendermint, voters don’t see the block transaction when voting on a proposed block. Hence they can’t oppose to accept a block if the block is rubbish. However, if such block is committed, everyone can provide an evidence of a misbehave and an honest validator should include a slashing transaction in a block at some point.
Proposal
Including transactions of category A should be slashable. The block producer doesn’t have any “on-chain” benefit from it and it consumes a space. Transactions for category B is a misbehave, but it’s hard to judge if it should be slashable.
- Create evidence and slashing conditions for misbehave of category A.
- Research sound conditions for slashing misbehave of category B.
NOTE: if accepted in SDK, this should be configurable.
Further discussion
We can also consider the following events as a misbehave leading to slashing events :
- empty (or x% empty) blocks (it’s hard to prove if a block producer has valid transactions in a mempool)
References
- Discord discussion about transaction validation and security.
- Further investigate execution: Lazy ledger research to enable transaction processing during the voting phase.
For Admin Use
- Not duplicate issue
- Appropriate labels applied
- Appropriate contributors tagged
- Contributor assigned/self-assigned
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 15 (9 by maintainers)
@robert-zaremba that is correct.
Yep. One thing that I think is making this unclear is that we’re using the terms CheckTx and antehandler interchangeably because currently, the CheckTx just runs the antehandler. However, they’re not the same thing. The proper thing is that “with ABCI++, all nodes should run the antehandlers as part of process proposal”.
Yep trying to prevent category B txs doesn’t work. It would open up spam attacks.
Just want to note that slashing for inclusion of txs that fail checkTx doesn’t work right now. During CheckTx, the SDK’s ante handler is run. During DeliverTx, each tx is run in order, first the ante handler and then the rest of the tx execution.
Problem is that some txs that passed antehandler during checktx, might fail during delivertx, because they were affected by the execution of a previous tx.
The obvious example is that if AddrA has two txs in this block, tx1 and tx2. It needs to pay fees for both txs, and it has the balance to do both of them, so it passes checktxs. But now if during the DeliverTx of tx1, it sends the entire balance of the account to a new address, it will fail the tx2’s DeliverTx antehandler.
What we will want to do is execute all the antehandlers of all txs in order first, and then the rest of the execution. This can take the form of executing the antehandlers immediately as part of ProcessProposal. Or it can be done during DeliverBlock.