Skip to content

Commit

Permalink
Support for additional Receipt fields #2 (#59)
Browse files Browse the repository at this point in the history
* Support logs_bloom in transaction_receipt

* Support cumulative_gas_used in transaction_receipt

* Support transaction_log_index in transaction_receipt

* Support log_index in transaction_receipt

* Support removed field in transaction_receipt

* Removed log_type field from rpc core Log

* Add comment for transaction_by_hash response
  • Loading branch information
tgmichel authored Jul 7, 2020
1 parent 412b277 commit 6b29482
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 15 deletions.
9 changes: 7 additions & 2 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,17 +260,22 @@ impl<T: Trait> Module<T> {
TransactionStatuses::get(hash)
}

// Requires returning a Vec<Receipt> to enable cumulative calculations in the rpc-end.
//
// - `cumulative_gas_used`: the sum of `used_gas` for this and all previous transactions
// in the block.
// - `log_index`: each Log's index, block wise.
pub fn transaction_by_hash(hash: H256) -> Option<(
ethereum::Transaction,
ethereum::Block,
TransactionStatus,
ethereum::Receipt
Vec<ethereum::Receipt>
)> {
let (block_hash, transaction_index) = Transactions::get(hash)?;
let transaction_status = TransactionStatuses::get(hash)?;
let (block, receipts) = BlocksAndReceipts::get(block_hash)?;
let transaction = &block.transactions[transaction_index as usize];
Some((transaction.clone(), block, transaction_status, receipts[transaction_index as usize].clone()))
Some((transaction.clone(), block, transaction_status, receipts))
}

pub fn transaction_by_block_hash_and_index(
Expand Down
3 changes: 0 additions & 3 deletions rpc/core/src/types/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ pub struct Log {
pub log_index: Option<U256>,
/// Log Index in Transaction
pub transaction_log_index: Option<U256>,
/// Log Type
#[serde(rename = "type")]
pub log_type: String,
/// Whether Log Type is Removed (Geth Compatibility Field)
#[serde(default)]
pub removed: bool,
Expand Down
2 changes: 1 addition & 1 deletion rpc/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ sp_api::decl_runtime_apis! {
EthereumTransaction,
EthereumBlock,
TransactionStatus,
EthereumReceipt
Vec<EthereumReceipt>
)>;
fn transaction_by_block_hash_and_index(
hash: H256,
Expand Down
33 changes: 25 additions & 8 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,24 +566,40 @@ impl<B, C, SC, P, CT, BE> EthApiT for EthApi<B, C, SC, P, CT, BE> where
fn transaction_receipt(&self, hash: H256) -> Result<Option<Receipt>> {
let header = self.select_chain.best_chain()
.map_err(|_| internal_err("fetch header failed"))?;
if let Ok(Some((_transaction, block, status, receipt))) = self.client.runtime_api()
if let Ok(Some((_transaction, block, status, receipts))) = self.client.runtime_api()
.transaction_by_hash(&BlockId::Hash(header.hash()), hash) {

let block_hash = H256::from_slice(
Keccak256::digest(&rlp::encode(&block.header)).as_slice()
);
let receipt = receipts[status.transaction_index as usize].clone();
let mut cumulative_receipts = receipts.clone();
cumulative_receipts.truncate((status.transaction_index + 1) as usize);

return Ok(Some(Receipt {
transaction_hash: Some(status.transaction_hash),
transaction_index: Some(status.transaction_index.into()),
block_hash: Some(block_hash),
from: Some(status.from),
to: status.to,
block_number: Some(block.header.number),
cumulative_gas_used: Default::default(), // TODO
cumulative_gas_used: {
let cumulative_gas: u32 = cumulative_receipts.iter().map(|r| {
r.used_gas.as_u32()
}).sum();
U256::from(cumulative_gas)
},
gas_used: Some(receipt.used_gas),
contract_address: status.contract_address,
logs: {
receipt.logs.iter().map(|log| {
let mut pre_receipts_log_index = None;
if cumulative_receipts.len() > 0 {
cumulative_receipts.truncate(cumulative_receipts.len() - 1);
pre_receipts_log_index = Some(cumulative_receipts.iter().map(|r| {
r.logs.len() as u32
}).sum::<u32>());
}
receipt.logs.iter().enumerate().map(|(i, log)| {
Log {
address: log.address,
topics: log.topics.clone(),
Expand All @@ -592,15 +608,16 @@ impl<B, C, SC, P, CT, BE> EthApiT for EthApi<B, C, SC, P, CT, BE> where
block_number: Some(block.header.number),
transaction_hash: Some(hash),
transaction_index: Some(status.transaction_index.into()),
log_index: None, // TODO
transaction_log_index: None, // TODO
log_type: Default::default(), // TODO
removed: false, // TODO
log_index: Some(U256::from(
(pre_receipts_log_index.unwrap_or(0)) + i as u32
)),
transaction_log_index: Some(U256::from(i)),
removed: false,
}
}).collect()
},
state_root: Some(receipt.state_root),
logs_bloom: Default::default(), // TODO
logs_bloom: receipt.logs_bloom,
status_code: None,
}))
}
Expand Down
2 changes: 1 addition & 1 deletion template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ impl_runtime_apis! {
EthereumTransaction,
EthereumBlock,
TransactionStatus,
EthereumReceipt)> {
Vec<EthereumReceipt>)> {
<ethereum::Module<Runtime>>::transaction_by_hash(hash)
}

Expand Down

0 comments on commit 6b29482

Please sign in to comment.