penumbra_sdk_mock_consensus/
abci.rs1use {
4 super::TestNode,
5 anyhow::{anyhow, Context},
6 bytes::Bytes,
7 tap::{Tap, TapFallible},
8 tendermint::{
9 abci::types::CommitInfo,
10 block::Header,
11 v0_37::abci::{request, response, ConsensusRequest, ConsensusResponse},
12 },
13 tower::{BoxError, Service},
14 tracing::{error, instrument, trace},
15};
16
17impl<C> TestNode<C>
19where
20 C: Service<ConsensusRequest, Response = ConsensusResponse, Error = BoxError>
21 + Send
22 + Clone
23 + 'static,
24 C::Future: Send + 'static,
25 C::Error: Sized,
26{
27 async fn service(&mut self) -> Result<&mut C, anyhow::Error> {
29 use tower::ServiceExt;
30 self.consensus
31 .ready()
32 .tap(|_| trace!("waiting for consensus service"))
33 .await
34 .tap_err(|error| error!(?error, "failed waiting for consensus service"))
35 .map_err(|_| anyhow!("failed waiting for consensus service"))
36 .tap_ok(|_| trace!("consensus service is now ready"))
37 }
38
39 #[instrument(level = "debug", skip_all)]
41 pub async fn begin_block(
42 &mut self,
43 header: Header,
44 last_commit_info: CommitInfo,
45 ) -> Result<response::BeginBlock, anyhow::Error> {
46 let request = ConsensusRequest::BeginBlock(request::BeginBlock {
47 hash: tendermint::Hash::None,
48 header,
49 last_commit_info,
50 byzantine_validators: Default::default(),
51 });
52 let service = self.service().await?;
53 match service
54 .tap(|_| trace!("sending BeginBlock request"))
55 .call(request)
56 .await
57 .tap_err(|error| error!(?error, "consensus service returned error"))
58 .map_err(|_| anyhow!("consensus service returned error"))?
59 {
60 ConsensusResponse::BeginBlock(response) => {
61 let response::BeginBlock { events } = &response;
62 trace!(?events, "received BeginBlock events");
63 Ok(response)
64 }
65 response => {
66 error!(?response, "unexpected InitChain response");
67 Err(anyhow!("unexpected InitChain response"))
68 }
69 }
70 }
71
72 #[instrument(level = "debug", skip_all)]
74 pub async fn deliver_tx(&mut self, tx: Bytes) -> Result<response::DeliverTx, anyhow::Error> {
75 let request = ConsensusRequest::DeliverTx(request::DeliverTx { tx });
76 let service = self.service().await?;
77 match service
78 .tap(|_| trace!("sending DeliverTx request"))
79 .call(request)
80 .await
81 .tap_err(|error| error!(?error, "consensus service returned error"))
82 .map_err(|_| anyhow!("consensus service returned error"))?
83 {
84 ConsensusResponse::DeliverTx(response) => {
85 let response::DeliverTx {
86 code,
87 gas_used,
88 gas_wanted,
89 events,
90 ..
91 } = &response;
92 trace!(
93 ?code,
94 ?gas_used,
95 ?gas_wanted,
96 ?events,
97 "received DeliverTx response"
98 );
99 Ok(response)
100 }
101 response => {
102 error!(?response, "unexpected DeliverTx response");
103 Err(anyhow!("unexpected DeliverTx response"))
104 }
105 }
106 }
107
108 #[instrument(level = "debug", skip_all)]
110 pub async fn end_block(&mut self) -> Result<response::EndBlock, anyhow::Error> {
111 let height = self
112 .height
113 .value()
114 .try_into()
115 .context("converting height into `i64`")?;
116 let request = ConsensusRequest::EndBlock(request::EndBlock { height });
117
118 let service = self.service().await?;
119 match service
120 .call(request)
121 .await
122 .tap_err(|error| error!(?error, "consensus service returned error"))
123 .map_err(|_| anyhow!("consensus service returned error"))?
124 {
125 ConsensusResponse::EndBlock(response) => {
126 let response::EndBlock {
127 validator_updates,
128 consensus_param_updates,
129 events,
130 } = &response;
131 trace!(
132 ?validator_updates,
133 ?consensus_param_updates,
134 ?events,
135 "received EndBlock response"
136 );
137 Ok(response)
138 }
139 response => {
140 error!(?response, "unexpected EndBlock response");
141 Err(anyhow!("unexpected EndBlock response"))
142 }
143 }
144 }
145
146 #[instrument(level = "debug", skip_all)]
148 pub async fn commit(&mut self) -> Result<response::Commit, anyhow::Error> {
149 let request = ConsensusRequest::Commit;
150 let service = self.service().await?;
151 match service
152 .call(request)
153 .await
154 .tap_err(|error| error!(?error, "consensus service returned error"))
155 .map_err(|_| anyhow!("consensus service returned error"))?
156 {
157 ConsensusResponse::Commit(response) => {
158 let response::Commit {
159 data,
160 retain_height,
161 } = &response;
162 trace!(?data, ?retain_height, "received Commit response");
163
164 Ok(response)
165 }
166 response => {
167 error!(?response, "unexpected Commit response");
168 Err(anyhow!("unexpected Commit response"))
169 }
170 }
171 }
172}