mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-03 14:47:16 +00:00
ABCI++ spec. First draft of properties
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
---
|
||||
order: 1
|
||||
title: New Methods
|
||||
---
|
||||
|
||||
# New Methods
|
||||
|
||||
## Description
|
||||
|
||||
### PrepareProposal
|
||||
|
||||
#### Parameters and Return values
|
||||
|
||||
TODO
|
||||
|
||||
#### When does Tendermint call it?
|
||||
|
||||
When a validator _p_ enters Tendermint consensus round _r_, height _h_, in which _p_ is the proposer:
|
||||
|
||||
1. _p_'s Tendermint collects the outstanding transactions from the mempool (TODO: should we limit size & gas?).
|
||||
2. _p_'s Tendermint creates a block header.
|
||||
3. _p_'s Tendermint calls `PrepareProposal` with the newly created block. The call is synchronous (i.e., Tendermint's execution will block until the Application returns).
|
||||
4. The Application checks the block (the header and transactions). It can also:
|
||||
* add/remove transactions
|
||||
* modify the header hashes
|
||||
* if the block is modified, the Application sets it in the return parameters
|
||||
5. The Application signals _Accept_ of _Reject_ in `PrepareProposal`'s return values
|
||||
* TODO: Decide if this kind if Accept/Reject is wanted/covered by impl (maybe a panic here makes more sense?)
|
||||
* If _Reject_, the proposed block --along with any modification-- is discarded. Tendermint interprets that there is nothing to be proposed for consensus at the moment and _p_ won't send any proposal message in round _r_, height _h_.
|
||||
* If _Accept_, _p_'s Tendermint uses the modified block as _p_'s proposal in round _r_, height _h_.
|
||||
|
||||
### ProcessProposal
|
||||
|
||||
#### Parameters and Return values
|
||||
|
||||
TODO
|
||||
|
||||
#### When does Tendermint call it?
|
||||
|
||||
When a validator _p_ enters Tendermint consensus round _r_, height _h_, in which _q_ is the proposer (possibly _p_ = _q_):
|
||||
|
||||
1. _p_ sets up timer `ProposeTimeout`.
|
||||
2. If _p_ is the proposer, execute steps 1-6 in _PrepareProposal_.
|
||||
3. Upon reception of `Proposal` message from _q_ for round _r_, height _h_, _p_'s Tendermint calls `ProcessProposal` with the newly received proposal. The call is synchronous.
|
||||
4. The Application checks/processes the proposed block, which is read-only, and returns _Accept_ or _Reject_.
|
||||
* Depending on the Application's needs, it may return from `ProcessProposal`
|
||||
* either after it has completely processed the block (the simpler case),
|
||||
* or immediately (after doing some basic checks), and process the block asynchronously. In this case the Application won't be able to reject the block, or force prevote/precommit `nil` afterwards.
|
||||
5. If the returned value is
|
||||
* _Reject_, Tendermint will prevote `nil` for the proposal in round _r_, height _h_ (this can be interpreted as _valid(v)_ returning false in the white paper's pseudocode)
|
||||
* _Accept_, Tendermint will follow the normal algorithm to prevote on the proposal in _r_, height _h_
|
||||
|
||||
### ExtendVote
|
||||
|
||||
#### Parameters and Return values
|
||||
|
||||
TODO
|
||||
|
||||
#### When does Tendermint call it?
|
||||
|
||||
When a validator _p_ is in Tendermint consensus round _r_, height _h_, state _prevote_, and the other conditions prescribed by the consensus algorithm for sending a _Precommit_ message are fulfilled:
|
||||
|
||||
1. _p_'s Terndermint updates the consensus state as prescriped by the algorithm (_validValue_, _lockedValue_, etc.)
|
||||
2. _p_'s Tendermint calls `ExtendVote` with the value that is about to be sent as precommit message. The call is synchronous.
|
||||
3. The Application returns an array of bytes, `precommit_extension`, which is not interpreted by Tendermint.
|
||||
4. _p_'s Tendermint includes `precommit_extension` as a new field in the `precommit` message.
|
||||
5. _p_'s Tendermint broadcasts the `precommit` message.
|
||||
|
||||
N.B: In Github discussions, I saw Dev becoming convinced that extending `nil` precommits is quite useless in practice. So I'd simplify the text above to only consider non-`nil` precommits. As it is now, the text is ambiguous when referrring to the "conditions".
|
||||
|
||||
### VerifyVoteExtension
|
||||
|
||||
#### Parameters and Return values
|
||||
|
||||
TODO
|
||||
|
||||
#### When does Tendermint call it?
|
||||
|
||||
When a validator _p_ is in Tendermint consensus round _r_, height _h_, state _prevote_, and _p_ receives a `Precommit` message for round _r_, height _h_ from _q_:
|
||||
|
||||
1. _p_'s Tendermint calls `VerifyVoteExtension`
|
||||
2. The Application returns Accept or Reject -- TODO: Can we really reject here? Discuss liveness problems
|
||||
3. _p_'s Tendermint deems the `precommit` message invalid if the Application returned Reject
|
||||
|
||||
### FinalizeBlock
|
||||
|
||||
#### Parameters and Return values
|
||||
|
||||
TODO
|
||||
|
||||
#### When is it called?
|
||||
|
||||
TODO: Quite simple. Equivalent to BeginBlock, [DeliverTx]*, EndBlock, Commit (?)
|
||||
|
||||
TODO: To discuss: An optimization could be the App setting a config to not send the whole block, just the hash or id
|
||||
|
||||
### [Unclear/controversial aspects]
|
||||
|
||||
#### Early evidence collecting (output of ProcessProposal in Dev's pseudocode)
|
||||
|
||||
Need to understand the use cases, in order to come up with the properties
|
||||
|
||||
#### Dev's v4 changes (a.k.a. _multithreaded ABCI++_)
|
||||
|
||||
Comments on the "fork-join" mechanism
|
||||
|
||||
* So far, the preferred operation mode for ABCI has been synchronous. The most notable exception is: checkTx (deliverTx is not really async). However, there are no strong properties to be expected from checkTx, relating the transactions it checks and their validity when they make it into a block.
|
||||
* The "join" part has two aims in the pseudocode (v4)
|
||||
* early collection and treatment of evidences. See above
|
||||
* influencing the pre-commit to be sent (whether _id(v)_ or `nil`)
|
||||
* TODO: Discuss strong liveness implications. Ask Josef: should I write something here and then discuss, or the other way around? (the latter seems more efficient)
|
||||
|
||||
#### Separation of `VerifyHeader` and `ProcessProposal`
|
||||
|
||||
To discuss. Starting point: it only makes sense if using the "Fork--Join" mechanism
|
||||
|
||||
##### [From Josef] We should understand the influence equivocation on proposals in ABCI++
|
||||
|
||||
TODO
|
||||
|
||||
#### Byzantine proposer
|
||||
|
||||
If Byzantine proposer proposes both A and B in the same round, today we might only receive A (proposal) and not B
|
||||
|
||||
#### `ProcessProposal`'s timeout (a.k.a. Zarko's Github comment)
|
||||
|
||||
TODO (to discuss): `PrepareProposal` must be synchronous, `ProcessProposal` may also want to fully process the block synchronously. However, they stand on the Tendermint's critical path, so the propose timeout needs to acknowledge that.
|
||||
|
||||
Idea: Make propose timestamp (current hardcoded to 3 secs in the implementation) part of ConsensusParams, so the App can adjust it with its knowledge of the time it takes
|
||||
|
||||
## Properties
|
||||
|
||||
[These are a sketch ATM]
|
||||
|
||||
### From Terndermint's point of view
|
||||
|
||||
`PrepareProposal`'s outcome (i.e., modified block and _Accept_ or _Reject_)
|
||||
|
||||
* it does not need to be deterministic
|
||||
|
||||
--
|
||||
|
||||
Discuss with Josef `PrepareProposal` in different rounds. Algo in paper allows different. Should we?
|
||||
|
||||
--
|
||||
|
||||
`ProcessProposal`'s outcome (_Accept_ or _Reject_):
|
||||
|
||||
* MUST be deterministic
|
||||
* MUST exclusively depend on the proposal's contents, and the Application's state that resulted from the last committed block
|
||||
|
||||
If this doesn't hold, Tendermint might not terminate (N.B: I'm not sure this is the case -- to discuss)
|
||||
|
||||
--
|
||||
|
||||
If `ProcessProposal`'s outcome is _Reject_ for some proposed block. Tendermint guarantees that the block will not be the decision.
|
||||
|
||||
TODO: This has implications on the termination mentioned above.
|
||||
|
||||
--
|
||||
|
||||
The validity of every transaction in a block (from the App's point of view), as well as the hashes in its header can be guaranteed if:
|
||||
|
||||
* `ProcessProposal` *synchronously* handles every proposed block as though Tendermint had already decided on it.
|
||||
* All the properties of `ProcessProposal` mentioned above hold.
|
||||
|
||||
--
|
||||
|
||||
What are the properties we can offer to ExtendVote/VerifyVoteExtension ?
|
||||
|
||||
* Can be many, a different one per round
|
||||
* In the same round, they are many as well: one per validator
|
||||
* TODO: ask Dev: what properties can/must the App guarantee when replying to ExtendVote (determinism?, same output?, no guarantees?)
|
||||
* The guarantees ABCI++ can offer depend on those
|
||||
|
||||
--
|
||||
|
||||
The two workflows discussed with Callum: App hash on N+1 vs App hash on N. How to capture it in ABCI++ ?
|
||||
|
||||
### From the Application's point of view
|
||||
|
||||
TODO
|
||||
|
||||
`ProcessProposal` in different rounds
|
||||
|
||||
`ExtendVote` in different rounds
|
||||
Reference in New Issue
Block a user