Skip to content
Tuan Pham Anh edited this page Jan 20, 2017 · 1 revision

https://github.com/tendermint/tendermint/issues/238

Q: I notice that a tx is only checked for validation in a single node before put in mempool , if this node is faulty or malicious (say cheating), then this malicious tx will also be included in block, also executed by other nodes. Is it a problem?

If one node receives a proposal, should this node validate all txs in the proposal? or just vote yes for the entire proposal? when will it vote no?

A: So it is possible for invalid txs to be incluided in a block; but we specifically list which txs are valid and which are not. Good validstors will never put bad txs in a block. A bad validator might put only bad txs in a block. As long as number of bad validators is limited, it shouldnt be much of a problem. Alternatively there are strategies we will implement down the road to minimize the effect

Q: How and where are valid txs listed?

A: Currently we're only tracking in memory, need to update the block header to include a bitarray of valid txs

Q: Isnt it a problem that bad txs are executed?

A: Not necessarily. They have no effect on state they are just included in blocks. we will update that so they at least pay some kind of fee, we're aware and working towards it.

Q: So a node always vote yes as long as it received proposal?

A: As long as the proposal is well formed and so on, yes, it does not run the block until after its been committed

Q: I thought that the application should decide which transactions are valid and have a method of only proposing valid transactions?

A: Yes, that happens with CheckTx. But if a proposer is malicious, it can do things like proposing invalid txs.

If all the proposers are good and the application is correct, all blocks will only have “good” txs. “Good” means it passes CheckTx.

But if any proposer is bad, bad txs may get included as well. In the near future we’ll include a list of TMSP return codes in the blockchain (in the next block), so anyone can see whether the txs were valid or not.

So the txs in the blockchain are more about, “which txs, in order, were tried by all the nodes?”… and some of those txs can be bad.

If you need to provide a feature to a user that provably tries to show that a tx was included in the blockchain and don’t care about the response code, you can use the existing Merkle root.

We are also adding in a new Merkle tree of all the txs along with their response codes.


Q: Is there a recommended procedure to reconcile double spends being committed to a block with the tmsp api? Or do I have to use a sort of secondary temporary state that exists between block commits that keeps track of the txs that have been checked against me via CheckTx? It seems if I don’t then if I check against my state since the last block commit, then I may accept two txs that conflict.

Clearly I won’t be able to accept the two txs when we get to the second in the sequence of CommitTx callbacks, so how does the he engine reconcile that? It seems like all the nodes would be in a broken state

A: You need to develop the logic to prevent replay/double spend yourself, based on your needs. Could be a nonce (monotonically incrementing integer) that you use when signing a transaction for instance. you implement replay/double spend yourself in app - checktx can offer "early reject" if you and up having two conflicting txs commited in same block, the last one will fail if you have this protection in place. The result of appendTx will be recorded in the block, but all nodes will be in same consistent state as the order of txs were agreed upon.

no state is changed in checktx it's just to sort out any clearly invalid txs.

Q: Since tx0 might conflict with tx1, would I have to make a duped current state that I can cycle that would remember what tx0 did atleast temporarily?

A: theoretically, you could have a no-op in checktx and just use appendtx exclusively.. but ethan/jae might be better able to to say for sure

Q: Would a CheckConflictingTxs type api callback that would return any conflicting txs be useful?

A: Tendermint doesn't know anything about the tx payload (= your application logic), so it wouldn't be able to tell a conflicting tx from a non-conflicting. The app would have to tell it.

Q: Is CheckTx is invoked on all nodes before AppendTx.. or just used to sanity check a tx before proposing it to other nodes.

A: Checktx is mempool acceptance. Appendtx is consensus phase.

Proposers are supposed to propose blocks with txs that passed CheckTx, in the order that they were checked. So if you implement that "secondary temporary state”, you can have all AppendTxs by honest proposers be OK. But dishonest proposers can still proposer bad blocks, so this needs to be taken into consideration.

Don’t expect txs in the blockchain to be valid… we will make changes to TendermintCore in the coming months to record the response codes so there will be a separate field in the Blocks that record the AppendTx response codes.

This "secondary temporary state” should act as a cache of the AppendTx primary state. The tricky part is that CheckTx can run concurrently with AppendTx (interleaved, not multithreaded) so this can invalidate CheckTxs… but, the solution we’re adopting in TendermintCore is to re-run the mempool’s Check’d txs in order, after a block is committed and AppendTxs are run, so, honest proposers will still be able to propose blocks with only valid txs that pass CheckTx.

CheckTx is invoked by all nodes prior to broadcasting a tx to peers… it’s not invoked upon commit of a block though… but the proposer does invoke it before proposing the block. So it’s invoked in two places… proposing, and mempool gossip.

Q: Will I see a checktx for the same tx twice then? that confounds having a separate cached state a bit

A: Yes. The second time could happen if you’re a proposer… but it happens after EndBlock/Commit so you can clear the secondary checktx state there.

so I’m the next proposer… I ran CheckTx as I received a new tx from a peer… then I see a block commit. Then I’ll run AppendTx on those txs and run EndBlock/Commit. During this time I can reset the secondary CheckTx state. Then I’ll run that tx through CheckTx again before proposing.

Q: This response code to be implimented might be an app state hash then?

A: Just a numeric code. To keep it light. The numeric respond code for each tx will just record a code that says whether the tx was OK, or if any specific exception happened, like running out of gas in the EVM...

So for example, when running out of gas in the EVM, CheckTx can return OK as long as the user has sufficient funds to pay for the gas that it declared as the gas limit on that tx. But on AppendTx it can return any error code, like ErrRanOutOfGas

Currently for the app Merkle hash we only support that once per block in Commit… I suppose we could change that in the future, but I don’t need per-tx app-state-roots atm.

everything should be verifiable with the previous state hash and the txs in the oncoming block

Clone this wiki locally