referrerpolicy=no-referrer-when-downgrade

pallet_revive_eth_rpc/client/
runtime_api.rs

1// This file is part of Substrate.
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
18use crate::{
19	client::Balance,
20	subxt_client::{self, SrcChainConfig},
21	ClientError, LOG_TARGET,
22};
23use pallet_revive::{
24	evm::{GenericTransaction, Trace, H160, U256},
25	EthTransactInfo,
26};
27use subxt::OnlineClient;
28
29/// A Wrapper around subxt Runtime API
30#[derive(Clone)]
31pub struct RuntimeApi(subxt::runtime_api::RuntimeApi<SrcChainConfig, OnlineClient<SrcChainConfig>>);
32
33impl RuntimeApi {
34	/// Create a new instance.
35	pub fn new(
36		api: subxt::runtime_api::RuntimeApi<SrcChainConfig, OnlineClient<SrcChainConfig>>,
37	) -> Self {
38		Self(api)
39	}
40
41	/// Get the balance of the given address.
42	pub async fn balance(&self, address: H160) -> Result<U256, ClientError> {
43		let address = address.0.into();
44		let payload = subxt_client::apis().revive_api().balance(address);
45		let balance = self.0.call(payload).await?;
46		Ok(*balance)
47	}
48
49	/// Get the contract storage for the given contract address and key.
50	pub async fn get_storage(
51		&self,
52		contract_address: H160,
53		key: [u8; 32],
54	) -> Result<Option<Vec<u8>>, ClientError> {
55		let contract_address = contract_address.0.into();
56		let payload = subxt_client::apis().revive_api().get_storage(contract_address, key);
57		let result = self.0.call(payload).await?.map_err(|_| ClientError::ContractNotFound)?;
58		Ok(result)
59	}
60
61	/// Dry run a transaction and returns the [`EthTransactInfo`] for the transaction.
62	pub async fn dry_run(
63		&self,
64		tx: GenericTransaction,
65	) -> Result<EthTransactInfo<Balance>, ClientError> {
66		let payload = subxt_client::apis().revive_api().eth_transact(tx.into());
67		let result = self.0.call(payload).await?;
68		match result {
69			Err(err) => {
70				log::debug!(target: LOG_TARGET, "Dry run failed {err:?}");
71				Err(ClientError::TransactError(err.0))
72			},
73			Ok(result) => Ok(result.0),
74		}
75	}
76
77	/// Get the nonce of the given address.
78	pub async fn nonce(&self, address: H160) -> Result<U256, ClientError> {
79		let address = address.0.into();
80		let payload = subxt_client::apis().revive_api().nonce(address);
81		let nonce = self.0.call(payload).await?;
82		Ok(nonce.into())
83	}
84
85	/// Get the gas price
86	pub async fn gas_price(&self) -> Result<U256, ClientError> {
87		let payload = subxt_client::apis().revive_api().gas_price();
88		let gas_price = self.0.call(payload).await?;
89		Ok(*gas_price)
90	}
91
92	/// Convert a weight to a fee.
93	pub async fn block_gas_limit(&self) -> Result<U256, ClientError> {
94		let payload = subxt_client::apis().revive_api().block_gas_limit();
95		let gas_limit = self.0.call(payload).await?;
96		Ok(*gas_limit)
97	}
98
99	/// Get the miner address
100	pub async fn block_author(&self) -> Result<Option<H160>, ClientError> {
101		let payload = subxt_client::apis().revive_api().block_author();
102		let author = self.0.call(payload).await?;
103		Ok(author)
104	}
105
106	/// Get the trace for the given transaction index in the given block.
107	pub async fn trace_tx(
108		&self,
109		block: sp_runtime::generic::Block<
110			sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>,
111			sp_runtime::OpaqueExtrinsic,
112		>,
113		transaction_index: u32,
114		tracer_type: crate::TracerType,
115	) -> Result<Trace, ClientError> {
116		let payload = subxt_client::apis()
117			.revive_api()
118			.trace_tx(block.into(), transaction_index, tracer_type.into())
119			.unvalidated();
120
121		let trace = self.0.call(payload).await?.ok_or(ClientError::EthExtrinsicNotFound)?.0;
122		Ok(trace)
123	}
124
125	/// Get the trace for the given block.
126	pub async fn trace_block(
127		&self,
128		block: sp_runtime::generic::Block<
129			sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>,
130			sp_runtime::OpaqueExtrinsic,
131		>,
132		tracer_type: crate::TracerType,
133	) -> Result<Vec<(u32, Trace)>, ClientError> {
134		let payload = subxt_client::apis()
135			.revive_api()
136			.trace_block(block.into(), tracer_type.into())
137			.unvalidated();
138
139		let traces = self.0.call(payload).await?.into_iter().map(|(idx, t)| (idx, t.0)).collect();
140		Ok(traces)
141	}
142
143	/// Get the trace for the given call.
144	pub async fn trace_call(
145		&self,
146		transaction: GenericTransaction,
147		tracer_type: crate::TracerType,
148	) -> Result<Trace, ClientError> {
149		let payload = subxt_client::apis()
150			.revive_api()
151			.trace_call(transaction.into(), tracer_type.into())
152			.unvalidated();
153
154		let trace = self.0.call(payload).await?.map_err(|err| ClientError::TransactError(err.0))?;
155		Ok(trace.0)
156	}
157
158	/// Get the code of the given address.
159	pub async fn code(&self, address: H160) -> Result<Vec<u8>, ClientError> {
160		let payload = subxt_client::apis().revive_api().code(address);
161		let code = self.0.call(payload).await?;
162		Ok(code)
163	}
164}