Skip to content

Commit

Permalink
Improve eth_getLogs runtime access (#153)
Browse files Browse the repository at this point in the history
* Add `current_all` to EthereumRuntimeRPCApi

* Use `TransactionStatus` only.

* Fix checker
  • Loading branch information
tgmichel authored Oct 5, 2020
1 parent 0e9381c commit cc1040c
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 25 deletions.
6 changes: 6 additions & 0 deletions rpc/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ sp_api::decl_runtime_apis! {
fn current_receipts() -> Option<Vec<ethereum::Receipt>>;
/// Return the current transaction status.
fn current_transaction_statuses() -> Option<Vec<TransactionStatus>>;
/// Return all the current data for a block in a single runtime call.
fn current_all() -> (
Option<EthereumBlock>,
Option<Vec<ethereum::Receipt>>,
Option<Vec<TransactionStatus>>
);
}
}

Expand Down
43 changes: 18 additions & 25 deletions rpc/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
}

fn logs(&self, filter: Filter) -> Result<Vec<Log>> {
let mut blocks_and_receipts = Vec::new();
let mut blocks_and_statuses = Vec::new();
let mut ret = Vec::new();

if let Some(hash) = filter.block_hash {
Expand All @@ -730,14 +730,12 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
_ => return Ok(Vec::new()),
};

let block = self.client.runtime_api()
.current_block(&id)
let (block, _, statuses) = self.client.runtime_api()
.current_all(&id)
.map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?;
let receipts = self.client.runtime_api().current_receipts(&id)
.map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?;

if let (Some(block), Some(receipts)) = (block, receipts) {
blocks_and_receipts.push((block, receipts));
if let (Some(block), Some(statuses)) = (block, statuses) {
blocks_and_statuses.push((block, statuses));
}
} else {
let mut current_number = filter.to_block
Expand All @@ -753,18 +751,15 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
.unwrap_or(
self.client.info().best_number
);

while current_number >= from_number {
let id = BlockId::Number(current_number);

let block = self.client.runtime_api()
.current_block(&id)
let (block, _, statuses) = self.client.runtime_api()
.current_all(&id)
.map_err(|err| internal_err(format!("fetch runtime account basic failed: {:?}", err)))?;
let receipts = self.client.runtime_api().current_receipts(&id)
.map_err(|err| internal_err(format!("call runtime failed: {:?}", err)))?;

if let (Some(block), Some(receipts)) = (block, receipts) {
blocks_and_receipts.push((block, receipts));
if let (Some(block), Some(statuses)) = (block, statuses) {
blocks_and_statuses.push((block, statuses));
}

if current_number == Zero::zero() {
Expand All @@ -775,15 +770,15 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
}
}

for (block, receipts) in blocks_and_receipts {
for (block, statuses) in blocks_and_statuses {
let mut block_log_index: u32 = 0;
for (index, receipt) in receipts.iter().enumerate() {
let logs = receipt.logs.clone();
let block_hash = H256::from_slice(
Keccak256::digest(&rlp::encode(&block.header)).as_slice()
);
for status in statuses.iter() {
let logs = status.logs.clone();
let mut transaction_log_index: u32 = 0;
let transaction = &block.transactions[index as usize];
let transaction_hash = H256::from_slice(
Keccak256::digest(&rlp::encode(transaction)).as_slice()
);
let transaction_hash = status.transaction_hash;
for log in logs {
let mut add: bool = false;
if let (
Expand All @@ -810,12 +805,10 @@ impl<B, C, P, CT, BE> EthApiT for EthApi<B, C, P, CT, BE> where
address: log.address.clone(),
topics: log.topics.clone(),
data: Bytes(log.data.clone()),
block_hash: Some(H256::from_slice(
Keccak256::digest(&rlp::encode(&block.header)).as_slice()
)),
block_hash: Some(block_hash),
block_number: Some(block.header.number.clone()),
transaction_hash: Some(transaction_hash),
transaction_index: Some(U256::from(index)),
transaction_index: Some(U256::from(status.transaction_index)),
log_index: Some(U256::from(block_log_index)),
transaction_log_index: Some(U256::from(transaction_log_index)),
removed: false,
Expand Down
12 changes: 12 additions & 0 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,18 @@ impl_runtime_apis! {
fn current_receipts() -> Option<Vec<frame_ethereum::Receipt>> {
Ethereum::current_receipts()
}

fn current_all() -> (
Option<frame_ethereum::Block>,
Option<Vec<frame_ethereum::Receipt>>,
Option<Vec<TransactionStatus>>
) {
(
Ethereum::current_block(),
Ethereum::current_receipts(),
Ethereum::current_transaction_statuses()
)
}
}

impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
Expand Down

0 comments on commit cc1040c

Please sign in to comment.