use serde::{Deserialize, Serialize};
use super::AccessList;
use crate::primitives::{Address, Bytes, U256};
#[cfg(feature = "rlp")]
use crate::{
errors::Result,
primitives::{Eip1559Signature, H256},
rlp::RlpEncoder,
};
#[cfg(feature = "rlp")]
use crate::primitives::keccak256;
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Eip1559TransactionRequest {
pub chain_id: U256,
pub nonce: U256,
pub max_priority_fee_per_gas: U256,
pub max_fee_per_gas: U256,
pub gas: U256,
#[serde(skip_serializing_if = "Option::is_none")]
pub to: Option<Address>,
pub value: Option<U256>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Bytes>,
pub access_list: AccessList,
}
#[cfg(feature = "rlp")]
#[cfg_attr(docsrs, doc(cfg(feature = "rlp")))]
impl Eip1559TransactionRequest {
pub fn sign_hash(&self) -> Result<H256> {
Ok(keccak256(self.rlp()?.0).into())
}
pub fn rlp(&self) -> Result<Bytes> {
let mut s = RlpEncoder::default();
(
&self.chain_id,
&self.nonce,
&self.max_priority_fee_per_gas,
&self.max_fee_per_gas,
&self.gas,
&self.to,
&self.value,
&self.data,
&self.access_list,
)
.serialize(&mut s)?;
let mut buff = vec![0x02u8];
let mut append = s.finalize()?.into();
buff.append(&mut append);
Ok(buff.into())
}
pub fn rlp_signed(&self, signature: Eip1559Signature) -> Result<Bytes> {
let mut s = RlpEncoder::default();
(
&self.chain_id,
&self.nonce,
&self.max_priority_fee_per_gas,
&self.max_fee_per_gas,
&self.gas,
&self.to,
&self.value,
&self.data,
&self.access_list,
signature.v,
signature.r,
signature.s,
)
.serialize(&mut s)?;
let mut buff = vec![0x02u8];
let mut append = s.finalize()?.into();
buff.append(&mut append);
Ok(buff.into())
}
}
#[cfg(feature = "rlp")]
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
fn test_rlp() {
let tx = json!({
"maxPriorityFeePerGas": "0x0",
"maxFeePerGas": "0x0",
"gas": "0x0",
"nonce": "0x0",
"to": null,
"value": "0x0",
"chainId": "0x1",
"type": "0x02",
"data": "0x00",
"accessList": [
{
"address": "0x0000000000000000000000000000000000000000",
"storageKeys": [
"0x0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"address": "0x0000000000000000000000000000000000000000",
"storageKeys": [
"0x0000000000000000000000000000000000000000000000000000000000000000"
]
}
]
});
let tx: Eip1559TransactionRequest = serde_json::from_value(tx).unwrap();
assert_eq!(
tx.rlp().unwrap().to_string(),
"0x02f87a0180808080808000f870f7940000000000000000000000000000000000000000e1a00000000000000000000000000000000000000000000000000000000000000000f7940000000000000000000000000000000000000000e1a00000000000000000000000000000000000000000000000000000000000000000"
);
let sig: Eip1559Signature = "0x007a53fb20b46d9cc2600d8dc3168a698d41c0dec029d46db4ba88ffe359bbe4092536bd58c593edcda36c5f2e35ed4db158b0cab202b6b2648403117e483a9b30".parse().unwrap();
assert_eq!(
tx.rlp_signed(sig).unwrap().to_string(),
"0x02f8bd0180808080808000f870f7940000000000000000000000000000000000000000e1a00000000000000000000000000000000000000000000000000000000000000000f7940000000000000000000000000000000000000000e1a0000000000000000000000000000000000000000000000000000000000000000080a07a53fb20b46d9cc2600d8dc3168a698d41c0dec029d46db4ba88ffe359bbe409a02536bd58c593edcda36c5f2e35ed4db158b0cab202b6b2648403117e483a9b30"
);
}
}