Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime API impls: gas_price, block_number, balance, code_at #9

Merged
merged 12 commits into from
Jun 4, 2020
6 changes: 3 additions & 3 deletions rpc/core/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub trait EthApi {

/// Returns current gas_price.
#[rpc(name = "eth_gasPrice")]
fn gas_price(&self) -> BoxFuture<U256>;
fn gas_price(&self) -> Result<U256>;

/// Returns accounts list.
#[rpc(name = "eth_accounts")]
Expand All @@ -69,7 +69,7 @@ pub trait EthApi {

/// Returns balance of the given account.
#[rpc(name = "eth_getBalance")]
fn balance(&self, _: H160, _: Option<BlockNumber>) -> BoxFuture<U256>;
fn balance(&self, _: H160, _: Option<BlockNumber>) -> Result<U256>;

/// Returns the account- and storage-values of the specified account including the Merkle-proof
#[rpc(name = "eth_getProof")]
Expand Down Expand Up @@ -109,7 +109,7 @@ pub trait EthApi {

/// Returns the code at given address at given time (block number).
#[rpc(name = "eth_getCode")]
fn code_at(&self, _: H160, _: Option<BlockNumber>) -> BoxFuture<Bytes>;
fn code_at(&self, _: H160, _: Option<BlockNumber>) -> Result<Bytes>;

/// Sends signed transaction, returning its hash.
#[rpc(name = "eth_sendRawTransaction")]
Expand Down
5 changes: 4 additions & 1 deletion rpc/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#![cfg_attr(not(feature = "std"), no_std)]

use sp_core::{H160, H256};
use sp_core::{H160, H256, U256};
use ethereum::Log;
use ethereum_types::Bloom;
use codec::{Encode, Decode};
Expand All @@ -39,6 +39,9 @@ sp_api::decl_runtime_apis! {
fn chain_id() -> u64;
fn account_basic(address: H160) -> pallet_evm::Account;
fn transaction_status(hash: H256) -> Option<TransactionStatus>;
fn gas_price() -> U256;
fn evm_balance(address: H160) -> U256;
fn code_at(address: H160) -> Vec<u8>;
}
}

Expand Down
60 changes: 52 additions & 8 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{marker::PhantomData, sync::Arc};
use ethereum_types::{H160, H256, H64, U256, U64};
use jsonrpc_core::{BoxFuture, Result, ErrorCode, Error, futures::future::{self, Future}};
use futures::future::TryFutureExt;
use sp_runtime::traits::{Block as BlockT, Header as _};
use sp_runtime::traits::{Block as BlockT, Header as _, UniqueSaturatedInto};
use sp_runtime::transaction_validity::TransactionSource;
use sp_api::{ProvideRuntimeApi, BlockId};
use sp_consensus::SelectChain;
Expand Down Expand Up @@ -98,20 +98,49 @@ impl<B, C, SC, P, CT> EthApiT for EthApi<B, C, SC, P, CT> where
.map_err(|_| internal_err("fetch runtime chain id failed"))?.into()))
}

fn gas_price(&self) -> BoxFuture<U256> {
unimplemented!("gas_price");
fn gas_price(&self) -> Result<U256> {
let header = self
.select_chain
.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;
Ok(
self.client
.runtime_api()
.gas_price(&BlockId::Hash(header.hash()))
.map_err(|_| internal_err("fetch runtime chain id failed"))?
.into(),
)
}

fn accounts(&self) -> Result<Vec<H160>> {
unimplemented!("accounts");
}

fn block_number(&self) -> Result<U256> {
unimplemented!("block_number");
let header = self
.select_chain
.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;
Ok(U256::from(header.number().clone().unique_saturated_into()))
}

fn balance(&self, _: H160, _: Option<BlockNumber>) -> BoxFuture<U256> {
unimplemented!("balance");
fn balance(&self, address: H160, number: Option<BlockNumber>) -> Result<U256> {
if let Some(number) = number {
if number != BlockNumber::Latest {
unimplemented!("fetch nonce for past blocks is not yet supported");
}
}
let header = self
.select_chain
.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;
Ok(
self.client
.runtime_api()
.evm_balance(&BlockId::Hash(header.hash()), address)
.map_err(|_| internal_err("fetch runtime chain id failed"))?
.into(),
)
}

fn proof(&self, _: H160, _: Vec<H256>, _: Option<BlockNumber>) -> BoxFuture<EthAccount> {
Expand Down Expand Up @@ -159,8 +188,23 @@ impl<B, C, SC, P, CT> EthApiT for EthApi<B, C, SC, P, CT> where
unimplemented!("block_uncles_count_by_number");
}

fn code_at(&self, _: H160, _: Option<BlockNumber>) -> BoxFuture<Bytes> {
unimplemented!("code_at");
fn code_at(&self, address: H160, number: Option<BlockNumber>) -> Result<Bytes> {
if let Some(number) = number {
if number != BlockNumber::Latest {
unimplemented!("fetch nonce for past blocks is not yet supported");
}
}
let header = self
.select_chain
.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;
Ok(
self.client
.runtime_api()
.code_at(&BlockId::Hash(header.hash()), address)
.map_err(|_| internal_err("fetch runtime chain id failed"))?
.into(),
)
}

fn send_raw_transaction(&self, bytes: Bytes) -> BoxFuture<H256> {
Expand Down
14 changes: 14 additions & 0 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata, U256, H160, H256};
use sp_runtime::traits::{
BlakeTwo256, Block as BlockT, IdentifyAccount, IdentityLookup, NumberFor, Saturating, Verify,
UniqueSaturatedInto
};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
Expand Down Expand Up @@ -448,6 +449,19 @@ impl_runtime_apis! {
fn transaction_status(hash: H256) -> Option<ethereum::TransactionStatus> {
ethereum::Module::<Runtime>::transaction_status(hash)
}

fn gas_price() -> U256 {
FixedGasPrice::min_gas_price()
}

fn evm_balance(address: H160) -> U256 {
let account: EVMAccount = evm::Module::<Runtime>::accounts(address);
account.balance
}

fn code_at(address: H160) -> Vec<u8> {
evm::Module::<Runtime>::account_codes(address)
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Expand Down