hotmint_consensus/application.rs
1use ruc::*;
2
3use hotmint_types::Block;
4use hotmint_types::context::{BlockContext, TxContext};
5use hotmint_types::evidence::EquivocationProof;
6use hotmint_types::validator_update::EndBlockResponse;
7
8/// Application interface for the consensus engine.
9///
10/// The lifecycle for each committed block:
11/// 1. `execute_block` — receives all decoded transactions at once; returns
12/// validator updates and events
13/// 2. `on_commit` — notification after the block is finalized
14///
15/// For block proposal:
16/// - `create_payload` — build the payload bytes for a new block
17///
18/// For validation (before voting):
19/// - `validate_block` — full block validation
20/// - `validate_tx` — individual transaction validation for mempool
21///
22/// For evidence:
23/// - `on_evidence` — called when equivocation is detected
24///
25/// All methods have default no-op implementations.
26pub trait Application: Send + Sync {
27 /// Create a payload for a new block proposal.
28 /// Typically pulls transactions from the mempool.
29 ///
30 /// If your mempool is async, use `tokio::runtime::Handle::current().block_on(..)`
31 /// to bridge into this synchronous callback.
32 fn create_payload(&self, _ctx: &BlockContext) -> Vec<u8> {
33 vec![]
34 }
35
36 /// Validate a proposed block before voting.
37 fn validate_block(&self, _block: &Block, _ctx: &BlockContext) -> bool {
38 true
39 }
40
41 /// Validate a single transaction for mempool admission.
42 ///
43 /// An optional [`TxContext`] provides the current chain height and epoch,
44 /// which can be useful for state-dependent validation (nonce checks, etc.).
45 fn validate_tx(&self, _tx: &[u8], _ctx: Option<&TxContext>) -> bool {
46 true
47 }
48
49 /// Execute an entire block in one call.
50 ///
51 /// Receives all decoded transactions from the block payload at once,
52 /// allowing batch-optimised processing (bulk DB writes, parallel
53 /// signature verification, etc.).
54 ///
55 /// Return [`EndBlockResponse`] with `validator_updates` to schedule an
56 /// epoch transition, and/or `events` to emit application-defined events.
57 fn execute_block(&self, _txs: &[&[u8]], _ctx: &BlockContext) -> Result<EndBlockResponse> {
58 Ok(EndBlockResponse::default())
59 }
60
61 /// Called when a block is committed to the chain (notification).
62 fn on_commit(&self, _block: &Block, _ctx: &BlockContext) -> Result<()> {
63 Ok(())
64 }
65
66 /// Called when equivocation (double-voting) is detected.
67 /// The application can use this to implement slashing.
68 fn on_evidence(&self, _proof: &EquivocationProof) -> Result<()> {
69 Ok(())
70 }
71
72 /// Query application state (returns opaque bytes).
73 fn query(&self, _path: &str, _data: &[u8]) -> Result<Vec<u8>> {
74 Ok(vec![])
75 }
76}
77
78/// No-op application stub for testing.
79pub struct NoopApplication;
80
81impl Application for NoopApplication {}