fix: fix deploy tx RLP decoding (#1124)

* fix: fix deploy tx RLP decoding

* refactor: move duplicate RLP code into helper function
This commit is contained in:
Jonathan LEI 2022-04-09 01:58:26 +08:00 committed by GitHub
parent 69bf6ddd0c
commit bf4aa42884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 9 deletions

View File

@ -1,4 +1,4 @@
use super::{eip2930::AccessList, normalize_v, rlp_opt}; use super::{decode_to, eip2930::AccessList, normalize_v, rlp_opt};
use crate::{ use crate::{
types::{Address, Bytes, NameOrAddress, Signature, Transaction, H256, U256, U64}, types::{Address, Bytes, NameOrAddress, Signature, Transaction, H256, U256, U64},
utils::keccak256, utils::keccak256,
@ -199,8 +199,7 @@ impl Eip1559TransactionRequest {
*offset += 1; *offset += 1;
self.gas = Some(rlp.val_at(*offset)?); self.gas = Some(rlp.val_at(*offset)?);
*offset += 1; *offset += 1;
self.to = Some(rlp.val_at(*offset)?); self.to = decode_to(rlp, offset)?;
*offset += 1;
self.value = Some(rlp.val_at(*offset)?); self.value = Some(rlp.val_at(*offset)?);
*offset += 1; *offset += 1;
let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?;

View File

@ -455,4 +455,12 @@ mod tests {
let decoded_transaction = TypedTransaction::decode(&expected_rlp).unwrap(); let decoded_transaction = TypedTransaction::decode(&expected_rlp).unwrap();
assert_eq!(tx.sighash(), decoded_transaction.sighash()); assert_eq!(tx.sighash(), decoded_transaction.sighash());
} }
#[test]
fn test_eip1559_deploy_tx_decode() {
let typed_tx_hex =
hex::decode("02dc8205058193849502f90085010c388d00837a120080808411223344c0").unwrap();
let tx_rlp = rlp::Rlp::new(typed_tx_hex.as_slice());
TypedTransaction::decode(&tx_rlp).unwrap();
}
} }

View File

@ -1,4 +1,4 @@
use super::{normalize_v, request::TransactionRequest}; use super::{decode_to, normalize_v, request::TransactionRequest};
use crate::types::{Address, Bytes, Signature, Transaction, H256, U256, U64}; use crate::types::{Address, Bytes, Signature, Transaction, H256, U256, U64};
use rlp::{Decodable, DecoderError, RlpStream}; use rlp::{Decodable, DecoderError, RlpStream};
@ -117,8 +117,7 @@ impl Eip2930TransactionRequest {
self.tx.gas = Some(rlp.val_at(*offset)?); self.tx.gas = Some(rlp.val_at(*offset)?);
*offset += 1; *offset += 1;
self.tx.to = Some(rlp.val_at(*offset)?); self.tx.to = decode_to(rlp, offset)?;
*offset += 1;
self.tx.value = Some(rlp.val_at(*offset)?); self.tx.value = Some(rlp.val_at(*offset)?);
*offset += 1; *offset += 1;
let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?; let data = rlp::Rlp::new(rlp.at(*offset)?.as_raw()).data()?;

View File

@ -60,6 +60,30 @@ fn decode_signature(
Ok(sig) Ok(sig)
} }
/// Decodes the `to` field of the RLP encoding based on the RLP offset passed. Increments the offset
/// by one.
#[inline]
fn decode_to(
rlp: &rlp::Rlp,
offset: &mut usize,
) -> Result<Option<super::NameOrAddress>, rlp::DecoderError> {
let to = {
let to = rlp.at(*offset)?;
if to.is_empty() {
if to.is_data() {
None
} else {
return Err(rlp::DecoderError::RlpExpectedToBeData)
}
} else {
Some(to.as_val()?)
}
};
*offset += 1;
Ok(to)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::types::{transaction::rlp_opt, U64}; use crate::types::{transaction::rlp_opt, U64};

View File

@ -1,5 +1,5 @@
//! Transaction types //! Transaction types
use super::{extract_chain_id, rlp_opt, NUM_TX_FIELDS}; use super::{decode_to, extract_chain_id, rlp_opt, NUM_TX_FIELDS};
use crate::{ use crate::{
types::{Address, Bytes, NameOrAddress, Signature, Transaction, H256, U256, U64}, types::{Address, Bytes, NameOrAddress, Signature, Transaction, H256, U256, U64},
utils::keccak256, utils::keccak256,
@ -217,8 +217,7 @@ impl TransactionRequest {
*offset += 1; *offset += 1;
} }
txn.to = Some(rlp.at(*offset)?.as_val()?); txn.to = decode_to(rlp, offset)?;
*offset += 1;
txn.value = Some(rlp.at(*offset)?.as_val()?); txn.value = Some(rlp.at(*offset)?.as_val()?);
*offset += 1; *offset += 1;