diff --git a/crates/primitives/src/transaction/eip1559.rs b/crates/primitives/src/transaction/eip1559.rs index 3108c6e51e..ba3e18a6d2 100644 --- a/crates/primitives/src/transaction/eip1559.rs +++ b/crates/primitives/src/transaction/eip1559.rs @@ -64,6 +64,24 @@ pub struct TxEip1559 { } impl TxEip1559 { + /// Returns the effective gas price for the given `base_fee`. + pub fn effective_gas_price(&self, base_fee: Option) -> u128 { + match base_fee { + None => self.max_fee_per_gas, + Some(base_fee) => { + // if the tip is greater than the max priority fee per gas, set it to the max + // priority fee per gas + base fee + let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); + if tip > self.max_priority_fee_per_gas { + self.max_priority_fee_per_gas + base_fee as u128 + } else { + // otherwise return the max fee per gas + self.max_fee_per_gas + } + } + } + } + /// Calculates a heuristic for the in-memory size of the [TxEip1559] transaction. #[inline] pub fn size(&self) -> usize { diff --git a/crates/primitives/src/transaction/eip4844.rs b/crates/primitives/src/transaction/eip4844.rs index 34b43e19bb..f9da9b0970 100644 --- a/crates/primitives/src/transaction/eip4844.rs +++ b/crates/primitives/src/transaction/eip4844.rs @@ -63,7 +63,7 @@ pub struct TxEip4844 { /// Max fee per data gas /// - /// aka BlobFeeCap + /// aka BlobFeeCap or blobGasFeeCap pub max_fee_per_blob_gas: u128, /// Input has two uses depending if transaction is Create or Call (if `to` field is None or diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index d3f03e0820..a2d64517fc 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -79,139 +79,6 @@ pub enum Transaction { Eip4844(TxEip4844), } -impl Transaction { - /// This encodes the transaction _without_ the signature, and is only suitable for creating a - /// hash intended for signing. - pub fn encode_without_signature(&self, out: &mut dyn bytes::BufMut) { - Encodable::encode(self, out); - } - - /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating - /// hash that for eip2718 does not require rlp header - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn bytes::BufMut, - with_header: bool, - ) { - match self { - Transaction::Legacy(TxLegacy { chain_id, .. }) => { - // do nothing w/ with_header - let payload_length = - self.fields_len() + signature.payload_len_with_eip155_chain_id(*chain_id); - let header = Header { list: true, payload_length }; - header.encode(out); - self.encode_fields(out); - signature.encode_with_eip155_chain_id(out, *chain_id); - } - _ => { - let payload_length = self.fields_len() + signature.payload_len(); - if with_header { - Header { - list: false, - payload_length: 1 + length_of_length(payload_length) + payload_length, - } - .encode(out); - } - out.put_u8(self.tx_type() as u8); - let header = Header { list: true, payload_length }; - header.encode(out); - self.encode_fields(out); - signature.encode(out); - } - } - } - - /// This sets the transaction's nonce. - pub fn set_nonce(&mut self, nonce: u64) { - match self { - Transaction::Legacy(tx) => tx.nonce = nonce, - Transaction::Eip2930(tx) => tx.nonce = nonce, - Transaction::Eip1559(tx) => tx.nonce = nonce, - Transaction::Eip4844(tx) => tx.nonce = nonce, - } - } - - /// This sets the transaction's value. - pub fn set_value(&mut self, value: u128) { - match self { - Transaction::Legacy(tx) => tx.value = value, - Transaction::Eip2930(tx) => tx.value = value, - Transaction::Eip1559(tx) => tx.value = value, - Transaction::Eip4844(tx) => tx.value = value, - } - } - - /// This sets the transaction's input field. - pub fn set_input(&mut self, input: Bytes) { - match self { - Transaction::Legacy(tx) => tx.input = input, - Transaction::Eip2930(tx) => tx.input = input, - Transaction::Eip1559(tx) => tx.input = input, - Transaction::Eip4844(tx) => tx.input = input, - } - } - - /// Calculates a heuristic for the in-memory size of the [Transaction]. - #[inline] - fn size(&self) -> usize { - match self { - Transaction::Legacy(tx) => tx.size(), - Transaction::Eip2930(tx) => tx.size(), - Transaction::Eip1559(tx) => tx.size(), - Transaction::Eip4844(tx) => tx.size(), - } - } -} - -impl Compact for Transaction { - fn to_compact(self, buf: &mut B) -> usize - where - B: bytes::BufMut + AsMut<[u8]>, - { - match self { - Transaction::Legacy(tx) => { - tx.to_compact(buf); - 0 - } - Transaction::Eip2930(tx) => { - tx.to_compact(buf); - 1 - } - Transaction::Eip1559(tx) => { - tx.to_compact(buf); - 2 - } - Transaction::Eip4844(tx) => { - tx.to_compact(buf); - 3 - } - } - } - - fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) { - match identifier { - 0 => { - let (tx, buf) = TxLegacy::from_compact(buf, buf.len()); - (Transaction::Legacy(tx), buf) - } - 1 => { - let (tx, buf) = TxEip2930::from_compact(buf, buf.len()); - (Transaction::Eip2930(tx), buf) - } - 2 => { - let (tx, buf) = TxEip1559::from_compact(buf, buf.len()); - (Transaction::Eip1559(tx), buf) - } - 3 => { - let (tx, buf) = TxEip4844::from_compact(buf, buf.len()); - (Transaction::Eip4844(tx), buf) - } - _ => unreachable!("Junk data in database: unknown Transaction variant"), - } - } -} - // === impl Transaction === impl Transaction { @@ -326,6 +193,20 @@ impl Transaction { } } + /// Max fee per blob gas for eip4844 transaction [TxEip4844]. + /// + /// Returns `None` for non-eip4844 transactions. + /// + /// This is also commonly referred to as the "Blob Gas Fee Cap" (`BlobGasFeeCap`). + pub fn max_fee_per_blob_gas(&self) -> Option { + match self { + Transaction::Eip4844(TxEip4844 { max_fee_per_blob_gas, .. }) => { + Some(*max_fee_per_blob_gas) + } + _ => None, + } + } + /// Return the max priority fee per gas if the transaction is an EIP-1559 transaction, and /// otherwise return the gas price. /// @@ -621,6 +502,137 @@ impl Transaction { } } } + + /// This encodes the transaction _without_ the signature, and is only suitable for creating a + /// hash intended for signing. + pub fn encode_without_signature(&self, out: &mut dyn bytes::BufMut) { + Encodable::encode(self, out); + } + + /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating + /// hash that for eip2718 does not require rlp header + pub fn encode_with_signature( + &self, + signature: &Signature, + out: &mut dyn bytes::BufMut, + with_header: bool, + ) { + match self { + Transaction::Legacy(TxLegacy { chain_id, .. }) => { + // do nothing w/ with_header + let payload_length = + self.fields_len() + signature.payload_len_with_eip155_chain_id(*chain_id); + let header = Header { list: true, payload_length }; + header.encode(out); + self.encode_fields(out); + signature.encode_with_eip155_chain_id(out, *chain_id); + } + _ => { + let payload_length = self.fields_len() + signature.payload_len(); + if with_header { + Header { + list: false, + payload_length: 1 + length_of_length(payload_length) + payload_length, + } + .encode(out); + } + out.put_u8(self.tx_type() as u8); + let header = Header { list: true, payload_length }; + header.encode(out); + self.encode_fields(out); + signature.encode(out); + } + } + } + + /// This sets the transaction's nonce. + pub fn set_nonce(&mut self, nonce: u64) { + match self { + Transaction::Legacy(tx) => tx.nonce = nonce, + Transaction::Eip2930(tx) => tx.nonce = nonce, + Transaction::Eip1559(tx) => tx.nonce = nonce, + Transaction::Eip4844(tx) => tx.nonce = nonce, + } + } + + /// This sets the transaction's value. + pub fn set_value(&mut self, value: u128) { + match self { + Transaction::Legacy(tx) => tx.value = value, + Transaction::Eip2930(tx) => tx.value = value, + Transaction::Eip1559(tx) => tx.value = value, + Transaction::Eip4844(tx) => tx.value = value, + } + } + + /// This sets the transaction's input field. + pub fn set_input(&mut self, input: Bytes) { + match self { + Transaction::Legacy(tx) => tx.input = input, + Transaction::Eip2930(tx) => tx.input = input, + Transaction::Eip1559(tx) => tx.input = input, + Transaction::Eip4844(tx) => tx.input = input, + } + } + + /// Calculates a heuristic for the in-memory size of the [Transaction]. + #[inline] + fn size(&self) -> usize { + match self { + Transaction::Legacy(tx) => tx.size(), + Transaction::Eip2930(tx) => tx.size(), + Transaction::Eip1559(tx) => tx.size(), + Transaction::Eip4844(tx) => tx.size(), + } + } +} + +impl Compact for Transaction { + fn to_compact(self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + match self { + Transaction::Legacy(tx) => { + tx.to_compact(buf); + 0 + } + Transaction::Eip2930(tx) => { + tx.to_compact(buf); + 1 + } + Transaction::Eip1559(tx) => { + tx.to_compact(buf); + 2 + } + Transaction::Eip4844(tx) => { + tx.to_compact(buf); + 3 + } + } + } + + fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) { + match identifier { + 0 => { + let (tx, buf) = TxLegacy::from_compact(buf, buf.len()); + (Transaction::Legacy(tx), buf) + } + 1 => { + let (tx, buf) = TxEip2930::from_compact(buf, buf.len()); + (Transaction::Eip2930(tx), buf) + } + 2 => { + let (tx, buf) = TxEip1559::from_compact(buf, buf.len()); + (Transaction::Eip1559(tx), buf) + } + 3 => { + let (tx, buf) = TxEip4844::from_compact(buf, buf.len()); + (Transaction::Eip4844(tx), buf) + } + _ => unreachable!("Junk data in database: unknown Transaction variant"), + } + } } impl Default for Transaction { @@ -664,26 +676,6 @@ impl Encodable for Transaction { } } -impl TxEip1559 { - /// Returns the effective gas price for the given `base_fee`. - pub fn effective_gas_price(&self, base_fee: Option) -> u128 { - match base_fee { - None => self.max_fee_per_gas, - Some(base_fee) => { - // if the tip is greater than the max priority fee per gas, set it to the max - // priority fee per gas + base fee - let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); - if tip > self.max_priority_fee_per_gas { - self.max_priority_fee_per_gas + base_fee as u128 - } else { - // otherwise return the max fee per gas - self.max_fee_per_gas - } - } - } - } -} - /// Whether or not the transaction is a contract creation. #[derive_arbitrary(compact, rlp)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]