1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This file is part of Frontier.
//
// Copyright (c) 2020-2022 Parity Technologies (UK) Ltd.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::{marker::PhantomData, sync::Arc};
use ethereum_types::H256;
use jsonrpsee::core::RpcResult;
// Substrate
use sp_api::{Core, ProvideRuntimeApi};
use sp_blockchain::HeaderBackend;
use sp_core::keccak_256;
use sp_runtime::traits::Block as BlockT;
// Frontier
use fc_rpc_core::{types::Bytes, Web3ApiServer};
use fp_rpc::EthereumRuntimeRPCApi;
use crate::internal_err;
/// Web3 API implementation.
pub struct Web3<B, C> {
client: Arc<C>,
_marker: PhantomData<B>,
}
impl<B, C> Web3<B, C> {
pub fn new(client: Arc<C>) -> Self {
Self {
client,
_marker: PhantomData,
}
}
}
impl<B, C> Web3ApiServer for Web3<B, C>
where
B: BlockT,
C: ProvideRuntimeApi<B>,
C::Api: EthereumRuntimeRPCApi<B>,
C: HeaderBackend<B> + 'static,
{
fn client_version(&self) -> RpcResult<String> {
let hash = self.client.info().best_hash;
let version = self
.client
.runtime_api()
.version(hash)
.map_err(|err| internal_err(format!("fetch runtime version failed: {:?}", err)))?;
Ok(format!(
"{spec_name}/v{spec_version}.{impl_version}/{pkg_name}-{pkg_version}",
spec_name = version.spec_name,
spec_version = version.spec_version,
impl_version = version.impl_version,
pkg_name = env!("CARGO_PKG_NAME"),
pkg_version = env!("CARGO_PKG_VERSION")
))
}
fn sha3(&self, input: Bytes) -> RpcResult<H256> {
Ok(H256::from(keccak_256(&input.into_vec())))
}
}