Skip to content
Merged
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
44 changes: 42 additions & 2 deletions crates/primitives/src/transaction/morph_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ pub const MAX_MEMO_LENGTH: usize = 64;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct MorphTxFields {
#[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))]
pub version: u8,
#[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))]
pub fee_token_id: u16,
#[cfg_attr(feature = "serde", serde(default))]
pub fee_limit: U256,
#[cfg_attr(
feature = "serde",
Expand Down Expand Up @@ -109,16 +112,17 @@ pub struct TxMorph {

/// Version of the Morph transaction format.
/// Used for future extensibility.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))]
pub version: u8,

/// Token ID for alternative fee payment.
/// This corresponds to the token registered in the L2 Token Registry.
/// 0 means ETH payment, > 0 means ERC20 token payment.
#[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
#[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))]
pub fee_token_id: u16,

/// Maximum amount of tokens the sender is willing to pay as fee.
#[cfg_attr(feature = "serde", serde(default))]
pub fee_limit: U256,
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// Reference key for the transaction (optional, v1 only).
Expand Down Expand Up @@ -2070,4 +2074,40 @@ mod tests {
assert_eq!(decoded_signed.tx().memo, None);
assert!(decoded_signed.tx().is_v0());
}

#[cfg(feature = "serde")]
#[test]
fn test_tx_morph_serde_defaults_for_legacy_fields() {
// Legacy V0 JSON that omits version, feeTokenId, and feeLimit.
let json = r#"{
"chainId": "0x1",
"nonce": "0x0",
"gasLimit": "0x5208",
"maxFeePerGas": "0x64",
"maxPriorityFeePerGas": "0x1",
"to": "0x0000000000000000000000000000000000000002",
"value": "0x0",
"accessList": [],
"input": "0x"
}"#;

let tx: TxMorph = serde_json::from_str(json).unwrap();
assert_eq!(tx.version, MORPH_TX_VERSION_0);
assert_eq!(tx.fee_token_id, 0);
assert_eq!(tx.fee_limit, U256::ZERO);
}

#[cfg(feature = "serde")]
#[test]
fn test_morph_tx_fields_serde_defaults_for_legacy_fields() {
// MorphTxFields should also accept JSON with omitted fields.
let json = r#"{}"#;

let fields: MorphTxFields = serde_json::from_str(json).unwrap();
assert_eq!(fields.version, 0);
assert_eq!(fields.fee_token_id, 0);
assert_eq!(fields.fee_limit, U256::ZERO);
assert_eq!(fields.reference, None);
assert_eq!(fields.memo, None);
}
}