fp_rpc/
lib.rs

1// This file is part of Frontier.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18#![cfg_attr(not(feature = "std"), no_std)]
19#![allow(clippy::too_many_arguments)]
20#![warn(unused_crate_dependencies)]
21
22extern crate alloc;
23
24use alloc::vec::Vec;
25use ethereum::{AuthorizationList, Log};
26use ethereum_types::{Address, Bloom};
27use scale_codec::{Decode, DecodeWithMemTracking, Encode};
28use scale_info::TypeInfo;
29// Substrate
30use sp_core::{H256, U256};
31use sp_runtime::{
32	traits::{Block as BlockT, HashingFor},
33	Permill, RuntimeDebug,
34};
35use sp_state_machine::OverlayedChanges;
36
37#[derive(
38	Clone,
39	Eq,
40	PartialEq,
41	Default,
42	RuntimeDebug,
43	Encode,
44	Decode,
45	DecodeWithMemTracking,
46	TypeInfo
47)]
48pub struct TransactionStatus {
49	pub transaction_hash: H256,
50	pub transaction_index: u32,
51	pub from: Address,
52	pub to: Option<Address>,
53	pub contract_address: Option<Address>,
54	pub logs: Vec<Log>,
55	pub logs_bloom: Bloom,
56}
57
58pub trait RuntimeStorageOverride<B: BlockT, C>: Send + Sync {
59	fn is_enabled() -> bool;
60
61	fn set_overlayed_changes(
62		client: &C,
63		overlayed_changes: &mut OverlayedChanges<HashingFor<B>>,
64		block: B::Hash,
65		version: u32,
66		address: Address,
67		balance: Option<U256>,
68		nonce: Option<U256>,
69	);
70
71	fn into_account_id_bytes(address: Address) -> Vec<u8>;
72}
73
74impl<B: BlockT, C> RuntimeStorageOverride<B, C> for () {
75	fn is_enabled() -> bool {
76		false
77	}
78
79	fn set_overlayed_changes(
80		_client: &C,
81		_overlayed_changes: &mut OverlayedChanges<HashingFor<B>>,
82		_block: B::Hash,
83		_version: u32,
84		_address: Address,
85		_balance: Option<U256>,
86		_nonce: Option<U256>,
87	) {
88	}
89
90	fn into_account_id_bytes(_address: Address) -> Vec<u8> {
91		Vec::default()
92	}
93}
94
95sp_api::decl_runtime_apis! {
96	/// API necessary for Ethereum-compatibility layer.
97	#[api_version(6)]
98	pub trait EthereumRuntimeRPCApi {
99		/// Returns runtime defined pallet_evm::ChainId.
100		fn chain_id() -> u64;
101
102		/// Returns pallet_evm::Accounts by address.
103		fn account_basic(address: Address) -> fp_evm::Account;
104
105		/// Returns FixedGasPrice::min_gas_price
106		fn gas_price() -> U256;
107
108		/// For a given account address, returns pallet_evm::AccountCodes.
109		fn account_code_at(address: Address) -> Vec<u8>;
110
111		/// Returns the converted FindAuthor::find_author authority id.
112		fn author() -> Address;
113
114		/// For a given account address and index, returns pallet_evm::AccountStorages.
115		fn storage_at(address: Address, index: U256) -> H256;
116
117		/// Returns a frame_ethereum::call response. If `estimate` is true,
118		#[changed_in(2)]
119		fn call(
120			from: Address,
121			to: Address,
122			data: Vec<u8>,
123			value: U256,
124			gas_limit: U256,
125			gas_price: Option<U256>,
126			nonce: Option<U256>,
127			estimate: bool,
128		) -> Result<fp_evm::ExecutionInfo::<Vec<u8>>, sp_runtime::DispatchError>;
129		#[changed_in(4)]
130		fn call(
131			from: Address,
132			to: Address,
133			data: Vec<u8>,
134			value: U256,
135			gas_limit: U256,
136			max_fee_per_gas: Option<U256>,
137			max_priority_fee_per_gas: Option<U256>,
138			nonce: Option<U256>,
139			estimate: bool,
140		) -> Result<fp_evm::ExecutionInfo::<Vec<u8>>, sp_runtime::DispatchError>;
141		#[changed_in(5)]
142		fn call(
143			from: Address,
144			to: Address,
145			data: Vec<u8>,
146			value: U256,
147			gas_limit: U256,
148			max_fee_per_gas: Option<U256>,
149			max_priority_fee_per_gas: Option<U256>,
150			nonce: Option<U256>,
151			estimate: bool,
152			access_list: Option<Vec<(Address, Vec<H256>)>>,
153		) -> Result<fp_evm::ExecutionInfo::<Vec<u8>>, sp_runtime::DispatchError>;
154		#[changed_in(6)]
155		fn call(
156			from: Address,
157			to: Address,
158			data: Vec<u8>,
159			value: U256,
160			gas_limit: U256,
161			max_fee_per_gas: Option<U256>,
162			max_priority_fee_per_gas: Option<U256>,
163			nonce: Option<U256>,
164			estimate: bool,
165			access_list: Option<Vec<(Address, Vec<H256>)>>,
166		) -> Result<fp_evm::ExecutionInfoV2::<Vec<u8>>, sp_runtime::DispatchError>;
167		#[allow(clippy::type_complexity)]
168		fn call(
169			from: Address,
170			to: Address,
171			data: Vec<u8>,
172			value: U256,
173			gas_limit: U256,
174			max_fee_per_gas: Option<U256>,
175			max_priority_fee_per_gas: Option<U256>,
176			nonce: Option<U256>,
177			estimate: bool,
178			access_list: Option<Vec<(Address, Vec<H256>)>>,
179			authorization_list: Option<AuthorizationList>,
180		) -> Result<fp_evm::ExecutionInfoV2::<Vec<u8>>, sp_runtime::DispatchError>;
181
182		/// Returns a frame_ethereum::create response.
183		#[changed_in(2)]
184		fn create(
185			from: Address,
186			data: Vec<u8>,
187			value: U256,
188			gas_limit: U256,
189			gas_price: Option<U256>,
190			nonce: Option<U256>,
191			estimate: bool,
192		) -> Result<fp_evm::ExecutionInfo::<Address>, sp_runtime::DispatchError>;
193		#[changed_in(4)]
194		fn create(
195			from: Address,
196			data: Vec<u8>,
197			value: U256,
198			gas_limit: U256,
199			max_fee_per_gas: Option<U256>,
200			max_priority_fee_per_gas: Option<U256>,
201			nonce: Option<U256>,
202			estimate: bool,
203		) -> Result<fp_evm::ExecutionInfo::<Address>, sp_runtime::DispatchError>;
204		#[changed_in(5)]
205		fn create(
206			from: Address,
207			data: Vec<u8>,
208			value: U256,
209			gas_limit: U256,
210			max_fee_per_gas: Option<U256>,
211			max_priority_fee_per_gas: Option<U256>,
212			nonce: Option<U256>,
213			estimate: bool,
214			access_list: Option<Vec<(Address, Vec<H256>)>>,
215		) -> Result<fp_evm::ExecutionInfo::<Address>, sp_runtime::DispatchError>;
216		#[changed_in(6)]
217		fn create(
218			from: Address,
219			data: Vec<u8>,
220			value: U256,
221			gas_limit: U256,
222			max_fee_per_gas: Option<U256>,
223			max_priority_fee_per_gas: Option<U256>,
224			nonce: Option<U256>,
225			estimate: bool,
226			access_list: Option<Vec<(Address, Vec<H256>)>>,
227		) -> Result<fp_evm::ExecutionInfoV2::<Address>, sp_runtime::DispatchError>;
228		#[allow(clippy::type_complexity)]
229		fn create(
230			from: Address,
231			data: Vec<u8>,
232			value: U256,
233			gas_limit: U256,
234			max_fee_per_gas: Option<U256>,
235			max_priority_fee_per_gas: Option<U256>,
236			nonce: Option<U256>,
237			estimate: bool,
238			access_list: Option<Vec<(Address, Vec<H256>)>>,
239			authorization_list: Option<AuthorizationList>,
240		) -> Result<fp_evm::ExecutionInfoV2::<Address>, sp_runtime::DispatchError>;
241
242		/// Return the current block. Legacy.
243		#[changed_in(2)]
244		fn current_block() -> Option<ethereum::BlockV0>;
245		/// Return the current block.
246		fn current_block() -> Option<ethereum::BlockV3>;
247
248		/// Return the current receipt.
249		#[changed_in(4)]
250		fn current_receipts() -> Option<Vec<ethereum::ReceiptV0>>;
251		/// Return the current receipt.
252		fn current_receipts() -> Option<Vec<ethereum::ReceiptV4>>;
253
254		/// Return the current transaction status.
255		fn current_transaction_statuses() -> Option<Vec<TransactionStatus>>;
256
257		/// Return all the current data for a block in a single runtime call. Legacy.
258		#[changed_in(2)]
259		fn current_all() -> (
260			Option<ethereum::BlockV0>,
261			Option<Vec<ethereum::ReceiptV0>>,
262			Option<Vec<TransactionStatus>>
263		);
264		/// Return all the current data for a block in a single runtime call.
265		#[changed_in(4)]
266		fn current_all() -> (
267			Option<ethereum::BlockV3>,
268			Option<Vec<ethereum::ReceiptV0>>,
269			Option<Vec<TransactionStatus>>
270		);
271		fn current_all() -> (
272			Option<ethereum::BlockV3>,
273			Option<Vec<ethereum::ReceiptV4>>,
274			Option<Vec<TransactionStatus>>
275		);
276
277		/// Receives a `Vec<OpaqueExtrinsic>` and filters all the ethereum transactions. Legacy.
278		#[changed_in(2)]
279		fn extrinsic_filter(
280			xts: Vec<<Block as BlockT>::Extrinsic>,
281		) -> Vec<ethereum::TransactionV0>;
282		/// Receives a `Vec<OpaqueExtrinsic>` and filters all the ethereum transactions.
283		fn extrinsic_filter(
284			xts: Vec<<Block as BlockT>::Extrinsic>,
285		) -> Vec<ethereum::TransactionV3>;
286
287		/// Return the elasticity multiplier.
288		fn elasticity() -> Option<Permill>;
289
290		/// Used to determine if gas limit multiplier for non-transactional calls (eth_call/estimateGas)
291		/// is supported.
292		fn gas_limit_multiplier_support();
293
294		/// Return the pending block.
295		fn pending_block(
296			xts: Vec<<Block as BlockT>::Extrinsic>,
297		) -> (Option<ethereum::BlockV3>, Option<Vec<TransactionStatus>>);
298		/// Initialize the pending block.
299		/// The behavior should be the same as the runtime api Core_initialize_block but
300		/// for a "pending" block.
301		/// If your project don't need to have a different behavior to initialize "pending" blocks,
302		/// you can copy your Core_initialize_block implementation.
303		fn initialize_pending_block(header: &<Block as BlockT>::Header);
304	}
305
306	#[api_version(2)]
307	pub trait ConvertTransactionRuntimeApi {
308		fn convert_transaction(transaction: ethereum::TransactionV3) -> <Block as BlockT>::Extrinsic;
309		#[changed_in(2)]
310		fn convert_transaction(transaction: ethereum::TransactionV0) -> <Block as BlockT>::Extrinsic;
311	}
312}
313
314/// Fallback transaction converter when the `ConvertTransactionRuntimeApi` is not available. For almost all
315/// non-legacy cases, you can instantiate this type as `NoTransactionConverter`.
316pub trait ConvertTransaction<E> {
317	fn convert_transaction(&self, transaction: ethereum::TransactionV3) -> E;
318}
319
320/// No fallback transaction converter is available.
321// `NoTransactionConverter` is a non-instantiable type (an enum with no variants),
322// so we are guaranteed at compile time that `NoTransactionConverter` can never be instantiated.
323pub enum NoTransactionConverter {}
324impl<E> ConvertTransaction<E> for NoTransactionConverter {
325	// `convert_transaction` is a method taking `&self` as a parameter, so it can only be called via an instance of type Self,
326	// so we are guaranteed at compile time that this method can never be called.
327	fn convert_transaction(&self, _transaction: ethereum::TransactionV3) -> E {
328		match *self {}
329	}
330}