From 6efa7ca85f41d0f7dc28db1d308667b26557c1e8 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Sun, 18 Dec 2022 06:40:43 -0500 Subject: [PATCH] fix(core): decode to correctly in Transaction (#1946) * would not correctly decode a create transaction because 0x80 was not properly decoded --- ethers-core/src/types/transaction/eip1559.rs | 2 +- ethers-core/src/types/transaction/mod.rs | 2 +- ethers-core/src/types/transaction/request.rs | 2 +- ethers-core/src/types/transaction/response.rs | 35 ++++++++++++++----- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ethers-core/src/types/transaction/eip1559.rs b/ethers-core/src/types/transaction/eip1559.rs index ba080e19..ba937fe6 100644 --- a/ethers-core/src/types/transaction/eip1559.rs +++ b/ethers-core/src/types/transaction/eip1559.rs @@ -208,7 +208,7 @@ impl Eip1559TransactionRequest { *offset += 1; tx.gas = Some(rlp.val_at(*offset)?); *offset += 1; - tx.to = decode_to(rlp, offset)?; + tx.to = decode_to(rlp, offset)?.map(NameOrAddress::Address); tx.value = Some(rlp.val_at(*offset)?); *offset += 1; let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; diff --git a/ethers-core/src/types/transaction/mod.rs b/ethers-core/src/types/transaction/mod.rs index efe70780..816f4539 100644 --- a/ethers-core/src/types/transaction/mod.rs +++ b/ethers-core/src/types/transaction/mod.rs @@ -75,7 +75,7 @@ fn decode_signature( fn decode_to( rlp: &rlp::Rlp, offset: &mut usize, -) -> Result, rlp::DecoderError> { +) -> Result, rlp::DecoderError> { let to = { let to = rlp.at(*offset)?; if to.is_empty() { diff --git a/ethers-core/src/types/transaction/request.rs b/ethers-core/src/types/transaction/request.rs index f8be2627..d31d91bf 100644 --- a/ethers-core/src/types/transaction/request.rs +++ b/ethers-core/src/types/transaction/request.rs @@ -233,7 +233,7 @@ impl TransactionRequest { *offset += 1; } - txn.to = decode_to(rlp, offset)?; + txn.to = decode_to(rlp, offset)?.map(NameOrAddress::Address); txn.value = Some(rlp.at(*offset)?.as_val()?); *offset += 1; diff --git a/ethers-core/src/types/transaction/response.rs b/ethers-core/src/types/transaction/response.rs index 314caf0b..b29d6f99 100644 --- a/ethers-core/src/types/transaction/response.rs +++ b/ethers-core/src/types/transaction/response.rs @@ -1,7 +1,7 @@ //! Transaction types use super::{ - decode_signature, eip2718::TypedTransaction, eip2930::AccessList, normalize_v, rlp_opt, - rlp_opt_list, + decode_signature, decode_to, eip2718::TypedTransaction, eip2930::AccessList, normalize_v, + rlp_opt, rlp_opt_list, }; use crate::{ types::{ @@ -248,8 +248,7 @@ impl Transaction { *offset += 1; self.gas = rlp.val_at(*offset)?; *offset += 1; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -279,8 +278,7 @@ impl Transaction { #[cfg(feature = "celo")] self.decode_celo_metadata(rlp, offset)?; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -310,8 +308,7 @@ impl Transaction { #[cfg(feature = "celo")] self.decode_celo_metadata(rlp, offset)?; - self.to = Some(rlp.val_at(*offset)?); - *offset += 1; + self.to = decode_to(rlp, offset)?; self.value = rlp.val_at(*offset)?; *offset += 1; let input = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; @@ -473,7 +470,7 @@ impl PartialOrd for TransactionReceipt { #[cfg(test)] #[cfg(not(feature = "celo"))] mod tests { - use rlp::Encodable; + use rlp::{Encodable, Rlp}; use crate::types::transaction::eip2930::AccessListItem; @@ -1093,4 +1090,24 @@ mod tests { let r = rlp::Rlp::new(b.as_slice()); Transaction::decode(&r).unwrap(); } + + #[test] + fn test_rlp_decoding_create_roundtrip() { + let tx = Transaction { + block_hash: None, + block_number: None, + from: Address::from_str("c26ad91f4e7a0cad84c4b9315f420ca9217e315d").unwrap(), + gas: U256::from_str_radix("0x10e2b", 16).unwrap(), + gas_price: Some(U256::from_str_radix("0x12ec276caf", 16).unwrap()), + hash: H256::from_str("929ff27a5c7833953df23103c4eb55ebdfb698678139d751c51932163877fada").unwrap(), + input: Bytes::from( + hex::decode("a9059cbb000000000000000000000000fdae129ecc2c27d166a3131098bc05d143fa258e0000000000000000000000000000000000000000000000000000000002faf080").unwrap() + ), + nonce: U256::zero(), + transaction_index: None, + value: U256::zero(), + ..Default::default() + }; + Transaction::decode(&Rlp::new(&tx.rlp())).unwrap(); + } }