Skip to content

Commit

Permalink
Add more test
Browse files Browse the repository at this point in the history
  • Loading branch information
sudo-shashank committed Oct 17, 2024
1 parent e455c30 commit cab7997
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 71 deletions.
21 changes: 21 additions & 0 deletions src/eth/eip_1559_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//! This module contains the logic for EIP-1559 transaction types.
//! Constants are taken from [FIP-0091](https://github.com/filecoin-project/FIPs/blob/020bcb412ee20a2879b4a710337959c51b938d3b/FIPS/fip-0091.md).

use crate::message::SignedMessage;
use crate::shim::address::Address;
use crate::shim::crypto::SignatureType::Delegated;
use anyhow::bail;
use anyhow::ensure;
Expand Down Expand Up @@ -137,6 +139,25 @@ impl EthEip1559TxArgs {
.finalize_unbounded_list();
Ok(stream.out().to_vec())
}

pub fn get_signed_message(&self, from: Address) -> anyhow::Result<SignedMessage> {
ensure!(self.chain_id != EIP155_CHAIN_ID, "Invalid chain id");
let method_info = get_filecoin_method_info(&self.to, &self.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: self.nonce,
value: self.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: self.gas_limit,
gas_fee_cap: self.max_fee_per_gas.clone().into(),
gas_premium: self.max_priority_fee_per_gas.clone().into(),
};
let signature = self.signature()?;
Ok(SignedMessage { message, signature })
}
}

impl EthEip1559TxArgsBuilder {
Expand Down
24 changes: 24 additions & 0 deletions src/eth/eip_155_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use crate::message::SignedMessage;
use crate::shim::address::Address;
use crate::shim::crypto::SignatureType::Delegated;
use anyhow::{bail, ensure, Context};
use derive_builder::Builder;
Expand Down Expand Up @@ -231,6 +233,28 @@ impl EthLegacyEip155TxArgs {
.finalize_unbounded_list();
Ok(stream.out().to_vec())
}

pub fn get_signed_message(&self, from: Address) -> anyhow::Result<SignedMessage> {
ensure!(
validate_eip155_chain_id(EIP155_CHAIN_ID, &self.v).is_ok(),
"Failed to validate EIP155 chain Id"
);
let method_info = get_filecoin_method_info(&self.to, &self.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: self.nonce,
value: self.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: self.gas_limit,
gas_fee_cap: self.gas_price.clone().into(),
gas_premium: self.gas_price.clone().into(),
};
let signature = self.signature()?;
Ok(SignedMessage { message, signature })
}
}

impl EthLegacyEip155TxArgsBuilder {
Expand Down
20 changes: 20 additions & 0 deletions src/eth/homestead_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use crate::message::SignedMessage;
use crate::shim::address::Address;
use crate::shim::crypto::SignatureType::Delegated;
use anyhow::{bail, ensure, Context};
use derive_builder::Builder;
Expand Down Expand Up @@ -186,6 +188,24 @@ impl EthLegacyHomesteadTxArgs {
.finalize_unbounded_list();
Ok(stream.out().to_vec())
}

pub fn get_signed_message(&self, from: Address) -> anyhow::Result<SignedMessage> {
let method_info = get_filecoin_method_info(&self.to, &self.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: self.nonce,
value: self.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: self.gas_limit,
gas_fee_cap: self.gas_price.clone().into(),
gas_premium: self.gas_price.clone().into(),
};
let signature = self.signature()?;
Ok(SignedMessage { message, signature })
}
}

impl EthLegacyHomesteadTxArgsBuilder {
Expand Down
148 changes: 77 additions & 71 deletions src/eth/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{
eip_1559_transaction::{EthEip1559TxArgs, EthEip1559TxArgsBuilder, EIP_1559_SIG_LEN},
eip_155_transaction::{
calc_valid_eip155_sig_len, EthLegacyEip155TxArgs, EthLegacyEip155TxArgsBuilder,
EIP155_CHAIN_ID, EIP_155_SIG_PREFIX,
EIP_155_SIG_PREFIX,
},
homestead_transaction::{
EthLegacyHomesteadTxArgs, EthLegacyHomesteadTxArgsBuilder, HOMESTEAD_SIG_LEN,
Expand Down Expand Up @@ -114,62 +114,9 @@ impl EthTx {
pub fn get_signed_message(&self) -> anyhow::Result<SignedMessage> {
let from = self.sender()?;
let msg = match self {
Self::Homestead(tx) => {
let method_info = get_filecoin_method_info(&tx.to, &tx.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: tx.nonce,
value: tx.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: tx.gas_limit,
gas_fee_cap: tx.gas_price.clone().into(),
gas_premium: tx.gas_price.clone().into(),
};
let signature = tx.signature()?;
SignedMessage { message, signature }
}
Self::Eip1559(tx) => {
ensure!(tx.chain_id != EIP155_CHAIN_ID, "Invalid chain id");
let method_info = get_filecoin_method_info(&tx.to, &tx.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: tx.nonce,
value: tx.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: tx.gas_limit,
gas_fee_cap: tx.max_fee_per_gas.clone().into(),
gas_premium: tx.max_priority_fee_per_gas.clone().into(),
};
let signature = tx.signature()?;
SignedMessage { message, signature }
}
Self::Eip155(tx) => {
ensure!(
validate_eip155_chain_id(EIP155_CHAIN_ID, &tx.v).is_ok(),
"Failed to validate EIP155 chain Id"
);
let method_info = get_filecoin_method_info(&tx.to, &tx.input)?;
let message = Message {
version: 0,
from,
to: method_info.to,
sequence: tx.nonce,
value: tx.value.clone().into(),
method_num: method_info.method,
params: method_info.params.into(),
gas_limit: tx.gas_limit,
gas_fee_cap: tx.gas_price.clone().into(),
gas_premium: tx.gas_price.clone().into(),
};
let signature = tx.signature()?;
SignedMessage { message, signature }
}
Self::Homestead(tx) => (*tx).get_signed_message(from)?,
Self::Eip1559(tx) => (*tx).get_signed_message(from)?,
Self::Eip155(tx) => (*tx).get_signed_message(from)?,
};
Ok(msg)
}
Expand Down Expand Up @@ -229,7 +176,7 @@ impl EthTx {
Ok(())
}

pub fn sender(&self) -> anyhow::Result<Address> {
fn sender(&self) -> anyhow::Result<Address> {
let hash = keccak_hash::keccak(self.rlp_unsigned_message()?);
let sig = self.signature()?;
let sig_data = self.to_verifiable_signature(sig.bytes().to_vec())?[..]
Expand Down Expand Up @@ -486,9 +433,9 @@ fn parse_legacy_tx(data: &[u8]) -> anyhow::Result<EthTx> {

#[derive(Debug)]
pub struct MethodInfo {
to: Address,
method: u64,
params: Vec<u8>,
pub to: Address,
pub method: u64,
pub params: Vec<u8>,
}

pub fn get_filecoin_method_info(
Expand Down Expand Up @@ -904,6 +851,75 @@ pub(crate) mod tests {
}
}

#[test]
fn test_pad_leading_zeros() {
// Case 1: Data is shorter than the target length
let data = vec![1, 2, 3];
let padded = pad_leading_zeros(&data, 5);
assert_eq!(padded, vec![0, 0, 1, 2, 3]);

// Case 2: Data is already the target length
let data = vec![4, 5, 6];
let padded = pad_leading_zeros(&data, 3);
assert_eq!(padded, vec![4, 5, 6]);

// Case 3: Data is longer than the target length (no padding should happen)
let data = vec![7, 8, 9, 10];
let padded = pad_leading_zeros(&data, 3); // length is smaller
assert_eq!(padded, vec![7, 8, 9, 10]); // Should return unchanged

// Case 4: Data is empty, and the target length is greater than zero
let data = vec![];
let padded = pad_leading_zeros(&data, 4);
assert_eq!(padded, vec![0, 0, 0, 0]);
}

#[test]
fn test_parse_eth_transaction() {
// Legacy transaction
let raw_tx = hex::decode(
"f8cc04830406968419ca81cc94d0fb381fc644cdd5d694d35e1afb445527b9244b80b864d5b3d76d00000000000000000000000000000000000000000000000045466fa6fdcb80000000000000000000000000000000000000000000000000000000002e90edd000000000000000000000000000000000000000000000000000000000000001518083099681a0580b1d36c5a8c8c1c550fb45b0a6ff21aaa517be036385541621961b5d873796a055e8447d58d64ebc3038d9882886bbc3b0228c7ac77c71f4e811b97ed3f14b5a",
)
.expect("Invalid hex");
let eth_tx = parse_eth_transaction(&raw_tx);
assert!(eth_tx.is_ok());

// EIP-1559 transaction
let raw_tx = hex::decode(
"02f901368304cb2f8201e68459682f008459682f7884023b53a794eb4a9cdb9f42d3a503d580a39b6e3736eb21fffd80b8c4383487be000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000660d4d120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003b6261666b726569656f6f75326d36356276376561786e7767656d7562723675787269696867366474646e6c7a663469616f37686c6e6a6d647372750000000000c001a0b9f0afb3fa8821fa414bac6056e613c61a8263ca341b59539096dbbc8600f530a0114a6a032347e132f115accc7664ccc61549be28f5b844c3fc170006feb72f24",
)
.expect("Invalid hex");
let eth_tx = parse_eth_transaction(&raw_tx);
assert!(eth_tx.is_ok());
}

#[test]
fn test_derive_sender() {
// Legacy transaction
let raw_tx = hex::decode(
"f8cc04830406968419ca81cc94d0fb381fc644cdd5d694d35e1afb445527b9244b80b864d5b3d76d00000000000000000000000000000000000000000000000045466fa6fdcb80000000000000000000000000000000000000000000000000000000002e90edd000000000000000000000000000000000000000000000000000000000000001518083099681a0580b1d36c5a8c8c1c550fb45b0a6ff21aaa517be036385541621961b5d873796a055e8447d58d64ebc3038d9882886bbc3b0228c7ac77c71f4e811b97ed3f14b5a",
)
.expect("Invalid hex");
let eth_tx = parse_eth_transaction(&raw_tx).unwrap();
let from = eth_tx.sender().unwrap();
assert_eq!(
EthAddress::from_filecoin_address(&from).unwrap(),
EthAddress::from_str("0xEb1D0C87B7e33D0Ab44a397b675F0897295491C2").unwrap()
);

// EIP-1559 transaction
let raw_tx = hex::decode(
"02f901368304cb2f8201e68459682f008459682f7884023b53a794eb4a9cdb9f42d3a503d580a39b6e3736eb21fffd80b8c4383487be000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000660d4d120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000003b6261666b726569656f6f75326d36356276376561786e7767656d7562723675787269696867366474646e6c7a663469616f37686c6e6a6d647372750000000000c001a0b9f0afb3fa8821fa414bac6056e613c61a8263ca341b59539096dbbc8600f530a0114a6a032347e132f115accc7664ccc61549be28f5b844c3fc170006feb72f24",
)
.expect("Invalid hex");
let eth_tx = parse_eth_transaction(&raw_tx).unwrap();
let from = eth_tx.sender().unwrap();
assert_eq!(
EthAddress::from_filecoin_address(&from).unwrap(),
EthAddress::from_str("0x4fda4174D5D07C906395bfB77806287cc65Fd129").unwrap()
);
}

#[test]
fn test_parse_legacy_tx() {
// Raw transaction hex for a Legacy transaction
Expand All @@ -915,7 +931,6 @@ pub(crate) mod tests {
let result = parse_legacy_tx(&raw_tx);
assert!(result.is_ok());
let txn = result.unwrap();
let from = txn.sender().unwrap();

if let EthTx::Eip155(tx) = txn {
assert_eq!(tx.chain_id, 314159);
Expand All @@ -926,10 +941,6 @@ pub(crate) mod tests {
tx.to.unwrap(),
EthAddress::from_str("0xd0fb381fc644cdd5d694d35e1afb445527b9244b").unwrap()
);
assert_eq!(
EthAddress::from_filecoin_address(&from).unwrap(),
EthAddress::from_str("0xEb1D0C87B7e33D0Ab44a397b675F0897295491C2").unwrap()
);
assert_eq!(tx.value, BigInt::from(0));
assert_eq!(
tx.v,
Expand Down Expand Up @@ -967,7 +978,6 @@ pub(crate) mod tests {
assert!(result.is_ok());

let txn = result.unwrap();
let from = txn.sender().unwrap();

if let EthTx::Eip1559(tx) = txn {
assert_eq!(tx.chain_id, 314159);
Expand All @@ -979,10 +989,6 @@ pub(crate) mod tests {
tx.to.unwrap(),
EthAddress::from_str("0xeb4a9cdb9f42d3a503d580a39b6e3736eb21fffd").unwrap()
);
assert_eq!(
EthAddress::from_filecoin_address(&from).unwrap(),
EthAddress::from_str("0x4fda4174D5D07C906395bfB77806287cc65Fd129").unwrap()
);
assert_eq!(tx.value, BigInt::from(0));
assert_eq!(
tx.v,
Expand Down
17 changes: 17 additions & 0 deletions src/rpc/methods/eth/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,4 +463,21 @@ mod tests {
let params = EthCallMessage::convert_data_to_message_params(data).unwrap();
assert_eq!(BASE64_STANDARD.encode(&*params).as_str(), "RUR7eINB");
}

#[test]
fn test_eth_address_from_pub_key() {
// Uncompressed pub key secp256k1)
let pubkey: [u8; 65] = [
4, 75, 249, 118, 22, 83, 215, 249, 252, 54, 149, 27, 253, 35, 238, 15, 229, 8, 50, 228,
19, 137, 115, 123, 183, 243, 237, 144, 113, 41, 115, 70, 234, 174, 61, 199, 1, 81, 95,
143, 102, 246, 176, 220, 176, 93, 241, 139, 94, 105, 141, 153, 20, 74, 35, 52, 139,
137, 5, 220, 53, 194, 22, 85, 80,
];

let expected_eth_address =
EthAddress::from_str("0xeb1d0c87b7e33d0ab44a397b675f0897295491c2").unwrap();

let result = EthAddress::eth_address_from_pub_key(&pubkey).unwrap();
assert_eq!(result, expected_eth_address);
}
}

0 comments on commit cab7997

Please sign in to comment.