Skip to content

Commit 735a1a5

Browse files
sergio-menaDaniel
andauthored
Fixed math notation in ABCI++ app requirements (tendermint#8499)
* Fixed math notation in ABCI++ app requirements * Update spec/abci++/abci++_app_requirements_002_draft.md Co-authored-by: Daniel <[email protected]> * Update spec/abci++/abci++_app_requirements_002_draft.md Co-authored-by: Daniel <[email protected]> * Update spec/abci++/abci++_app_requirements_002_draft.md Co-authored-by: Daniel <[email protected]> * Update spec/abci++/abci++_app_requirements_002_draft.md Co-authored-by: Daniel <[email protected]> Co-authored-by: Daniel <[email protected]>
1 parent c052181 commit 735a1a5

File tree

1 file changed

+101
-87
lines changed

1 file changed

+101
-87
lines changed

spec/abci++/abci++_app_requirements_002_draft.md

Lines changed: 101 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -6,77 +6,81 @@ title: Application Requirements
66
# Application Requirements
77

88
This section specifies what Tendermint expects from the Application. It is structured as a set
9-
of formal requirement that can be used for testing and verification of the Application's logic.
10-
11-
Let $p$ and $q$ be two different correct proposers in rounds $r_p$ and $r_q$ respectively, in height $h$.
12-
Let $s_{p,h-1}$ be $p$'s Application's state committed for height $h-1$.
13-
Let $v_p$ (resp. $v_q$) be the block that $p$'s (resp. $q$'s) Tendermint passes on to the Application
14-
via `RequestPrepareProposal` as proposer of round $r_p$ (resp $r_q$), height $h$, also known as the
15-
raw proposal.
16-
Let $v'_p$ (resp. $v'_q$) the possibly modified block $p$'s (resp. $q$'s) Application returns via
17-
`ResponsePrepareProposal` to Tendermint, also known as the prepared proposal.
18-
19-
Process $p$'s prepared proposal can differ in two different rounds where $p$ is the proposer.
20-
21-
* Requirement 1 [`PrepareProposal`, header-changes] When the blockchain is in same-block execution mode,
22-
$p$'s Application provides values for the following parameters in `ResponsePrepareProposal`:
23-
_AppHash_, _TxResults_, _ConsensusParams_, _ValidatorUpdates_. Provided values for
24-
_ConsensusParams_ and _ValidatorUpdates_ MAY be empty to denote that the Application
9+
of formal requirements that can be used for testing and verification of the Application's logic.
10+
11+
Let *p* and *q* be two different correct proposers in rounds *r<sub>p</sub>* and *r<sub>q</sub>*
12+
respectively, in height *h*.
13+
Let *s<sub>p,h-1</sub>* be *p*'s Application's state committed for height *h-1*.
14+
Let *v<sub>p</sub>* (resp. *v<sub>q</sub>*) be the block that *p*'s (resp. *q*'s) Tendermint passes
15+
on to the Application
16+
via `RequestPrepareProposal` as proposer of round *r<sub>p</sub>* (resp *r<sub>q</sub>*), height *h*,
17+
also known as the raw proposal.
18+
Let *v'<sub>p</sub>* (resp. *v'<sub>q</sub>*) the possibly modified block *p*'s (resp. *q*'s) Application
19+
returns via `ResponsePrepareProposal` to Tendermint, also known as the prepared proposal.
20+
21+
Process *p*'s prepared proposal can differ in two different rounds where *p* is the proposer.
22+
23+
* Requirement 1 [`PrepareProposal`, header-changes]: When the blockchain is in same-block execution mode,
24+
*p*'s Application provides values for the following parameters in `ResponsePrepareProposal`:
25+
`AppHash`, `TxResults`, `ConsensusParams`, `ValidatorUpdates`. Provided values for
26+
`ConsensusParams` and `ValidatorUpdates` MAY be empty to denote that the Application
2527
wishes to keep the current values.
2628

27-
Parameters _AppHash_, _TxResults_, _ConsensusParams_, and _ValidatorUpdates_ are used by Tendermint to
29+
Parameters `AppHash`, `TxResults`, `ConsensusParams`, and `ValidatorUpdates` are used by Tendermint to
2830
compute various hashes in the block header that will finally be part of the proposal.
2931

30-
* Requirement 2 [`PrepareProposal`, no-header-changes] When the blockchain is in next-block execution
31-
mode, $p$'s Application does not provide values for the following parameters in `ResponsePrepareProposal`:
32-
_AppHash_, _TxResults_, _ConsensusParams_, _ValidatorUpdates_.
32+
* Requirement 2 [`PrepareProposal`, no-header-changes]: When the blockchain is in next-block execution
33+
mode, *p*'s Application does not provide values for the following parameters in `ResponsePrepareProposal`:
34+
`AppHash`, `TxResults`, `ConsensusParams`, `ValidatorUpdates`.
3335

3436
In practical terms, Requirements 1 and 2 imply that Tendermint will (a) panic if the Application is in
35-
same-block execution mode and _does_ _not_ provide values for
36-
_AppHash_, _TxResults_, _ConsensusParams_, and _ValidatorUpdates_, or
37-
(b) log an error if the Application is in next-block execution mode and _does_ provide values for
38-
_AppHash_, _TxResults_, _ConsensusParams_, or _ValidatorUpdates_ (the values provided will be ignored).
37+
same-block execution mode and *does not* provide values for
38+
`AppHash`, `TxResults`, `ConsensusParams`, and `ValidatorUpdates`, or
39+
(b) log an error if the Application is in next-block execution mode and *does* provide values for
40+
`AppHash`, `TxResults`, `ConsensusParams`, or `ValidatorUpdates` (the values provided will be ignored).
3941

40-
* Requirement 3 [`PrepareProposal`, timeliness] If $p$'s Application fully executes prepared blocks in
41-
`PrepareProposal` and the network is in a synchronous period while processes $p$ and $q$ are in $r_p$, then
42-
the value of *TimeoutPropose* at $q$ must be such that $q$'s propose timer does not time out
43-
(which would result in $q$ prevoting *nil* in $r_p$).
42+
* Requirement 3 [`PrepareProposal`, timeliness]: If *p*'s Application fully executes prepared blocks in
43+
`PrepareProposal` and the network is in a synchronous period while processes *p* and *q* are in *r<sub>p</sub>*,
44+
then the value of *TimeoutPropose* at *q* must be such that *q*'s propose timer does not time out
45+
(which would result in *q* prevoting `nil` in *r<sub>p</sub>*).
4446

4547
Full execution of blocks at `PrepareProposal` time stands on Tendermint's critical path. Thus,
46-
Requirement 3 ensures the Application will set a value for _TimeoutPropose_ such that the time it takes
48+
Requirement 3 ensures the Application will set a value for `TimeoutPropose` such that the time it takes
4749
to fully execute blocks in `PrepareProposal` does not interfere with Tendermint's propose timer.
4850

49-
* Requirement 4 [`PrepareProposal`, tx-size] When $p$'s Application calls `ResponsePrepareProposal`, the
51+
* Requirement 4 [`PrepareProposal`, tx-size]: When *p*'s Application calls `ResponsePrepareProposal`, the
5052
total size in bytes of the transactions returned does not exceed `RequestPrepareProposal.max_tx_bytes`.
5153

5254
Busy blockchains might seek to maximize the amount of transactions included in each block. Under those conditions,
5355
Tendermint might choose to increase the transactions passed to the Application via `RequestPrepareProposal.txs`
5456
beyond the `RequestPrepareProposal.max_tx_bytes` limit. The idea is that, if the Application drops some of
5557
those transactions, it can still return a transaction list whose byte size is as close to
5658
`RequestPrepareProposal.max_tx_bytes` as possible. Thus, Requirement 4 ensures that the size in bytes of the
57-
transaction list returned by the application will never cause the resulting block to go beyond its byte limit.
59+
transaction list returned by the application will never cause the resulting block to go beyond its byte size
60+
limit.
5861

59-
* Requirement 5 [`PrepareProposal`, `ProcessProposal`, coherence]: For any two correct processes $p$ and $q$,
60-
if $q$'s Tendermint calls `RequestProcessProposal` on $v'_p$,
61-
$q$'s Application returns Accept in `ResponseProcessProposal`.
62+
* Requirement 5 [`PrepareProposal`, `ProcessProposal`, coherence]: For any two correct processes *p* and *q*,
63+
if *q*'s Tendermint calls `RequestProcessProposal` on *v'<sub>p</sub>*,
64+
*q*'s Application returns Accept in `ResponseProcessProposal`.
6265

63-
Requirement 5 makes sure that blocks proposed by correct processes _always_ pass the correct receiving process's
66+
Requirement 5 makes sure that blocks proposed by correct processes *always* pass the correct receiving process's
6467
`ProcessProposal` check.
6568
On the other hand, if there is a deterministic bug in `PrepareProposal` or `ProcessProposal` (or in both),
6669
strictly speaking, this makes all processes that hit the bug byzantine. This is a problem in practice,
67-
as very often validators are running the Application from the same codebase, so potentially _all_ would
70+
as very often validators are running the Application from the same codebase, so potentially *all* would
6871
likely hit the bug at the same time. This would result in most (or all) processes prevoting `nil`, with the
6972
serious consequences on Tendermint's liveness that this entails. Due to its criticality, Requirement 5 is a
7073
target for extensive testing and automated verification.
7174

7275
* Requirement 6 [`ProcessProposal`, determinism-1]: `ProcessProposal` is a (deterministic) function of the current
73-
state and the block that is about to be applied. In other words, for any correct process $p$, and any arbitrary block $v'$,
74-
if $p$'s Tendermint calls `RequestProcessProposal` on $v'$ at height $h$,
75-
then $p$'s Application's acceptance or rejection **exclusively** depends on $v'$ and $s_{p,h-1}$.
76-
77-
* Requirement 7 [`ProcessProposal`, determinism-2]: For any two correct processes $p$ and $q$, and any arbitrary block $v'$,
78-
if $p$'s (resp. $q$'s) Tendermint calls `RequestProcessProposal` on $v'$ at height $h$,
79-
then $p$'s Application accepts $v'$ if and only if $q$'s Application accepts $v'$.
76+
state and the block that is about to be applied. In other words, for any correct process *p*, and any arbitrary block *v'*,
77+
if *p*'s Tendermint calls `RequestProcessProposal` on *v'* at height *h*,
78+
then *p*'s Application's acceptance or rejection **exclusively** depends on *v'* and *s<sub>p,h-1</sub>*.
79+
80+
* Requirement 7 [`ProcessProposal`, determinism-2]: For any two correct processes *p* and *q*, and any arbitrary
81+
block *v'*,
82+
if *p*'s (resp. *q*'s) Tendermint calls `RequestProcessProposal` on *v'* at height *h*,
83+
then *p*'s Application accepts *v'* if and only if *q*'s Application accepts *v'*.
8084
Note that this requirement follows from Requirement 6 and the Agreement property of consensus.
8185

8286
Requirements 6 and 7 ensure that all correct processes will react in the same way to a proposed block, even
@@ -87,79 +91,89 @@ In such a scenario, Tendermint's liveness cannot be guaranteed.
8791
Again, this is a problem in practice if most validators are running the same software, as they are likely
8892
to hit the bug at the same point. There is currently no clear solution to help with this situation, so
8993
the Application designers/implementors must proceed very carefully with the logic/implementation
90-
of `ProcessProposal`. As a general rule `ProcessProposal` _should_ always accept the block.
91-
92-
According to the Tendermint algorithm, a correct process can broadcast at most one precommit message in round $r$, height $h$.
93-
Since, as stated in the [Description](#description) section, `ResponseExtendVote` is only called when Tendermint
94-
is about to broadcast a non-`nil` precommit message, a correct process can only produce one vote extension in round $r$, height $h$.
95-
Let $e^r_p$ be the vote extension that the Application of a correct process $p$ returns via `ResponseExtendVote` in round $r$, height $h$.
96-
Let $w^r_p$ be the proposed block that $p$'s Tendermint passes to the Application via `RequestExtendVote` in round $r$, height $h$.
97-
98-
* Requirement 8 [`ExtendVote`, `VerifyVoteExtension`, coherence]: For any two correct processes $p$ and $q$, if $q$ receives $e^r_p$
99-
from $p$ in height $h$, $q$'s Application returns Accept in `ResponseVerifyVoteExtension`.
94+
of `ProcessProposal`. As a general rule `ProcessProposal` SHOULD always accept the block.
95+
96+
According to the Tendermint algorithm, a correct process can broadcast at most one precommit
97+
message in round *r*, height *h*.
98+
Since, as stated in the [Methods](./abci++_methods_002_draft.md#extendvote) section, `ResponseExtendVote`
99+
is only called when Tendermint
100+
is about to broadcast a non-`nil` precommit message, a correct process can only produce one vote extension
101+
in round *r*, height *h*.
102+
Let *e<sup>r</sup><sub>p</sub>* be the vote extension that the Application of a correct process *p* returns via
103+
`ResponseExtendVote` in round *r*, height *h*.
104+
Let *w<sup>r</sup><sub>p</sub>* be the proposed block that *p*'s Tendermint passes to the Application via `RequestExtendVote`
105+
in round *r*, height *h*.
106+
107+
* Requirement 8 [`ExtendVote`, `VerifyVoteExtension`, coherence]: For any two correct processes *p* and *q*, if *q*
108+
receives *e<sup>r</sup><sub>p</sub>*
109+
from *p* in height *h*, *q*'s Application returns Accept in `ResponseVerifyVoteExtension`.
100110

101111
Requirement 8 constrains the creation and handling of vote extensions in a similar way as Requirement 5
102-
contrains the creation and handling of proposed blocks.
103-
Requirement 8 ensures that extensions created by correct processes _always_ pass the `VerifyVoteExtension`
112+
constrains the creation and handling of proposed blocks.
113+
Requirement 8 ensures that extensions created by correct processes *always* pass the `VerifyVoteExtension`
104114
checks performed by correct processes receiving those extensions.
105115
However, if there is a (deterministic) bug in `ExtendVote` or `VerifyVoteExtension` (or in both),
106116
we will face the same liveness issues as described for Requirement 5, as Precommit messages with invalid vote
107117
extensions will be discarded.
108118

109119
* Requirement 9 [`VerifyVoteExtension`, determinism-1]: `VerifyVoteExtension` is a (deterministic) function of
110120
the current state, the vote extension received, and the prepared proposal that the extension refers to.
111-
In other words, for any correct process $p$, and any arbitrary vote extension $e$, and any arbitrary
112-
block $w$, if $p$'s (resp. $q$'s) Tendermint calls `RequestVerifyVoteExtension` on $e$ and $w$ at height $h$,
113-
then $p$'s Application's acceptance or rejection **exclusively** depends on $e$, $w$ and $s_{p,h-1}$.
114-
115-
* Requirement 10 [`VerifyVoteExtension`, determinism-2]: For any two correct processes $p$ and $q$,
116-
and any arbitrary vote extension $e$, and any arbitrary block $w$,
117-
if $p$'s (resp. $q$'s) Tendermint calls `RequestVerifyVoteExtension` on $e$ and $w$ at height $h$,
118-
then $p$'s Application accepts $e$ if and only if $q$'s Application accepts $e$.
121+
In other words, for any correct process *p*, and any arbitrary vote extension *e*, and any arbitrary
122+
block *w*, if *p*'s (resp. *q*'s) Tendermint calls `RequestVerifyVoteExtension` on *e* and *w* at height *h*,
123+
then *p*'s Application's acceptance or rejection **exclusively** depends on *e*, *w* and *s<sub>p,h-1</sub>*.
124+
125+
* Requirement 10 [`VerifyVoteExtension`, determinism-2]: For any two correct processes *p* and *q*,
126+
and any arbitrary vote extension *e*, and any arbitrary block *w*,
127+
if *p*'s (resp. *q*'s) Tendermint calls `RequestVerifyVoteExtension` on *e* and *w* at height *h*,
128+
then *p*'s Application accepts *e* if and only if *q*'s Application accepts *e*.
119129
Note that this requirement follows from Requirement 9 and the Agreement property of consensus.
120130

121131
Requirements 9 and 10 ensure that the validation of vote extensions will be deterministic at all
122132
correct processes.
123-
Requirements 9 and 10 protect against arbitrary vote extension data from Byzantine processes
124-
similarly to Requirements 6 and 7 and proposed blocks.
133+
Requirements 9 and 10 protect against arbitrary vote extension data from Byzantine processes,
134+
in a similar way as Requirements 6 and 7 protect against arbitrary proposed blocks.
125135
Requirements 9 and 10 can be violated by a bug inducing non-determinism in
126136
`VerifyVoteExtension`. In this case liveness can be compromised.
127-
Extra care should be put in the implementation of `ExtendVote` and `VerifyVoteExtension` and,
128-
as a general rule, `VerifyVoteExtension` _should_ always accept the vote extension.
137+
Extra care should be put in the implementation of `ExtendVote` and `VerifyVoteExtension`.
138+
As a general rule, `VerifyVoteExtension` SHOULD always accept the vote extension.
129139

130-
* Requirement 11 [_all_, no-side-effects]: $p$'s calls to `RequestPrepareProposal`,
131-
`RequestProcessProposal`, `RequestExtendVote`, and `RequestVerifyVoteExtension` at height $h$ do
132-
not modify $s_{p,h-1}$.
140+
* Requirement 11 [*all*, no-side-effects]: *p*'s calls to `RequestPrepareProposal`,
141+
`RequestProcessProposal`, `RequestExtendVote`, and `RequestVerifyVoteExtension` at height *h* do
142+
not modify *s<sub>p,h-1</sub>*.
133143

134-
* Requirement 12 [`ExtendVote`, `FinalizeBlock`, non-dependency]: for any correct process $p$,
135-
and any vote extension $e$ that $p$ received at height $h$, the computation of
136-
$s_{p,h}$ does not depend on $e$.
144+
* Requirement 12 [`ExtendVote`, `FinalizeBlock`, non-dependency]: for any correct process *p*,
145+
and any vote extension *e* that *p* received at height *h*, the computation of
146+
*s<sub>p,h</sub>* does not depend on *e*.
137147

138-
The call to correct process $p$'s `RequestFinalizeBlock` at height $h$, with block $v_{p,h}$
139-
passed as parameter, creates state $s_{p,h}$.
148+
The call to correct process *p*'s `RequestFinalizeBlock` at height *h*, with block *v<sub>p,h</sub>*
149+
passed as parameter, creates state *s<sub>p,h</sub>*.
140150
Additionally,
141151

142-
* in next-block execution mode, $p$'s `FinalizeBlock` creates a set of transaction results $T_{p,h}$,
143-
* in same-block execution mode, $p$'s `PrepareProposal` creates a set of transaction results $T_{p,h}$
144-
if $p$ was the proposer of $v_{p,h}$, otherwise `FinalizeBlock` creates $T_{p,h}$.
152+
* in next-block execution mode, *p*'s `FinalizeBlock` creates a set of transaction results *T<sub>p,h</sub>*,
153+
* in same-block execution mode, *p*'s `PrepareProposal` creates a set of transaction results *T<sub>p,h</sub>*
154+
if *p* was the proposer of *v<sub>p,h</sub>*. If *p* was not the proposer of *v<sub>p,h</sub>*,
155+
`ProcessProposal` creates *T<sub>p,h</sub>*. `FinalizeBlock` MAY re-create *T<sub>p,h</sub>* if it was
156+
removed from memory during the execution of height *h*.
145157

146-
* Requirement 13 [`FinalizeBlock`, determinism-1]: For any correct process $p$,
147-
$s_{p,h}$ exclusively depends on $s_{p,h-1}$ and $v_{p,h}$.
158+
* Requirement 13 [`FinalizeBlock`, determinism-1]: For any correct process *p*,
159+
*s<sub>p,h</sub>* exclusively depends on *s<sub>p,h-1</sub>* and *v<sub>p,h</sub>*.
148160

149-
* Requirement 14 [`FinalizeBlock`, determinism-2]: For any correct process $p$,
150-
the contents of $T_{p,h}$ exclusively depend on $s_{p,h-1}$ and $v_{p,h}$.
161+
* Requirement 14 [`FinalizeBlock`, determinism-2]: For any correct process *p*,
162+
the contents of *T<sub>p,h</sub>* exclusively depend on *s<sub>p,h-1</sub>* and *v<sub>p,h</sub>*.
151163

152164
Note that Requirements 13 and 14, combined with Agreement property of consensus ensure
153-
the Application state evolves consistently at all correct processes.
165+
state machine replication, i.e., the Application state evolves consistently at all correct processes.
154166

155167
Finally, notice that neither `PrepareProposal` nor `ExtendVote` have determinism-related
156168
requirements associated.
157169
Indeed, `PrepareProposal` is not required to be deterministic:
158170

159-
* $v'_p$ may depend on $v_p$ and $s_{p,h-1}$, but may also depend on other values or operations.
160-
* $v_p = v_q \nRightarrow v'_p = v'_q$.
171+
* *v'<sub>p</sub>* may depend on *v<sub>p</sub>* and *s<sub>p,h-1</sub>*, but may also depend on other values or operations.
172+
* *v<sub>p</sub> = v<sub>q</sub> &#8655; v'<sub>p</sub> = v'<sub>q</sub>*.
161173

162174
Likewise, `ExtendVote` can also be non-deterministic:
163175

164-
* $e^r_p$ may depend on $w^r_p$ and $s_{p,h-1}$, but may also depend on other values or operations.
165-
* $w^r_p = w^r_q \nRightarrow e^r_p = e^r_q$
176+
* *e<sup>r</sup><sub>p</sub>* may depend on *w<sup>r</sup><sub>p</sub>* and *s<sub>p,h-1</sub>*,
177+
but may also depend on other values or operations.
178+
* *w<sup>r</sup><sub>p</sub> = w<sup>r</sup><sub>q</sub> &#8655;
179+
e<sup>r</sup><sub>p</sub> = e<sup>r</sup><sub>q</sub>*

0 commit comments

Comments
 (0)