1mod defaults;
2pub mod grpc;
3pub mod utils;
4
5use protos::crypto;
6
7pub use defaults::*;
8pub use grpc::*;
9
10use lazy_static::lazy_static;
11use owning_ref::MutexGuardRefMut;
12use std::sync::Mutex;
13
14use mockall::automock;
15
16lazy_static! {
17 static ref ABCI_INTERFACE_INSTANCE: Mutex<Option<AIType>> = Mutex::new(None);
18}
19
20type AIType = Box<dyn AbciInterface + Send>;
21type AbciResult<T> = Result<Box<T>, Box<dyn std::error::Error>>;
22
23#[automock]
25pub trait ResponseFlush {}
26
27#[automock]
29pub trait ResponseEcho {
30 fn get_message(&self) -> String;
31
32 fn set_message(&mut self, v: String);
33}
34
35#[automock]
37pub trait ResponseCheckTx {
38 fn get_code(&self) -> u32;
39 fn get_data(&self) -> Vec<u8>;
40 fn get_log(&self) -> String;
41 fn get_info(&self) -> String;
42 fn get_gas_wanted(&self) -> i64;
43 fn get_gas_used(&self) -> i64;
44 fn get_codespace(&self) -> String;
45
46 fn set_code(&mut self, v: u32);
47 fn set_data(&mut self, v: Vec<u8>);
48 fn set_log(&mut self, v: String);
49 fn set_info(&mut self, v: String);
50 fn set_gas_wanted(&mut self, v: i64);
51 fn set_gas_used(&mut self, v: i64);
52 fn set_codespace(&mut self, v: String);
53}
54
55#[automock]
57pub trait ResponseDeliverTx {
58 fn get_code(&self) -> u32;
59 fn get_data(&self) -> Vec<u8>;
60 fn get_log(&self) -> String;
61 fn get_info(&self) -> String;
62 fn get_gas_wanted(&self) -> i64;
63 fn get_gas_used(&self) -> i64;
64 fn get_codespace(&self) -> String;
65
66 fn set_code(&mut self, v: u32);
67 fn set_data(&mut self, v: Vec<u8>);
68 fn set_log(&mut self, v: String);
69 fn set_info(&mut self, v: String);
70 fn set_gas_wanted(&mut self, v: i64);
71 fn set_gas_used(&mut self, v: i64);
72 fn set_codespace(&mut self, v: String);
73}
74
75#[automock]
77pub trait ResponseInitChain {}
78
79#[automock]
81pub trait ResponseSetOption {
82 fn get_code(&self) -> u32;
83 fn get_log(&self) -> String;
84 fn get_info(&self) -> String;
85}
86
87#[automock]
89pub trait ResponseBeginBlock {}
90
91#[automock]
93pub trait ResponseEndBlock {}
94
95#[automock]
97pub trait ResponseCommit {
98 fn get_data(&self) -> Vec<u8>;
99 fn get_retain_height(&self) -> i64;
100
101 fn set_data(&mut self, v: Vec<u8>);
102 fn set_retain_height(&mut self, v: i64);
103}
104
105#[automock]
107pub trait ResponseInfo {
108 fn get_version(&self) -> String;
109 fn get_app_version(&self) -> u64;
110 fn get_data(&self) -> String;
111 fn get_last_block_height(&self) -> i64;
112 fn get_last_block_app_hash(&self) -> Vec<u8>;
113}
114
115#[automock]
117pub trait ResponseQuery {
118 fn get_code(&self) -> u32;
119 fn get_log(&self) -> String;
120 fn get_info(&self) -> String;
121 fn get_index(&self) -> i64;
122 fn get_key(&self) -> Vec<u8>;
123 fn get_value(&self) -> Vec<u8>;
124 fn get_height(&self) -> i64;
125 fn get_codespace(&self) -> String;
126 fn get_proof(&self) -> Option<crypto::merkle::Proof>;
127
128 fn set_code(&mut self, v: u32);
129 fn set_log(&mut self, v: String);
130 fn set_info(&mut self, v: String);
131 fn set_index(&mut self, v: i64);
132 fn set_key(&mut self, v: Vec<u8>);
133 fn set_value(&mut self, v: Vec<u8>);
134 fn set_height(&mut self, v: i64);
135 fn set_codespace(&mut self, v: String);
136}
137
138#[automock]
140pub trait AbciInterface {
141 fn echo(&mut self, message: String) -> AbciResult<dyn ResponseEcho>;
142
143 fn check_tx(&mut self, tx: Vec<u8>) -> AbciResult<dyn ResponseCheckTx>;
144
145 fn deliver_tx(&mut self, tx: Vec<u8>) -> AbciResult<dyn ResponseDeliverTx>;
146
147 fn init_chain(
148 &mut self,
149 time_seconds: i64,
150 time_nanos: i32,
151 chain_id: &str,
152 pub_key_types: Vec<String>,
153 max_bytes: i64,
154 max_gas: i64,
155 max_age_num_blocks: i64,
156 max_age_duration: u64,
157 app_state_bytes: Vec<u8>,
158 ) -> AbciResult<dyn ResponseInitChain>;
159
160 fn set_option(&mut self, key: &str, value: &str) -> AbciResult<dyn ResponseSetOption>;
161
162 fn begin_block(
163 &mut self,
164 height: i64,
165 hash: Vec<u8>,
166 last_block_id: Vec<u8>,
167 proposer_address: Vec<u8>,
168 ) -> AbciResult<dyn ResponseBeginBlock>;
169
170 fn end_block(&mut self, height: i64) -> AbciResult<dyn ResponseEndBlock>;
171
172 fn commit(&mut self) -> AbciResult<dyn ResponseCommit>;
173
174 fn query(
175 &mut self,
176 path: String,
177 data: Vec<u8>,
178 height: i64,
179 prove: bool,
180 ) -> AbciResult<dyn ResponseQuery>;
181
182 fn info(&mut self) -> AbciResult<dyn ResponseInfo>;
183
184 fn flush(&mut self) -> AbciResult<dyn ResponseFlush>;
185}
186
187pub fn set_abci_instance<'ret>(
189 new_instance: AIType,
190) -> Result<MutexGuardRefMut<'ret, Option<AIType>, AIType>, Box<dyn std::error::Error>> {
191 let mut instance = ABCI_INTERFACE_INSTANCE.lock()?;
192 *instance = Some(new_instance);
193 let res = MutexGuardRefMut::new(instance).map_mut(|mg| mg.as_mut().unwrap());
196 Ok(res)
197}
198
199pub fn get_abci_instance<'ret>(
201) -> Result<MutexGuardRefMut<'ret, Option<AIType>, AIType>, Box<dyn std::error::Error>> {
202 let instance = ABCI_INTERFACE_INSTANCE.lock()?;
203 if instance.is_none() {
204 panic!("abci instance has not been set, execute set_abci_instance before calling this function");
205 }
206 let res = MutexGuardRefMut::new(instance).map_mut(|mg| mg.as_mut().unwrap());
209 Ok(res)
210}