Role of abci::deliverTx - how to reject correctly?

Is it enough to reject an invalid transaction in checkTx or should deliverTx also do the checking (again)?

What happens when a transaction is rejected in deliverTx phase? would it not be included in the block? Since block creation is already in-progress at that point, is it correct to reject a block in deliverTx method?

1 Like

This is explained somewhat here: https://docs.tendermint.com/master/spec/abci/apps.html#transaction-results

Basically CheckTx will reject it from the mempool, so a correct proposer will never propose a tx in a block if it failed CheckTx. But its always possible a malicious proposer will put such a tx in a block, so DeliverTx must check as well. This does mean it’s possible for blocks to include invalid txs, though it should indicate that the proposer is malicious. The block will not be considered invalid, since blocks are committed before they’re executed - it just means that a valid block can contain an invalid transaction (which is weird if you’re coming from other blockchains). There’s a lot of flexibility left to the app developer but in general the DeliverTx should do at least as many checks as CheckTx.

Thank you @ebuchman

That is the concerning part:

DeliverTx can detect malicious transactions, but cannot do anything about them.

There does not seem to be any way malicious transactions can be rejected from entering the block for sure.

valid block can contain an invalid transaction: In such case, the burden of real validity falls onto the “reader” of the blocks (whenever anyone reads, they have to validate the transaction all over again), which somehow feels completely off the trajectory.

In other words, Tendermint is no more reliable than any other plain database. (reliable as in, to contain only verified and validated facts that one can rely on). i.e. the whole ‘consensus’ part becomes broken off (or unreliable, and reader has to get the consensus all over again from all parties)

Hoping to see to some fixes for this, if possible.

Few corollaries of the current design:

  • If DeliverTx cannot reject the transaction, then it follows that it does not even make sense to check for their validity in the first place.
  • It even brings the question of why should checkTx validate it either, given that anyone can else maliciously add bad transactions anyway.