Skip to content

Commit

Permalink
Implement block_by_hash Runtime API (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
tgmichel authored Jun 10, 2020
1 parent 1347e81 commit 530b734
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 31 deletions.
7 changes: 7 additions & 0 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,13 @@ impl<T: Trait> Module<T> {
None
}

pub fn block_by_hash(hash: H256) -> Option<ethereum::Block> {
if let Some((block, _receipt)) = BlocksAndReceipts::get(hash) {
return Some(block)
}
None
}

/// Execute an Ethereum transaction, ignoring transaction signatures.
pub fn execute(source: H160, transaction: ethereum::Transaction) {
let transaction_hash = H256::from_slice(
Expand Down
2 changes: 1 addition & 1 deletion rpc/core/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub trait EthApi {

/// Returns block with given hash.
#[rpc(name = "eth_getBlockByHash")]
fn block_by_hash(&self, _: H256, _: bool) -> BoxFuture<Option<RichBlock>>;
fn block_by_hash(&self, _: H256, _: bool) -> Result<Option<RichBlock>>;

/// Returns block with given number.
#[rpc(name = "eth_getBlockByNumber")]
Expand Down
1 change: 1 addition & 0 deletions rpc/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ sp_api::decl_runtime_apis! {
fn author() -> H160;
fn block_by_number(number: u32) -> Option<EthereumBlock>;
fn block_transaction_count_by_number(number: u32) -> Option<U256>;
fn block_by_hash(hash: H256) -> Option<EthereumBlock>;
}
}

Expand Down
75 changes: 45 additions & 30 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ impl<B: BlockT, C, SC, P, CT, BE> EthApi<B, C, SC, P, CT, BE> {
}
}

fn rich_block_build(block: ethereum::Block) -> RichBlock {
Rich {
inner: Block {
hash: None, // TODO
parent_hash: block.header.parent_hash,
uncles_hash: H256::zero(), // TODO
author: H160::default(), // TODO
miner: H160::default(), // TODO
state_root: block.header.state_root,
transactions_root: block.header.transactions_root,
receipts_root: block.header.receipts_root,
number: Some(block.header.number),
gas_used: block.header.gas_used,
gas_limit: block.header.gas_limit,
extra_data: Bytes(vec![]), // TODO H256 to Vec<u8>
logs_bloom: Some(block.header.logs_bloom),
timestamp: U256::from(block.header.timestamp),
difficulty: block.header.difficulty,
total_difficulty: None, // TODO
seal_fields: vec![], // TODO
uncles: vec![], // TODO
// TODO expected struct `frontier_rpc_core::types::transaction::Transaction`,
// found struct `ethereum::transaction::Transaction`
transactions: BlockTransactions::Full(vec![]),
size: None // TODO
},
extra_info: BTreeMap::new()
}
}

impl<B, C, SC, P, CT, BE> EthApiT for EthApi<B, C, SC, P, CT, BE> where
C: ProvideRuntimeApi<B> + StorageProvider<B,BE>,
C::Api: EthereumRuntimeApi<B>,
Expand Down Expand Up @@ -165,8 +195,18 @@ impl<B, C, SC, P, CT, BE> EthApiT for EthApi<B, C, SC, P, CT, BE> where
unimplemented!("storage_at");
}

fn block_by_hash(&self, _: H256, _: bool) -> BoxFuture<Option<RichBlock>> {
unimplemented!("block_by_hash");
fn block_by_hash(&self, hash: H256, _: bool) -> Result<Option<RichBlock>> {
let header = self.select_chain.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;

if let Ok(Some(block)) = self.client.runtime_api().block_by_hash(
&BlockId::Hash(header.hash()),
hash
) {
Ok(Some(rich_block_build(block)))
} else {
Ok(None)
}
}

fn block_by_number(&self, number: BlockNumber, _: bool) -> Result<Option<RichBlock>> {
Expand All @@ -185,34 +225,9 @@ impl<B, C, SC, P, CT, BE> EthApiT for EthApi<B, C, SC, P, CT, BE> where

if let Ok(Some(block)) = self.client.runtime_api().block_by_number(
&BlockId::Hash(header.hash()),
number_param) {
Ok(Some(Rich {
inner: Block {
hash: None, // TODO
parent_hash: block.header.parent_hash,
uncles_hash: H256::zero(), // TODO
author: H160::default(), // TODO
miner: H160::default(), // TODO
state_root: block.header.state_root,
transactions_root: block.header.transactions_root,
receipts_root: block.header.receipts_root,
number: Some(block.header.number),
gas_used: block.header.gas_used,
gas_limit: block.header.gas_limit,
extra_data: Bytes(vec![]), // TODO H256 to Vec<u8>
logs_bloom: Some(block.header.logs_bloom),
timestamp: U256::from(block.header.timestamp),
difficulty: block.header.difficulty,
total_difficulty: None, // TODO
seal_fields: vec![], // TODO
uncles: vec![], // TODO
// TODO expected struct `frontier_rpc_core::types::transaction::Transaction`,
// found struct `ethereum::transaction::Transaction`
transactions: BlockTransactions::Full(vec![]),
size: None // TODO
},
extra_info: BTreeMap::new()
}))
number_param
) {
Ok(Some(rich_block_build(block)))
} else {
Ok(None)
}
Expand Down
4 changes: 4 additions & 0 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,10 @@ impl_runtime_apis! {
}
None
}

fn block_by_hash(hash: H256) -> Option<EthereumBlock> {
<ethereum::Module<Runtime>>::block_by_hash(hash)
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Expand Down

0 comments on commit 530b734

Please sign in to comment.