fc_storage/overrides/
schema.rs

1// This file is part of Frontier.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use std::sync::Arc;
20
21use ethereum_types::{Address, H256, U256};
22// Substrate
23use sc_client_api::backend::{Backend, StorageProvider};
24use sp_runtime::{traits::Block as BlockT, Permill};
25// Frontier
26use fp_rpc::TransactionStatus;
27
28use crate::overrides::{StorageOverride, StorageQuerier};
29
30pub mod v1 {
31	use super::*;
32
33	/// A storage override for runtimes that use schema v1.
34	#[derive(Clone)]
35	pub struct SchemaStorageOverride<B, C, BE> {
36		querier: StorageQuerier<B, C, BE>,
37	}
38
39	impl<B, C, BE> SchemaStorageOverride<B, C, BE> {
40		pub fn new(client: Arc<C>) -> Self {
41			let querier = StorageQuerier::new(client);
42			Self { querier }
43		}
44	}
45
46	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverride<B, C, BE>
47	where
48		B: BlockT,
49		C: StorageProvider<B, BE> + Send + Sync,
50		BE: Backend<B>,
51	{
52		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
53			SchemaStorageOverrideRef::new(&self.querier).account_code_at(at, address)
54		}
55
56		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
57			SchemaStorageOverrideRef::new(&self.querier).account_storage_at(at, address, index)
58		}
59
60		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
61			SchemaStorageOverrideRef::new(&self.querier).current_block(at)
62		}
63
64		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
65			SchemaStorageOverrideRef::new(&self.querier).current_receipts(at)
66		}
67
68		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
69			SchemaStorageOverrideRef::new(&self.querier).current_transaction_statuses(at)
70		}
71
72		fn elasticity(&self, at: B::Hash) -> Option<Permill> {
73			SchemaStorageOverrideRef::new(&self.querier).elasticity(at)
74		}
75
76		fn is_eip1559(&self, at: B::Hash) -> bool {
77			SchemaStorageOverrideRef::new(&self.querier).is_eip1559(at)
78		}
79	}
80
81	/// A storage override reference for runtimes that use schema v1.
82	pub struct SchemaStorageOverrideRef<'a, B, C, BE> {
83		querier: &'a StorageQuerier<B, C, BE>,
84	}
85
86	impl<'a, B, C, BE> SchemaStorageOverrideRef<'a, B, C, BE> {
87		pub fn new(querier: &'a StorageQuerier<B, C, BE>) -> Self {
88			Self { querier }
89		}
90	}
91
92	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverrideRef<'_, B, C, BE>
93	where
94		B: BlockT,
95		C: StorageProvider<B, BE> + Send + Sync,
96		BE: Backend<B>,
97	{
98		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
99			self.querier.account_code(at, address)
100		}
101
102		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
103			self.querier.account_storage(at, address, index)
104		}
105
106		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
107			self.querier
108				.current_block::<ethereum::BlockV0>(at)
109				.map(Into::into)
110		}
111
112		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
113			self.querier
114				.current_receipts::<ethereum::ReceiptV0>(at)
115				.map(|receipts| {
116					receipts
117						.into_iter()
118						.map(|r| {
119							ethereum::ReceiptV4::Legacy(ethereum::EIP658ReceiptData {
120								status_code: r.state_root.to_low_u64_be() as u8,
121								used_gas: r.used_gas,
122								logs_bloom: r.logs_bloom,
123								logs: r.logs,
124							})
125						})
126						.collect()
127				})
128		}
129
130		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
131			self.querier.current_transaction_statuses(at)
132		}
133
134		fn elasticity(&self, _at: B::Hash) -> Option<Permill> {
135			None
136		}
137
138		fn is_eip1559(&self, _at: B::Hash) -> bool {
139			false
140		}
141	}
142}
143
144pub mod v2 {
145	use super::*;
146
147	/// A storage override for runtimes that use schema v2.
148	#[derive(Clone)]
149	pub struct SchemaStorageOverride<B, C, BE> {
150		querier: StorageQuerier<B, C, BE>,
151	}
152
153	impl<B, C, BE> SchemaStorageOverride<B, C, BE> {
154		pub fn new(client: Arc<C>) -> Self {
155			let querier = StorageQuerier::new(client);
156			Self { querier }
157		}
158	}
159
160	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverride<B, C, BE>
161	where
162		B: BlockT,
163		C: StorageProvider<B, BE> + Send + Sync,
164		BE: Backend<B>,
165	{
166		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
167			SchemaStorageOverrideRef::new(&self.querier).account_code_at(at, address)
168		}
169
170		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
171			SchemaStorageOverrideRef::new(&self.querier).account_storage_at(at, address, index)
172		}
173
174		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
175			SchemaStorageOverrideRef::new(&self.querier).current_block(at)
176		}
177
178		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
179			SchemaStorageOverrideRef::new(&self.querier).current_receipts(at)
180		}
181
182		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
183			SchemaStorageOverrideRef::new(&self.querier).current_transaction_statuses(at)
184		}
185
186		fn elasticity(&self, at: B::Hash) -> Option<Permill> {
187			SchemaStorageOverrideRef::new(&self.querier).elasticity(at)
188		}
189
190		fn is_eip1559(&self, at: B::Hash) -> bool {
191			SchemaStorageOverrideRef::new(&self.querier).is_eip1559(at)
192		}
193	}
194
195	/// A storage override reference for runtimes that use schema v2.
196	pub struct SchemaStorageOverrideRef<'a, B, C, BE> {
197		querier: &'a StorageQuerier<B, C, BE>,
198	}
199
200	impl<'a, B, C, BE> SchemaStorageOverrideRef<'a, B, C, BE> {
201		pub fn new(querier: &'a StorageQuerier<B, C, BE>) -> Self {
202			Self { querier }
203		}
204	}
205
206	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverrideRef<'_, B, C, BE>
207	where
208		B: BlockT,
209		C: StorageProvider<B, BE> + Send + Sync,
210		BE: Backend<B>,
211	{
212		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
213			self.querier.account_code(at, address)
214		}
215
216		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
217			self.querier.account_storage(at, address, index)
218		}
219
220		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
221			self.querier.current_block(at)
222		}
223
224		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
225			self.querier
226				.current_receipts::<ethereum::ReceiptV0>(at)
227				.map(|receipts| {
228					receipts
229						.into_iter()
230						.map(|r| {
231							ethereum::ReceiptV4::Legacy(ethereum::EIP658ReceiptData {
232								status_code: r.state_root.to_low_u64_be() as u8,
233								used_gas: r.used_gas,
234								logs_bloom: r.logs_bloom,
235								logs: r.logs,
236							})
237						})
238						.collect()
239				})
240		}
241
242		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
243			self.querier.current_transaction_statuses(at)
244		}
245
246		fn elasticity(&self, at: B::Hash) -> Option<Permill> {
247			self.querier.elasticity(at)
248		}
249
250		fn is_eip1559(&self, _at: B::Hash) -> bool {
251			true
252		}
253	}
254}
255
256pub mod v3 {
257	use super::*;
258
259	/// A storage override for runtimes that use schema v3.
260	#[derive(Clone)]
261	pub struct SchemaStorageOverride<B, C, BE> {
262		querier: StorageQuerier<B, C, BE>,
263	}
264
265	impl<B, C, BE> SchemaStorageOverride<B, C, BE> {
266		pub fn new(client: Arc<C>) -> Self {
267			let querier = StorageQuerier::new(client);
268			Self { querier }
269		}
270	}
271
272	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverride<B, C, BE>
273	where
274		B: BlockT,
275		C: StorageProvider<B, BE> + Send + Sync,
276		BE: Backend<B>,
277	{
278		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
279			SchemaStorageOverrideRef::new(&self.querier).account_code_at(at, address)
280		}
281
282		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
283			SchemaStorageOverrideRef::new(&self.querier).account_storage_at(at, address, index)
284		}
285
286		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
287			SchemaStorageOverrideRef::new(&self.querier).current_block(at)
288		}
289
290		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
291			SchemaStorageOverrideRef::new(&self.querier).current_receipts(at)
292		}
293
294		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
295			SchemaStorageOverrideRef::new(&self.querier).current_transaction_statuses(at)
296		}
297
298		fn elasticity(&self, at: B::Hash) -> Option<Permill> {
299			SchemaStorageOverrideRef::new(&self.querier).elasticity(at)
300		}
301
302		fn is_eip1559(&self, at: B::Hash) -> bool {
303			SchemaStorageOverrideRef::new(&self.querier).is_eip1559(at)
304		}
305	}
306
307	/// A storage override for runtimes that use schema v3.
308	pub struct SchemaStorageOverrideRef<'a, B, C, BE> {
309		querier: &'a StorageQuerier<B, C, BE>,
310	}
311
312	impl<'a, B, C, BE> SchemaStorageOverrideRef<'a, B, C, BE> {
313		pub fn new(querier: &'a StorageQuerier<B, C, BE>) -> Self {
314			Self { querier }
315		}
316	}
317
318	impl<B, C, BE> StorageOverride<B> for SchemaStorageOverrideRef<'_, B, C, BE>
319	where
320		B: BlockT,
321		C: StorageProvider<B, BE> + Send + Sync,
322		BE: Backend<B>,
323	{
324		fn account_code_at(&self, at: B::Hash, address: Address) -> Option<Vec<u8>> {
325			self.querier.account_code(at, address)
326		}
327
328		fn account_storage_at(&self, at: B::Hash, address: Address, index: U256) -> Option<H256> {
329			self.querier.account_storage(at, address, index)
330		}
331
332		fn current_block(&self, at: B::Hash) -> Option<ethereum::BlockV3> {
333			self.querier.current_block(at)
334		}
335
336		fn current_receipts(&self, at: B::Hash) -> Option<Vec<ethereum::ReceiptV4>> {
337			self.querier.current_receipts::<ethereum::ReceiptV4>(at)
338		}
339
340		fn current_transaction_statuses(&self, at: B::Hash) -> Option<Vec<TransactionStatus>> {
341			self.querier.current_transaction_statuses(at)
342		}
343
344		fn elasticity(&self, at: B::Hash) -> Option<Permill> {
345			self.querier.elasticity(at)
346		}
347
348		fn is_eip1559(&self, _at: B::Hash) -> bool {
349			true
350		}
351	}
352}