From 6ea36d14940a19f638512556ccc4c5127150b5c9 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 11 Nov 2024 17:30:33 +0700 Subject: [PATCH] feat(api-server): add `yParity` for non-legacy txs (#3246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Closes #3245 ## Why ❔ See #3245 for more details. TLDR better compatibility with ETH spec. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/lib/dal/src/models/storage_transaction.rs | 8 ++++++++ core/lib/types/src/api/mod.rs | 3 +++ core/lib/types/src/l2/mod.rs | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/core/lib/dal/src/models/storage_transaction.rs b/core/lib/dal/src/models/storage_transaction.rs index 459a3ec0c0fb..b55126800cce 100644 --- a/core/lib/dal/src/models/storage_transaction.rs +++ b/core/lib/dal/src/models/storage_transaction.rs @@ -541,6 +541,13 @@ impl StorageApiTransaction { .or_else(|| self.max_fee_per_gas.clone()) .unwrap_or_else(BigDecimal::zero), }; + // Legacy transactions are not supposed to have `yParity` and are reliant on `v` instead. + // Other transactions are required to have `yParity` which replaces the deprecated `v` value + // (still included for backwards compatibility). + let y_parity = match self.tx_format { + None | Some(0) => None, + _ => signature.as_ref().map(|s| U64::from(s.v())), + }; let mut tx = api::Transaction { hash: H256::from_slice(&self.tx_hash), nonce: U256::from(self.nonce.unwrap_or(0) as u64), @@ -553,6 +560,7 @@ impl StorageApiTransaction { gas_price: Some(bigdecimal_to_u256(gas_price)), gas: bigdecimal_to_u256(self.gas_limit.unwrap_or_else(BigDecimal::zero)), input: serde_json::from_value(self.calldata).expect("incorrect calldata in Postgres"), + y_parity, v: signature.as_ref().map(|s| U64::from(s.v())), r: signature.as_ref().map(|s| U256::from(s.r())), s: signature.as_ref().map(|s| U256::from(s.s())), diff --git a/core/lib/types/src/api/mod.rs b/core/lib/types/src/api/mod.rs index 409dc3727570..5f81e889b537 100644 --- a/core/lib/types/src/api/mod.rs +++ b/core/lib/types/src/api/mod.rs @@ -515,6 +515,9 @@ pub struct Transaction { pub gas: U256, /// Input data pub input: Bytes, + /// The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature + #[serde(rename = "yParity", default, skip_serializing_if = "Option::is_none")] + pub y_parity: Option, /// ECDSA recovery id #[serde(default, skip_serializing_if = "Option::is_none")] pub v: Option, diff --git a/core/lib/types/src/l2/mod.rs b/core/lib/types/src/l2/mod.rs index 48e813e571d2..e7d582ab17a1 100644 --- a/core/lib/types/src/l2/mod.rs +++ b/core/lib/types/src/l2/mod.rs @@ -396,6 +396,13 @@ impl From for api::Transaction { } else { (None, None, None) }; + // Legacy transactions are not supposed to have `yParity` and are reliant on `v` instead. + // Other transactions are required to have `yParity` which replaces the deprecated `v` value + // (still included for backwards compatibility). + let y_parity = match tx.common_data.transaction_type { + TransactionType::LegacyTransaction => None, + _ => v, + }; Self { hash: tx.hash(), @@ -409,6 +416,7 @@ impl From for api::Transaction { max_fee_per_gas: Some(tx.common_data.fee.max_fee_per_gas), gas: tx.common_data.fee.gas_limit, input: Bytes(tx.execute.calldata), + y_parity, v, r, s,