oasis_core_runtime/transaction/
dispatcher.rs1use std::sync::{atomic::AtomicBool, Arc};
3
4use super::{context::Context, tags::Tags, types::TxnBatch};
5use crate::{
6 common::crypto::hash::Hash,
7 consensus::roothash,
8 types::{CheckTxResult, Error as RuntimeError},
9};
10
11pub trait Dispatcher: Send + Sync {
16 fn is_supported(&self) -> bool {
18 true
19 }
20
21 fn execute_batch(
27 &self,
28 ctx: Context,
29 batch: &TxnBatch,
30 in_msgs: &[roothash::IncomingMessage],
31 ) -> Result<ExecuteBatchResult, RuntimeError>;
32
33 fn schedule_and_execute_batch(
42 &self,
43 _ctx: Context,
44 _initial_batch: &mut TxnBatch,
45 _in_msgs: &[roothash::IncomingMessage],
46 ) -> Result<ExecuteBatchResult, RuntimeError> {
47 Err(RuntimeError::new(
48 "rhp/dispatcher",
49 3,
50 "scheduling not supported",
51 ))
52 }
53
54 fn check_batch(
62 &self,
63 ctx: Context,
64 batch: &TxnBatch,
65 ) -> Result<Vec<CheckTxResult>, RuntimeError>;
66
67 fn finalize(&self, _new_storage_root: Hash) {
69 }
71
72 fn set_abort_batch_flag(&mut self, _abort_batch: Arc<AtomicBool>) {
74 }
76
77 fn query(&self, _ctx: Context, _method: &str, _args: Vec<u8>) -> Result<Vec<u8>, RuntimeError> {
85 Err(RuntimeError::new(
87 "rhp/dispatcher",
88 2,
89 "query not supported",
90 ))
91 }
92}
93
94impl<T: Dispatcher + ?Sized> Dispatcher for Box<T> {
95 fn is_supported(&self) -> bool {
96 T::is_supported(&**self)
97 }
98
99 fn execute_batch(
100 &self,
101 ctx: Context,
102 batch: &TxnBatch,
103 in_msgs: &[roothash::IncomingMessage],
104 ) -> Result<ExecuteBatchResult, RuntimeError> {
105 T::execute_batch(&**self, ctx, batch, in_msgs)
106 }
107
108 fn schedule_and_execute_batch(
109 &self,
110 ctx: Context,
111 initial_batch: &mut TxnBatch,
112 in_msgs: &[roothash::IncomingMessage],
113 ) -> Result<ExecuteBatchResult, RuntimeError> {
114 T::schedule_and_execute_batch(&**self, ctx, initial_batch, in_msgs)
115 }
116
117 fn check_batch(
118 &self,
119 ctx: Context,
120 batch: &TxnBatch,
121 ) -> Result<Vec<CheckTxResult>, RuntimeError> {
122 T::check_batch(&**self, ctx, batch)
123 }
124
125 fn finalize(&self, new_storage_root: Hash) {
126 T::finalize(&**self, new_storage_root)
127 }
128
129 fn set_abort_batch_flag(&mut self, abort_batch: Arc<AtomicBool>) {
130 T::set_abort_batch_flag(&mut **self, abort_batch)
131 }
132
133 fn query(&self, ctx: Context, method: &str, args: Vec<u8>) -> Result<Vec<u8>, RuntimeError> {
134 T::query(&**self, ctx, method, args)
135 }
136}
137
138impl<T: Dispatcher + ?Sized> Dispatcher for Arc<T> {
139 fn is_supported(&self) -> bool {
140 T::is_supported(&**self)
141 }
142
143 fn execute_batch(
144 &self,
145 ctx: Context,
146 batch: &TxnBatch,
147 in_msgs: &[roothash::IncomingMessage],
148 ) -> Result<ExecuteBatchResult, RuntimeError> {
149 T::execute_batch(&**self, ctx, batch, in_msgs)
150 }
151
152 fn schedule_and_execute_batch(
153 &self,
154 ctx: Context,
155 initial_batch: &mut TxnBatch,
156 in_msgs: &[roothash::IncomingMessage],
157 ) -> Result<ExecuteBatchResult, RuntimeError> {
158 T::schedule_and_execute_batch(&**self, ctx, initial_batch, in_msgs)
159 }
160
161 fn check_batch(
162 &self,
163 ctx: Context,
164 batch: &TxnBatch,
165 ) -> Result<Vec<CheckTxResult>, RuntimeError> {
166 T::check_batch(&**self, ctx, batch)
167 }
168
169 fn finalize(&self, new_storage_root: Hash) {
170 T::finalize(&**self, new_storage_root)
171 }
172
173 fn set_abort_batch_flag(&mut self, _abort_batch: Arc<AtomicBool>) {
174 unimplemented!()
175 }
176
177 fn query(&self, ctx: Context, method: &str, args: Vec<u8>) -> Result<Vec<u8>, RuntimeError> {
178 T::query(&**self, ctx, method, args)
179 }
180}
181
182pub struct ExecuteTxResult {
184 pub output: Vec<u8>,
186 pub tags: Tags,
188}
189
190pub struct ExecuteBatchResult {
192 pub results: Vec<ExecuteTxResult>,
194 pub messages: Vec<roothash::Message>,
196 pub in_msgs_count: usize,
198 pub block_tags: Tags,
200 pub tx_reject_hashes: Vec<Hash>,
204}
205
206#[derive(Default)]
211pub struct NoopDispatcher;
212
213impl Dispatcher for NoopDispatcher {
214 fn is_supported(&self) -> bool {
215 false
216 }
217
218 fn execute_batch(
219 &self,
220 _ctx: Context,
221 _batch: &TxnBatch,
222 in_msgs: &[roothash::IncomingMessage],
223 ) -> Result<ExecuteBatchResult, RuntimeError> {
224 Ok(ExecuteBatchResult {
225 results: Vec::new(),
226 messages: Vec::new(),
227 block_tags: Tags::new(),
228 in_msgs_count: in_msgs.len(),
229 tx_reject_hashes: Vec::new(),
230 })
231 }
232
233 fn schedule_and_execute_batch(
234 &self,
235 _ctx: Context,
236 _initial_batch: &mut TxnBatch,
237 in_msgs: &[roothash::IncomingMessage],
238 ) -> Result<ExecuteBatchResult, RuntimeError> {
239 Ok(ExecuteBatchResult {
240 results: Vec::new(),
241 messages: Vec::new(),
242 block_tags: Tags::new(),
243 in_msgs_count: in_msgs.len(),
244 tx_reject_hashes: Vec::new(),
245 })
246 }
247
248 fn check_batch(
249 &self,
250 _ctx: Context,
251 _batch: &TxnBatch,
252 ) -> Result<Vec<CheckTxResult>, RuntimeError> {
253 Ok(Vec::new())
254 }
255}