abci/async_api/
application.rs

1use async_trait::async_trait;
2
3use crate::types::*;
4
5/// Trait for initialization and for queries from the user.
6#[async_trait]
7pub trait Info: Send + Sync {
8    /// Echo a string to test abci client/server implementation.
9    ///
10    /// # Equivalent to
11    ///
12    /// ```rust,ignore
13    /// async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho
14    /// ```
15    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
16        ResponseEcho {
17            message: echo_request.message,
18        }
19    }
20
21    /// Return information about the application state.
22    ///
23    /// # Crash Recovery
24    ///
25    /// On startup, Tendermint calls the [`info`] method to get the **latest committed state** of the app. The app
26    /// **MUST** return information consistent with the last block it successfully completed [`commit`] for.
27    ///
28    /// If the app succesfully committed block `H` but not `H+1`, then
29    /// - `last_block_height = H`
30    /// - `last_block_app_hash = <hash returned by Commit for block H>`
31    ///
32    /// If the app failed during the [`commit`] of block `H`, then
33    /// - `last_block_height = H-1`
34    /// - `last_block_app_hash = <hash returned by Commit for block H-1, which is the hash in the header of block H>`
35    ///
36    /// [`info`]: trait.Info.html#tymethod.info
37    /// [`commit`]: trait.Consensus.html#tymethod.commit
38    ///
39    /// # Equivalent to
40    ///
41    /// ```rust,ignore
42    /// async fn info(&self, info_request: RequestInfo) -> ResponseInfo
43    /// ```
44    async fn info(&self, info_request: RequestInfo) -> ResponseInfo;
45
46    /// Set non-consensus critical application specific options.
47    ///
48    /// # Equivalent to
49    ///
50    /// ```rust,ignore
51    /// async fn set_option(&self, set_option_request: RequestSetOption) -> ResponseSetOption
52    /// ```
53    async fn set_option(&self, _set_option_request: RequestSetOption) -> ResponseSetOption {
54        Default::default()
55    }
56
57    /// Query for data from the application at current or past height.
58    ///
59    /// # Equivalent to
60    ///
61    /// ```rust,ignore
62    /// async fn query(&self, query_request: RequestQuery) -> ResponseQuery
63    /// ```
64    async fn query(&self, _query_request: RequestQuery) -> ResponseQuery {
65        Default::default()
66    }
67
68    /// Signals that messages queued on the client should be flushed to the server.
69    ///
70    /// # Equivalent to
71    ///
72    /// ```rust,ignore
73    /// async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush
74    /// ```
75    async fn flush(&self, _flush_request: RequestFlush) -> ResponseFlush {
76        Default::default()
77    }
78}
79
80/// Trait for managing consensus of blockchain.
81///
82/// # Details
83///
84/// [_Consensus_] should maintain a `consensus_state` - the working state for block execution. It should be updated by
85/// the calls to [`begin_block`], [`deliver_tx`], and [`end_block`] during block execution and committed to disk as the
86/// **latest committed state** during [`commit`].
87///
88/// Updates made to the `consensus_state` by each method call must be readable by each subsequent method - ie. the
89/// updates are linearizable.
90///
91/// [_Consensus_]: trait.Consensus.html#details
92/// [`begin_block`]: trait.Consensus.html#tymethod.begin_block
93/// [`deliver_tx`]: trait.Consensus.html#tymethod.deliver_tx
94/// [`end_block`]: trait.Consensus.html#tymethod.end_block
95/// [`commit`]: trait.Consensus.html#tymethod.commit
96#[async_trait]
97pub trait Consensus: Send + Sync {
98    /// Echo a string to test abci client/server implementation.
99    ///
100    /// # Equivalent to
101    ///
102    /// ```rust,ignore
103    /// async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho
104    /// ```
105    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
106        ResponseEcho {
107            message: echo_request.message,
108        }
109    }
110
111    /// Called once upon genesis. Usually used to establish initial (genesis) state.
112    ///
113    /// # Equivalent to
114    ///
115    /// ```rust,ignore
116    /// async fn init_chain(&self, init_chain_request: RequestInitChain) -> ResponseInitChain
117    /// ```
118    async fn init_chain(&self, init_chain_request: RequestInitChain) -> ResponseInitChain;
119
120    /// Signals the beginning of a new block. Called prior to any [`deliver_tx`](trait.Consensus.html#tymethod.deliver_tx)s.
121    ///
122    /// # Equivalent to
123    ///
124    /// ```rust,ignore
125    /// async fn begin_block(&self, begin_block_request: RequestBeginBlock) -> ResponseBeginBlock
126    /// ```
127    async fn begin_block(&self, begin_block_request: RequestBeginBlock) -> ResponseBeginBlock;
128
129    /// Execute the transaction in full. The workhorse of the application.
130    ///
131    /// # Equivalent to
132    ///
133    /// ```rust,ignore
134    /// async fn deliver_tx(&self, deliver_tx_request: RequestDeliverTx) -> ResponseDeliverTx
135    /// ```
136    async fn deliver_tx(&self, deliver_tx_request: RequestDeliverTx) -> ResponseDeliverTx;
137
138    /// Signals the end of a block. Called after all transactions, prior to each [`commit`](trait.Commit.html#tymethod.commit).
139    ///
140    /// # Equivalent to
141    ///
142    /// ```rust,ignore
143    /// async fn end_block(&self, end_block_request: RequestEndBlock) -> ResponseEndBlock
144    /// ```
145    async fn end_block(&self, end_block_request: RequestEndBlock) -> ResponseEndBlock;
146
147    /// Persist the application state.
148    ///
149    /// # Details
150    ///
151    /// Application state should only be persisted to disk during [`commit`].
152    ///
153    /// Before [`commit`] is called, Tendermint locks and flushes the mempool so that no new messages will be received
154    /// on the mempool connection. This provides an opportunity to safely update all three states ([_Consensus_],
155    /// [_Mempool_] and [_Info_]) to the **latest committed state** at once.
156    ///
157    /// When [`commit`] completes, it unlocks the mempool.
158    ///
159    /// # Warning
160    ///
161    /// If the ABCI application logic processing the [`commit`] message sends a `/broadcast_tx_sync` or
162    /// `/broadcast_tx_commit` and waits for the response before proceeding, it will deadlock. Executing those
163    /// `broadcast_tx` calls involves acquiring a lock that is held during the [`commit`] call, so it's not possible. If
164    /// you make the call to the `broadcast_tx` endpoints concurrently, that's no problem, it just can't be part of the
165    /// sequential logic of the [`commit`] function.
166    ///
167    /// [`commit`]: trait.Commit.html#tymethod.commit
168    /// [_Consensus_]: trait.Consensus.html#details
169    /// [_Mempool_]: trait.Mempool.html#details
170    /// [_Info_]: trait.Info.html
171    ///
172    /// # Equivalent to
173    ///
174    /// ```rust,ignore
175    /// async fn commit(&self, commit_request: RequestCommit) -> ResponseCommit
176    /// ```
177    async fn commit(&self, commit_request: RequestCommit) -> ResponseCommit;
178
179    /// Signals that messages queued on the client should be flushed to the server.
180    ///
181    /// # Equivalent to
182    ///
183    /// ```rust,ignore
184    /// async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush
185    /// ```
186    async fn flush(&self, _flush_request: RequestFlush) -> ResponseFlush {
187        Default::default()
188    }
189}
190
191/// Trait for managing tendermint's mempool.
192///
193/// # Details
194///
195/// [_Mempool_] should maintain a `mempool_state` to sequentially process pending transactions in the mempool that have
196/// not yet been committed. It should be initialized to the latest committed state at the end of every [`commit`].
197///
198/// The `mempool_state` may be updated concurrently with the `consensus_state`, as messages may be sent concurrently on
199/// [_Consensus_] and [_Mempool_] connections. However, before calling [`commit`], Tendermint will lock and flush the
200/// mempool connection, ensuring that all existing [`check_tx`] are responded to and no new ones can begin.
201///
202/// After [`commit`], [`check_tx`] is run again on all transactions that remain in the node's local mempool after
203/// filtering those included in the block. To prevent the mempool from rechecking all transactions every time a block is
204/// committed, set the configuration option `mempool.recheck=false`.
205///
206/// Finally, the mempool will unlock and new transactions can be processed through [`check_tx`] again.
207///
208/// Note that [`check_tx`] doesn't have to check everything that affects transaction validity; the expensive things can
209/// be skipped. In fact, [`check_tx`] doesn't have to check anything; it might say that any transaction is a valid
210/// transaction. Unlike [`deliver_tx`], [`check_tx`] is just there as a sort of weak filter to keep invalid transactions
211/// out of the blockchain. It's weak, because a Byzantine node doesn't care about [`check_tx`]; it can propose a block
212/// full of invalid transactions if it wants.
213///
214/// [_Mempool_]: trait.Mempool.html#details
215/// [`commit`]: trait.Consensus.html#tymethod.commit
216/// [_Consensus_]: trait.Consensus.html#details
217/// [`deliver_tx`]: trait.Consensus.html#tymethod.deliver_tx
218/// [`check_tx`]: trait.Mempool.html#method.check_tx
219#[async_trait]
220pub trait Mempool: Send + Sync {
221    /// Echo a string to test abci client/server implementation.
222    ///
223    /// # Equivalent to
224    ///
225    /// ```rust,ignore
226    /// async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho
227    /// ```
228    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
229        ResponseEcho {
230            message: echo_request.message,
231        }
232    }
233
234    /// Guardian of the mempool: every node runs CheckTx before letting a transaction into its local mempool.
235    /// Technically optional - not involved in processing blocks
236    ///
237    /// # Equivalent to
238    ///
239    /// ```rust,ignore
240    /// async fn check_tx(&self, check_tx_request: RequestCheckTx) -> ResponseCheckTx
241    /// ```
242    async fn check_tx(&self, check_tx_request: RequestCheckTx) -> ResponseCheckTx;
243
244    /// Signals that messages queued on the client should be flushed to the server.
245    ///
246    /// # Equivalent to
247    ///
248    /// ```rust,ignore
249    /// async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush
250    /// ```
251    async fn flush(&self, _flush_request: RequestFlush) -> ResponseFlush {
252        Default::default()
253    }
254}
255
256/// Trait for serving and restoring tendermint's state sync snapshots.
257///
258/// # Details
259///
260/// State sync allows new nodes to rapidly bootstrap by discovering, fetching, and applying state
261/// machine snapshots instead of replaying historical blocks. For more details, see the state sync
262/// section.
263///
264/// When a new node is discovering snapshots in the P2P network, existing nodes will call
265/// [`list_snapshots`] on the application to retrieve any local state snapshots. The new node will
266/// offer these snapshots to its local application via [`offer_snapshot`].
267///
268/// Once the application accepts a snapshot and begins restoring it, Tendermint will fetch snapshot
269/// chunks from existing nodes via [`load_snapshot_chunk`] and apply them sequentially to the local
270/// application with `apply_snapshot_chunk`. When all chunks have been applied, the application
271/// `app_hash` is retrieved via an [`info`] query and compared to the blockchain's `app_hash`
272/// verified via light client.
273///
274/// [`list_snapshots`]: trait.StateSync.html#method.list_snapshots
275/// [`offer_snapshot`]: trait.StateSync.html#method.offer_snapshot
276/// [`load_snapshot_chunk`]: trait.StateSync.html#method.load_snapshot_chunk
277/// [`apply_snapshot_chunk`]: trait.StateSync.html#method.apply_snapshot_chunk
278/// [`info`]: trait.Info.html#tymethod.info
279#[async_trait]
280pub trait Snapshot: Send + Sync {
281    /// Echo a string to test abci client/server implementation.
282    ///
283    /// # Equivalent to
284    ///
285    /// ```rust,ignore
286    /// async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho
287    /// ```
288    async fn echo(&self, echo_request: RequestEcho) -> ResponseEcho {
289        ResponseEcho {
290            message: echo_request.message,
291        }
292    }
293
294    /// # Equivalent to
295    ///
296    /// ```rust,ignore
297    /// async fn list_snapshots(&self, list_snapshots_request: RequestListSnapshots) -> ResponseListSnapshots
298    /// ```
299    async fn list_snapshots(
300        &self,
301        _list_snapshots_request: RequestListSnapshots,
302    ) -> ResponseListSnapshots {
303        Default::default()
304    }
305
306    /// # Equivalent to
307    ///
308    /// ```rust,ignore
309    /// async fn offer_snapshot(&self: offer_snapshot_request: RequestOfferSnapshot) -> ResponseOfferSnapshot
310    /// ```
311    async fn offer_snapshot(
312        &self,
313        _offer_snapshot_request: RequestOfferSnapshot,
314    ) -> ResponseOfferSnapshot {
315        Default::default()
316    }
317
318    /// # Equivalent to
319    ///
320    /// ```rust,ignore
321    /// async fn load_snapshot_chunk(&self, load_snapshot_chunk_request: RequestLoadSnapshotChunk) -> ResponseLoadSnapshotChunk
322    /// ```
323    async fn load_snapshot_chunk(
324        &self,
325        _load_snapshot_chunk_request: RequestLoadSnapshotChunk,
326    ) -> ResponseLoadSnapshotChunk {
327        Default::default()
328    }
329
330    /// # Equivalent to
331    ///
332    /// ```rust,ignore
333    /// async fn apply_snapshot_chunk(&self: apply_snapshot_chunk_request: RequestApplySnapshotChunk) -> ResponseApplySnapshotChunk
334    /// ```
335    async fn apply_snapshot_chunk(
336        &self,
337        _apply_snapshot_chunk_request: RequestApplySnapshotChunk,
338    ) -> ResponseApplySnapshotChunk {
339        Default::default()
340    }
341
342    /// Signals that messages queued on the client should be flushed to the server.
343    ///
344    /// # Equivalent to
345    ///
346    /// ```rust,ignore
347    /// async fn flush(&self, flush_request: RequestFlush) -> ResponseFlush
348    /// ```
349    async fn flush(&self, _flush_request: RequestFlush) -> ResponseFlush {
350        Default::default()
351    }
352}