From c8b4373e13c83b26dee2c8f4ac6967260c4cd43b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 18 Oct 2019 18:12:02 +0200 Subject: [PATCH] [receipt]: add `sender` & `receiver` to `RichReceipts` (#11179) * [receipts]: add `to` & `from` to `RichReceipts` * [rpc]: add test for `pending_receipt` * docs(common_types/receipt): add note Option field --- ethcore/src/miner/miner.rs | 5 +++++ ethcore/types/src/receipt.rs | 8 ++++++++ rpc/src/v1/tests/mocked/eth.rs | 32 +++++++++++++++++++++++++++++-- rpc/src/v1/tests/mocked/parity.rs | 2 +- rpc/src/v1/types/receipt.rs | 10 ++++++---- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d97b1170266..3d55f88eea1 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1236,6 +1236,11 @@ impl miner::MinerService for Miner { let prev_gas = if index == 0 { Default::default() } else { receipts[index - 1].gas_used }; let receipt = &receipts[index]; RichReceipt { + from: tx.sender(), + to: match tx.action { + Action::Create => None, + Action::Call(ref address) => Some(*address), + }, transaction_hash: tx.hash(), transaction_index: index, cumulative_gas_used: receipt.gas_used, diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index 95b39e7de4b..9f53a43354b 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -122,6 +122,7 @@ pub struct RichReceipt { /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`. pub gas_used: U256, /// Contract address. + /// NOTE: It is an Option because only `Action::Create` transactions has a contract address pub contract_address: Option
, /// Logs pub logs: Vec, @@ -129,6 +130,11 @@ pub struct RichReceipt { pub log_bloom: Bloom, /// Transaction outcome. pub outcome: TransactionOutcome, + /// Receiver address + /// NOTE: It is an Option because only `Action::Call` transactions has a receiver address + pub to: Option, + /// Sender + pub from: H160 } /// Receipt with additional info. @@ -147,6 +153,7 @@ pub struct LocalizedReceipt { /// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`. pub gas_used: U256, /// Contract address. + /// NOTE: It is an Option because only `Action::Create` transactions has a contract address pub contract_address: Option
, /// Logs pub logs: Vec, @@ -155,6 +162,7 @@ pub struct LocalizedReceipt { /// Transaction outcome. pub outcome: TransactionOutcome, /// Receiver address + /// NOTE: It is an Option because only `Action::Call` transactions has a receiver address pub to: Option, /// Sender pub from: H160 diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index bb6cb6b67ce..0f4342e4bbe 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -35,7 +35,7 @@ use types::{ ids::{BlockId, TransactionId}, transaction::{Transaction, Action}, log_entry::{LocalizedLogEntry, LogEntry}, - receipt::{LocalizedReceipt, TransactionOutcome}, + receipt::{LocalizedReceipt, RichReceipt, TransactionOutcome}, snapshot::RestorationStatus, }; @@ -971,7 +971,7 @@ fn rpc_eth_transaction_receipt() { "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","removed":false,"topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","status":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","removed":false,"topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"#; assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } @@ -991,6 +991,34 @@ fn rpc_eth_transaction_receipt_null() { assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); } +#[test] +fn rpc_eth_pending_receipt() { + let pending = RichReceipt { + from: H160::from_str("b60e8dd61c5d32be8058bb8eb970870f07233155").unwrap(), + to: Some(H160::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + transaction_hash: H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap(), + transaction_index: 0, + cumulative_gas_used: U256::from(0x20), + gas_used: U256::from(0x10), + contract_address: None, + logs: Vec::new(), + log_bloom: Bloom::zero(), + outcome: TransactionOutcome::Unknown, + }; + let tester = EthTester::default(); + + tester.miner.pending_receipts.lock().push(pending); + + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_getTransactionReceipt", + "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"contractAddress":null,"cumulativeGasUsed":"0x20","from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","gasUsed":"0x10","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionHash":"0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238","transactionIndex":"0x0"},"id":1}"#; + assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); +} + // These tests are incorrect: their output is undefined as long as eth_getCompilers is []. // Will ignore for now, but should probably be replaced by more substantial tests which check // the output of eth_getCompilers to determine whether to test. CI systems can then be preinstalled diff --git a/rpc/src/v1/tests/mocked/parity.rs b/rpc/src/v1/tests/mocked/parity.rs index 9439164ee61..85f80350337 100644 --- a/rpc/src/v1/tests/mocked/parity.rs +++ b/rpc/src/v1/tests/mocked/parity.rs @@ -510,7 +510,7 @@ fn rpc_parity_block_receipts() { "params": [], "id": 1 }"#; - let response = r#"{"jsonrpc":"2.0","result":[{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x0","contractAddress":null,"cumulativeGasUsed":"0x5208","from":"0x0000000000000000000000000000000000000009","gasUsed":"0x5208","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001","root":null,"status":null,"to":null,"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000001","transactionIndex":"0x0"}],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":[{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x0","contractAddress":null,"cumulativeGasUsed":"0x5208","from":"0x0000000000000000000000000000000000000009","gasUsed":"0x5208","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001","to":null,"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000001","transactionIndex":"0x0"}],"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); } diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index 9e5b5e3a686..727b4ce6e90 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -43,12 +43,14 @@ pub struct Receipt { /// Logs pub logs: Vec, /// State Root - #[serde(rename = "root")] + // NOTE(niklasad1): EIP98 makes this optional field, if it's missing then skip serializing it + #[serde(skip_serializing_if = "Option::is_none", rename = "root")] pub state_root: Option, /// Logs bloom pub logs_bloom: H2048, /// Status code - #[serde(rename = "status")] + // NOTE(niklasad1): Unknown after EIP98 rules, if it's missing then skip serializing it + #[serde(skip_serializing_if = "Option::is_none", rename = "status")] pub status_code: Option, } @@ -91,8 +93,8 @@ impl From for Receipt { impl From for Receipt { fn from(r: RichReceipt) -> Self { Receipt { - from: None, - to: None, + from: Some(r.from), + to: r.to.map(Into::into), transaction_hash: Some(r.transaction_hash), transaction_index: Some(r.transaction_index.into()), block_hash: None,