gear_common/auxiliary/
gas_provider.rs1use crate::{
22 gas_provider::{Error, GasNode, GasNodeId, Provider, TreeImpl},
23 storage::{MapStorage, ValueStorage},
24 Origin,
25};
26use alloc::collections::BTreeMap;
27use core::{cell::RefCell, ops::DerefMut};
28use sp_core::H256;
29
30pub(crate) type Balance = u64;
32pub(crate) type Funds = u128;
34pub(crate) type NodeId = GasNodeId<PlainNodeId, ReservationNodeId>;
36pub(crate) type Node = GasNode<ExternalOrigin, NodeId, Balance, Funds>;
38
39pub struct AuxiliaryGasProvider;
41
42impl Provider for AuxiliaryGasProvider {
43 type ExternalOrigin = ExternalOrigin;
44 type NodeId = NodeId;
45 type Balance = Balance;
46 type Funds = Funds;
47 type InternalError = GasTreeError;
48 type Error = GasTreeError;
49
50 type GasTree = TreeImpl<
51 TotalIssuanceWrap,
52 Self::InternalError,
53 Self::Error,
54 ExternalOrigin,
55 Self::NodeId,
56 GasNodesWrap,
57 >;
58}
59
60#[derive(Debug, Copy, Hash, Clone, Eq, PartialEq, Ord, PartialOrd)]
61pub struct ExternalOrigin(pub H256);
62
63impl Origin for ExternalOrigin {
64 fn into_origin(self) -> H256 {
65 self.0
66 }
67
68 fn from_origin(val: H256) -> Self {
69 Self(val)
70 }
71}
72
73#[derive(Debug, Copy, Hash, Clone, Eq, PartialEq, Ord, PartialOrd)]
74pub struct PlainNodeId(pub H256);
75
76impl Origin for PlainNodeId {
77 fn into_origin(self) -> H256 {
78 self.0
79 }
80
81 fn from_origin(val: H256) -> Self {
82 Self(val)
83 }
84}
85
86impl<U> From<PlainNodeId> for GasNodeId<PlainNodeId, U> {
87 fn from(plain_node_id: PlainNodeId) -> Self {
88 Self::Node(plain_node_id)
89 }
90}
91
92#[derive(Debug, Copy, Hash, Clone, Eq, PartialEq, Ord, PartialOrd)]
93pub struct ReservationNodeId(pub H256);
94
95impl Origin for ReservationNodeId {
96 fn into_origin(self) -> H256 {
97 self.0
98 }
99
100 fn from_origin(val: H256) -> Self {
101 Self(val)
102 }
103}
104
105impl<T> From<ReservationNodeId> for GasNodeId<T, ReservationNodeId> {
106 fn from(node_id: ReservationNodeId) -> Self {
107 Self::Reservation(node_id)
108 }
109}
110
111#[derive(Clone, Copy, Debug, Eq, PartialEq)]
113pub enum GasTreeError {
114 NodeAlreadyExists,
115 ParentIsLost,
116 ParentHasNoChildren,
117 NodeNotFound,
118 NodeWasConsumed,
119 InsufficientBalance,
120 Forbidden,
121 UnexpectedConsumeOutput,
122 UnexpectedNodeType,
123 ValueIsNotCaught,
124 ValueIsBlocked,
125 ValueIsNotBlocked,
126 ConsumedWithLock,
127 ConsumedWithSystemReservation,
128 TotalValueIsOverflowed,
129 TotalValueIsUnderflowed,
130}
131
132impl Error for GasTreeError {
133 fn node_already_exists() -> Self {
134 Self::NodeAlreadyExists
135 }
136
137 fn parent_is_lost() -> Self {
138 Self::ParentIsLost
139 }
140
141 fn parent_has_no_children() -> Self {
142 Self::ParentHasNoChildren
143 }
144
145 fn node_not_found() -> Self {
146 Self::NodeNotFound
147 }
148
149 fn node_was_consumed() -> Self {
150 Self::NodeWasConsumed
151 }
152
153 fn insufficient_balance() -> Self {
154 Self::InsufficientBalance
155 }
156
157 fn forbidden() -> Self {
158 Self::Forbidden
159 }
160
161 fn unexpected_consume_output() -> Self {
162 Self::UnexpectedConsumeOutput
163 }
164
165 fn unexpected_node_type() -> Self {
166 Self::UnexpectedNodeType
167 }
168
169 fn value_is_not_caught() -> Self {
170 Self::ValueIsNotCaught
171 }
172
173 fn value_is_blocked() -> Self {
174 Self::ValueIsBlocked
175 }
176
177 fn value_is_not_blocked() -> Self {
178 Self::ValueIsNotBlocked
179 }
180
181 fn consumed_with_lock() -> Self {
182 Self::ConsumedWithLock
183 }
184
185 fn consumed_with_system_reservation() -> Self {
186 Self::ConsumedWithSystemReservation
187 }
188
189 fn total_value_is_overflowed() -> Self {
190 Self::TotalValueIsOverflowed
191 }
192
193 fn total_value_is_underflowed() -> Self {
194 Self::TotalValueIsUnderflowed
195 }
196}
197
198std::thread_local! {
199 pub(crate) static TOTAL_ISSUANCE: RefCell<Option<Balance>> = const { RefCell::new(None) };
201}
202
203#[derive(Debug, PartialEq, Eq)]
205pub struct TotalIssuanceWrap;
206
207impl ValueStorage for TotalIssuanceWrap {
208 type Value = Balance;
209
210 fn exists() -> bool {
211 TOTAL_ISSUANCE.with(|i| i.borrow().is_some())
212 }
213
214 fn get() -> Option<Self::Value> {
215 TOTAL_ISSUANCE.with(|i| *i.borrow())
216 }
217
218 fn kill() {
219 TOTAL_ISSUANCE.with(|i| {
220 *i.borrow_mut() = None;
221 })
222 }
223
224 fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(f: F) -> R {
225 TOTAL_ISSUANCE.with(|i| f(i.borrow_mut().deref_mut()))
226 }
227
228 fn put(value: Self::Value) {
229 TOTAL_ISSUANCE.with(|i| {
230 i.replace(Some(value));
231 })
232 }
233
234 fn set(value: Self::Value) -> Option<Self::Value> {
235 Self::mutate(|opt| {
236 let prev = opt.take();
237 *opt = Some(value);
238 prev
239 })
240 }
241
242 fn take() -> Option<Self::Value> {
243 TOTAL_ISSUANCE.with(|i| i.take())
244 }
245}
246
247std::thread_local! {
248 pub(crate) static GAS_NODES: RefCell<BTreeMap<NodeId, Node>> = const { RefCell::new(BTreeMap::new()) };
250}
251
252pub struct GasNodesWrap;
254
255impl MapStorage for GasNodesWrap {
256 type Key = NodeId;
257 type Value = Node;
258
259 fn contains_key(key: &Self::Key) -> bool {
260 GAS_NODES.with(|tree| tree.borrow().contains_key(key))
261 }
262
263 fn get(key: &Self::Key) -> Option<Self::Value> {
264 GAS_NODES.with(|tree| tree.borrow().get(key).cloned())
265 }
266
267 fn insert(key: Self::Key, value: Self::Value) {
268 GAS_NODES.with(|tree| tree.borrow_mut().insert(key, value));
269 }
270
271 fn mutate<R, F: FnOnce(&mut Option<Self::Value>) -> R>(_key: Self::Key, _f: F) -> R {
272 unimplemented!()
273 }
274
275 fn mutate_values<F: FnMut(Self::Value) -> Self::Value>(mut _f: F) {
276 unimplemented!()
277 }
278
279 fn remove(key: Self::Key) {
280 GAS_NODES.with(|tree| tree.borrow_mut().remove(&key));
281 }
282
283 fn clear() {
284 GAS_NODES.with(|tree| tree.borrow_mut().clear());
285 }
286
287 fn take(key: Self::Key) -> Option<Self::Value> {
288 GAS_NODES.with(|tree| tree.borrow_mut().remove(&key))
289 }
290}