From 76305a0486256212f8ddddd97aac485e0f48136a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Wed, 4 Dec 2024 01:03:58 +0100 Subject: [PATCH 1/2] Correct web-client vesting contract data parsing Now takes the transaction's actual recipient data, instead of the internal representation of a vesting contract's `CreationTransactionData`. The internal representation uses `varints` for the serialization of the contract's `startTime` and `timeStep`, but the transaction recipient data doesn't. Since the transaction recipient data also has formats that doesn't include the contracts `totalAmount`, this field is required now to be passed to the parsing method. --- .../transaction/src/account/vesting_contract.rs | 4 ++-- web-client/src/common/vesting_contract.rs | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/primitives/transaction/src/account/vesting_contract.rs b/primitives/transaction/src/account/vesting_contract.rs index 9ac7325139..df03749f0a 100644 --- a/primitives/transaction/src/account/vesting_contract.rs +++ b/primitives/transaction/src/account/vesting_contract.rs @@ -114,7 +114,7 @@ struct CreationTransactionData32 { } impl CreationTransactionData { - fn parse_impl(data: &[u8], tx_value: Coin) -> Result { + pub fn parse_data(data: &[u8], tx_value: Coin) -> Result { Ok(match data.len() { CreationTransactionData8::SIZE => { // Only timestamp: vest full amount at that time @@ -163,7 +163,7 @@ impl CreationTransactionData { }) } pub fn parse(tx: &Transaction) -> Result { - CreationTransactionData::parse_impl(&tx.recipient_data, tx.value) + CreationTransactionData::parse_data(&tx.recipient_data, tx.value) } pub fn to_tx_data(&self) -> Vec { diff --git a/web-client/src/common/vesting_contract.rs b/web-client/src/common/vesting_contract.rs index b01300b4f8..71df54b64a 100644 --- a/web-client/src/common/vesting_contract.rs +++ b/web-client/src/common/vesting_contract.rs @@ -1,4 +1,4 @@ -use nimiq_serde::Deserialize; +use nimiq_primitives::coin::Coin; use nimiq_transaction::account::vesting_contract::CreationTransactionData; use wasm_bindgen::prelude::*; @@ -18,8 +18,11 @@ pub struct VestingContract; impl VestingContract { /// Parses the data of a Vesting Contract creation transaction into a plain object. #[wasm_bindgen(js_name = dataToPlain)] - pub fn data_to_plain(data: &[u8]) -> Result { - let plain = VestingContract::parse_data(data)?; + pub fn data_to_plain( + data: &[u8], + tx_value: u64, + ) -> Result { + let plain = VestingContract::parse_data(data, tx_value)?; Ok(serde_wasm_bindgen::to_value(&plain)?.into()) } @@ -32,8 +35,11 @@ impl VestingContract { } impl VestingContract { - pub fn parse_data(bytes: &[u8]) -> Result { - let data = CreationTransactionData::deserialize_all(bytes)?; + pub fn parse_data( + bytes: &[u8], + tx_value: u64, + ) -> Result { + let data = CreationTransactionData::parse_data(bytes, Coin::try_from(tx_value)?)?; Ok(PlainTransactionRecipientData::Vesting(PlainVestingData { raw: hex::encode(bytes), From d1e070a62935461633e6906f6d27a39b8eb99907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren?= Date: Wed, 4 Dec 2024 01:12:32 +0100 Subject: [PATCH 2/2] Verify that actual vesting creation data can be parsed --- primitives/transaction/tests/vesting_contract_verify.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/primitives/transaction/tests/vesting_contract_verify.rs b/primitives/transaction/tests/vesting_contract_verify.rs index 3060dffb4f..c745896362 100644 --- a/primitives/transaction/tests/vesting_contract_verify.rs +++ b/primitives/transaction/tests/vesting_contract_verify.rs @@ -39,6 +39,7 @@ fn it_can_verify_creation_transaction() { AccountType::verify_incoming_transaction(&transaction), Err(TransactionError::InvalidData) ); + CreationTransactionData::parse_data(&data, transaction.value).unwrap(); transaction.recipient_data = data; // Invalid recipient @@ -70,6 +71,7 @@ fn it_can_verify_creation_transaction() { Serialize::serialize_to_writer(&100u64.to_be_bytes(), &mut data); Serialize::serialize_to_writer(&100u64.to_be_bytes(), &mut data); Serialize::serialize_to_writer(&Coin::try_from(100).unwrap(), &mut data); + CreationTransactionData::parse_data(&data, transaction.value).unwrap(); transaction.recipient_data = data; transaction.recipient = transaction.contract_creation_address(); assert_eq!( @@ -85,6 +87,7 @@ fn it_can_verify_creation_transaction() { Serialize::serialize_to_writer(&100u64.to_be_bytes(), &mut data); Serialize::serialize_to_writer(&Coin::try_from(100).unwrap(), &mut data); Serialize::serialize_to_writer(&Coin::try_from(100).unwrap(), &mut data); + CreationTransactionData::parse_data(&data, transaction.value).unwrap(); transaction.recipient_data = data; transaction.recipient = transaction.contract_creation_address(); assert_eq!(