Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: impl From<Transaction> for TransactionRequest + small type updates #338

Merged
merged 7 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 46 additions & 18 deletions crates/rpc-types/src/eth/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::eth::other::OtherFields;
pub use access_list::{AccessList, AccessListItem, AccessListWithGasUsed};
use alloy_primitives::{Address, Bytes, B256, U128, U256, U64};
use alloy_primitives::{Address, Bytes, B256, U256, U8};
pub use blob::BlobTransactionSidecar;
pub use common::TransactionInfo;
pub use optimism::OptimismTransactionReceiptFields;
Expand Down Expand Up @@ -44,18 +44,18 @@ pub struct Transaction {
pub value: U256,
/// Gas Price
#[serde(skip_serializing_if = "Option::is_none")]
pub gas_price: Option<U128>,
pub gas_price: Option<U256>,
/// Gas amount
pub gas: U256,
/// Max BaseFeePerGas the user is willing to pay.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_fee_per_gas: Option<U128>,
pub max_fee_per_gas: Option<U256>,
/// The miner's tip.
#[serde(skip_serializing_if = "Option::is_none")]
pub max_priority_fee_per_gas: Option<U128>,
pub max_priority_fee_per_gas: Option<U256>,
/// Configured max fee per blob gas for eip-4844 transactions
#[serde(skip_serializing_if = "Option::is_none")]
pub max_fee_per_blob_gas: Option<U128>,
pub max_fee_per_blob_gas: Option<U256>,
mattsse marked this conversation as resolved.
Show resolved Hide resolved
/// Data
pub input: Bytes,
/// All _flattened_ fields of the transaction signature.
Expand All @@ -64,21 +64,22 @@ pub struct Transaction {
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub signature: Option<Signature>,
/// The chain id of the transaction, if any.
pub chain_id: Option<U64>,
#[serde(with = "alloy_serde::u64_hex_opt")]
pub chain_id: Option<u64>,
mattsse marked this conversation as resolved.
Show resolved Hide resolved
/// Contains the blob hashes for eip-4844 transactions.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub blob_versioned_hashes: Vec<B256>,
/// EIP2930
///
/// Pre-pay to warm storage access.
#[serde(skip_serializing_if = "Option::is_none")]
pub access_list: Option<Vec<AccessListItem>>,
pub access_list: Option<AccessList>,
/// EIP2718
///
/// Transaction type, Some(2) for EIP-1559 transaction,
/// Some(1) for AccessList transaction, None for Legacy
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub transaction_type: Option<U64>,
pub transaction_type: Option<U8>,

/// Arbitrary extra fields.
///
Expand All @@ -87,6 +88,33 @@ pub struct Transaction {
pub other: OtherFields,
}

impl Transaction {
/// Converts [Transaction] into [TransactionRequest].
///
/// During this conversion data for [TransactionRequest::sidecar] is not populated as it is not
/// part of [Transaction].
pub fn into_request(self) -> TransactionRequest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason we have this instead of just the auto-impl'd Into we get from From?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We wanted to have it documented on Transaction

Ref #338 (comment)

TransactionRequest {
from: Some(self.from),
to: self.to,
gas: Some(self.gas),
gas_price: self.gas_price,
value: Some(self.value),
input: self.input.into(),
nonce: Some(self.nonce),
chain_id: self.chain_id,
access_list: self.access_list,
transaction_type: self.transaction_type,
max_fee_per_gas: self.max_fee_per_gas,
max_priority_fee_per_gas: self.max_priority_fee_per_gas,
max_fee_per_blob_gas: self.max_fee_per_blob_gas,
blob_versioned_hashes: Some(self.blob_versioned_hashes),
sidecar: None,
other: OtherFields::default(),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -102,7 +130,7 @@ mod tests {
from: Address::with_last_byte(6),
to: Some(Address::with_last_byte(7)),
value: U256::from(8),
gas_price: Some(U128::from(9)),
gas_price: Some(U256::from(9)),
gas: U256::from(10),
input: Bytes::from(vec![11, 12, 13]),
signature: Some(Signature {
Expand All @@ -111,12 +139,12 @@ mod tests {
s: U256::from(14),
y_parity: None,
}),
chain_id: Some(U64::from(17)),
chain_id: Some(17),
blob_versioned_hashes: vec![],
access_list: None,
transaction_type: Some(U64::from(20)),
max_fee_per_gas: Some(U128::from(21)),
max_priority_fee_per_gas: Some(U128::from(22)),
transaction_type: Some(U8::from(20)),
max_fee_per_gas: Some(U256::from(21)),
max_priority_fee_per_gas: Some(U256::from(22)),
max_fee_per_blob_gas: None,
other: Default::default(),
};
Expand All @@ -140,7 +168,7 @@ mod tests {
from: Address::with_last_byte(6),
to: Some(Address::with_last_byte(7)),
value: U256::from(8),
gas_price: Some(U128::from(9)),
gas_price: Some(U256::from(9)),
gas: U256::from(10),
input: Bytes::from(vec![11, 12, 13]),
signature: Some(Signature {
Expand All @@ -149,12 +177,12 @@ mod tests {
s: U256::from(14),
y_parity: Some(Parity(true)),
}),
chain_id: Some(U64::from(17)),
chain_id: Some(17),
blob_versioned_hashes: vec![],
access_list: None,
transaction_type: Some(U64::from(20)),
max_fee_per_gas: Some(U128::from(21)),
max_priority_fee_per_gas: Some(U128::from(22)),
transaction_type: Some(U8::from(20)),
max_fee_per_gas: Some(U256::from(21)),
max_priority_fee_per_gas: Some(U256::from(22)),
max_fee_per_blob_gas: None,
other: Default::default(),
};
Expand Down
10 changes: 9 additions & 1 deletion crates/rpc-types/src/eth/transaction/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Alloy basic Transaction Request type.

use crate::{eth::transaction::AccessList, other::OtherFields, BlobTransactionSidecar};
use crate::{
eth::transaction::AccessList, other::OtherFields, BlobTransactionSidecar, Transaction,
};
use alloy_primitives::{Address, Bytes, ChainId, B256, U256, U8};
use serde::{Deserialize, Serialize};
use std::hash::Hash;
Expand Down Expand Up @@ -238,6 +240,12 @@ impl From<Option<Bytes>> for TransactionInput {
}
}

impl From<Transaction> for TransactionRequest {
fn from(tx: Transaction) -> TransactionRequest {
Comment on lines +243 to +244
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is definitely useful, for example,

eth_getTransaction
-> eth_call

so I think we want/need this.
The missing blob is also not problematic because this will be used mostly for calls.
and there's nothing we can do without the blob anyway

mattsse marked this conversation as resolved.
Show resolved Hide resolved
tx.into_request()
}
}

/// Error thrown when both `data` and `input` fields are set and not equal.
#[derive(Debug, Default, thiserror::Error)]
#[error("both \"data\" and \"input\" are set and not equal. Please use \"input\" to pass transaction call data")]
Expand Down
Loading