Skip to content

Commit

Permalink
feat: implement eip2718/2930/1559 for receipts
Browse files Browse the repository at this point in the history
  • Loading branch information
yangby-cryptape committed Jun 27, 2023
1 parent df165b8 commit 9f6c101
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 12 deletions.
98 changes: 86 additions & 12 deletions ethers-core/src/types/transaction/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,16 +476,6 @@ pub struct TransactionReceipt {
pub other: crate::types::OtherFields,
}

impl rlp::Encodable for TransactionReceipt {
fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(4);
rlp_opt(s, &self.status);
s.append(&self.cumulative_gas_used);
s.append(&self.logs_bloom);
s.append_list(&self.logs);
}
}

// Compares the transaction receipt against another receipt by checking the blocks first and then
// the transaction index in the block
impl Ord for TransactionReceipt {
Expand All @@ -508,10 +498,61 @@ impl PartialOrd<Self> for TransactionReceipt {
}
}

impl TransactionReceipt {
/// Encode a transaction receipt into bytes base on RLP.
///
/// According to [`EIP-2718`]:
/// - `Receipt` is either `TransactionType || ReceiptPayload` or `LegacyReceipt`.
/// - `LegacyReceipt` is kept to be RLP encoded bytes; it is
/// `rlp([status, cumulativeGasUsed, logsBloom, logs])`.
/// - `ReceiptPayload` is an opaque byte array whose interpretation is dependent on the
/// `TransactionType` and defined in future EIPs.
/// - As [`EIP-2930`] defined:
/// if `TransactionType` is `1`, `ReceiptPayload` is
/// `rlp([status, cumulativeGasUsed, logsBloom, logs])`.
/// - As [`EIP-1559`] defined:
/// if `TransactionType` is `2`, `ReceiptPayload` is
/// `rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])`.
///
/// [`EIP-2718`]: https://eips.ethereum.org/EIPS/eip-2718#receipts
/// [`EIP-2930`]: https://eips.ethereum.org/EIPS/eip-2930#parameters
/// [`EIP-1559`]: https://eips.ethereum.org/EIPS/eip-1559#specification
pub fn rlp(&self) -> Bytes {
let mut rlp = RlpStream::new();
rlp.begin_list(4);
rlp_opt(&mut rlp, &self.status);
rlp.append(&self.cumulative_gas_used);
rlp.append(&self.logs_bloom);
rlp.append_list(&self.logs);

let rlp_bytes: Bytes = rlp.out().freeze().into();
let mut encoded = vec![];
match self.transaction_type {
Some(x) if x == U64::from(0x1) => {
encoded.extend_from_slice(&[0x1]);
encoded.extend_from_slice(rlp_bytes.as_ref());
encoded.into()
}
Some(x) if x == U64::from(0x2) => {
encoded.extend_from_slice(&[0x2]);
encoded.extend_from_slice(rlp_bytes.as_ref());
encoded.into()
}
#[cfg(feature = "optimism")]
Some(x) if x == U64::from(0x7E) => {
encoded.extend_from_slice(&[0x7E]);
encoded.extend_from_slice(rlp_bytes.as_ref());
encoded.into()
}
_ => rlp_bytes,
}
}
}

#[cfg(test)]
#[cfg(not(any(feature = "celo", feature = "optimism")))]
mod tests {
use rlp::{Encodable, Rlp};
use rlp::Rlp;

use crate::types::transaction::eip2930::AccessListItem;

Expand Down Expand Up @@ -1085,14 +1126,47 @@ mod tests {
#[test]
fn rlp_encode_receipt() {
let receipt = TransactionReceipt { status: Some(1u64.into()), ..Default::default() };
let encoded = receipt.rlp_bytes();
let encoded = receipt.rlp();

assert_eq!(
encoded,
hex::decode("f901060180b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0").unwrap(),
);
}

#[test]
fn rlp_encode_legacy_receipt() {
// Test case from Ethereum Mainnet (block-number: 17451262, tx-index: 12).
let receipt_json_str = include_str!("../../../testdata/receipt-17451262-12.json");
let expected_hex_str = include_str!("../../../testdata/receipt-17451262-12.hex");
let v: serde_json::Value = serde_json::from_str(receipt_json_str).unwrap();
let receipt: TransactionReceipt = serde_json::from_value(v.clone()).unwrap();
let encoded = receipt.rlp();
assert_eq!(encoded, hex::decode(expected_hex_str).unwrap());
}

#[test]
fn rlp_encode_typed_receipt_eip2930() {
// Test case from Ethereum Mainnet (block-number: 17451262, tx-index: 6).
let receipt_json_str = include_str!("../../../testdata/receipt-17451262-6.json");
let expected_hex_str = include_str!("../../../testdata/receipt-17451262-6.hex");
let v: serde_json::Value = serde_json::from_str(receipt_json_str).unwrap();
let receipt: TransactionReceipt = serde_json::from_value(v.clone()).unwrap();
let encoded = receipt.rlp();
assert_eq!(encoded, hex::decode(expected_hex_str).unwrap());
}

#[test]
fn rlp_encode_typed_receipt_eip1559() {
// Test case from Ethereum Mainnet (block-number: 17451262, tx-index: 2).
let receipt_json_str = include_str!("../../../testdata/receipt-17451262-2.json");
let expected_hex_str = include_str!("../../../testdata/receipt-17451262-2.hex");
let v: serde_json::Value = serde_json::from_str(receipt_json_str).unwrap();
let receipt: TransactionReceipt = serde_json::from_value(v.clone()).unwrap();
let encoded = receipt.rlp();
assert_eq!(encoded, hex::decode(expected_hex_str).unwrap());
}

#[test]
fn can_sort_receipts() {
let mut a = TransactionReceipt { block_number: Some(0u64.into()), ..Default::default() };
Expand Down
1 change: 1 addition & 0 deletions ethers-core/testdata/receipt-17451262-12.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f901a701831d1f52b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000100000400000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000002000000500000000000004000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000f89df89b9495ad61b0a150d79219dcf64e1e6cc01f0b64c4cef863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000de74eef3cfb2dbc8d08a6838a1dcea4a6d775f77a0000000000000000000000000cffad3200574698b78f32232aa9d63eabd290703a000000000000000000000000000000000000000000000421c908a67f030560c00
32 changes: 32 additions & 0 deletions ethers-core/testdata/receipt-17451262-12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"transactionHash": "0x4b5650349045b1f3e002c04d064ad563261a3f8a1236e99d2b5261e945e951ef",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"logs": [
{
"transactionHash": "0x4b5650349045b1f3e002c04d064ad563261a3f8a1236e99d2b5261e945e951ef",
"address": "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x00000000000000000000000000000000000000000000421c908a67f030560c00",
"logIndex": "0x47",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000de74eef3cfb2dbc8d08a6838a1dcea4a6d775f77",
"0x000000000000000000000000cffad3200574698b78f32232aa9d63eabd290703"
],
"transactionIndex": "0xc"
}
],
"contractAddress": null,
"effectiveGasPrice": "0x79a7d523a",
"cumulativeGasUsed": "0x1d1f52",
"from": "0xde74eef3cfb2dbc8d08a6838a1dcea4a6d775f77",
"gasUsed": "0x752b",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000100000400000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000002000000500000000000004000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
"transactionIndex": "0xc",
"type": "0x0"
}
1 change: 1 addition & 0 deletions ethers-core/testdata/receipt-17451262-2.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
02f9043a018308381ab9010000208020000000000000000080000000000020000000000000000000000000000000000000000000000000000000000002000000080000000000000000000000000000080000000000000008000003200000000000000000000000008020000000000400000000000000100000000000000000000000000000000010000000000000000080000008000000000000200000000001000000080000004000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000200000000000000000200000010000001000000000400000000000000000f9032ff87a94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a0e1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109ca00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada000000000000000000000000000000000000000000000000000470de4df820000f89b94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada0000000000000000000000000817d342132d79cebfd6303e87558d6599f3c3a8ba000000000000000000000000000000000000000000000000000470de4df820000f89b9401f6f4d612649741c895c1dacdbc98f359594d43f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0000000000000000000000000817d342132d79cebfd6303e87558d6599f3c3a8ba0000000000000000000000000018862eb5b3d719016cd6542c81cfce24a6ad16ca0000000000000000000000000000000000000000000000000043de1c6e853f335f87994817d342132d79cebfd6303e87558d6599f3c3a8be1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840000000000000000000000000000000000000000000000000007c67812d65755b000000000000000000000000000000000000000000000000004f2b9257986353f8fc94817d342132d79cebfd6303e87558d6599f3c3a8bf863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822a00000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fada0000000000000000000000000018862eb5b3d719016cd6542c81cfce24a6ad16cb880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000043de1c6e853f3350000000000000000000000000000000000000000000000000000000000000000
89 changes: 89 additions & 0 deletions ethers-core/testdata/receipt-17451262-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"logs": [
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x00000000000000000000000000000000000000000000000000470de4df820000",
"logIndex": "0x10",
"removed": false,
"topics": [
"0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c",
"0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"
],
"transactionIndex": "0x2"
},
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x00000000000000000000000000000000000000000000000000470de4df820000",
"logIndex": "0x11",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad",
"0x000000000000000000000000817d342132d79cebfd6303e87558d6599f3c3a8b"
],
"transactionIndex": "0x2"
},
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"address": "0x01f6f4d612649741c895c1dacdbc98f359594d43",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x000000000000000000000000000000000000000000000000043de1c6e853f335",
"logIndex": "0x12",
"removed": false,
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000817d342132d79cebfd6303e87558d6599f3c3a8b",
"0x000000000000000000000000018862eb5b3d719016cd6542c81cfce24a6ad16c"
],
"transactionIndex": "0x2"
},
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"address": "0x817d342132d79cebfd6303e87558d6599f3c3a8b",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x000000000000000000000000000000000000000000000000007c67812d65755b000000000000000000000000000000000000000000000000004f2b9257986353",
"logIndex": "0x13",
"removed": false,
"topics": [
"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"
],
"transactionIndex": "0x2"
},
{
"transactionHash": "0x5524a0af14b83f8900b50d08dea2332df23d367f1541268b943e4c588418f8b3",
"address": "0x817d342132d79cebfd6303e87558d6599f3c3a8b",
"blockHash": "0xf0bc137c355238b0e075507ba17456aff47ee376cea24c590d5b044705cb5877",
"blockNumber": "0x10a48fe",
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000470de4df820000000000000000000000000000000000000000000000000000043de1c6e853f3350000000000000000000000000000000000000000000000000000000000000000",
"logIndex": "0x14",
"removed": false,
"topics": [
"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822",
"0x0000000000000000000000003fc91a3afd70395cd496c647d5a6cc9d4b2b7fad",
"0x000000000000000000000000018862eb5b3d719016cd6542c81cfce24a6ad16c"
],
"transactionIndex": "0x2"
}
],
"contractAddress": null,
"effectiveGasPrice": "0x4773283b3",
"cumulativeGasUsed": "0x8381a",
"from": "0x018862eb5b3d719016cd6542c81cfce24a6ad16c",
"gasUsed": "0x1f5f6",
"logsBloom": "0x00208020000000000000000080000000000020000000000000000000000000000000000000000000000000000000000002000000080000000000000000000000000000080000000000000008000003200000000000000000000000008020000000000400000000000000100000000000000000000000000000000010000000000000000080000008000000000000200000000001000000080000004000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000001000000000000000000000200000000000000000200000010000001000000000400000000000000000",
"status": "0x1",
"to": "0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad",
"transactionIndex": "0x2",
"type": "0x2"
}
Loading

0 comments on commit 9f6c101

Please sign in to comment.