From 31bcdf4b654ead3880cec8bc38394939a086b5bf Mon Sep 17 00:00:00 2001 From: Thibault Martinez Date: Tue, 27 Feb 2024 15:08:01 +0100 Subject: [PATCH] Use TransactionFailureReason as semantic validation error (#2058) * Use TransactionFailureReason as semantic validation error * Adapt * nit * let it error * python * nodejs * Fix doc * remove if lets * stealer stealer --- bindings/core/src/method/utils.rs | 2 +- bindings/core/src/method_handler/utils.rs | 4 +- bindings/core/src/response.rs | 3 - bindings/nodejs/lib/utils/utils.ts | 7 +- bindings/python/iota_sdk/utils.py | 4 +- .../client/api/block_builder/transaction.rs | 10 +- sdk/src/client/error.rs | 2 +- sdk/src/client/secret/mod.rs | 11 +- sdk/src/types/block/error.rs | 11 ++ sdk/src/types/block/semantic/error.rs | 3 + sdk/src/types/block/semantic/mod.rs | 136 ++++++++++-------- sdk/src/wallet/operations/transaction/mod.rs | 4 +- sdk/tests/client/signing/account.rs | 12 +- sdk/tests/client/signing/basic.rs | 18 +-- sdk/tests/client/signing/delegation.rs | 56 ++++---- sdk/tests/client/signing/mod.rs | 6 +- sdk/tests/client/signing/nft.rs | 6 +- 17 files changed, 141 insertions(+), 154 deletions(-) diff --git a/bindings/core/src/method/utils.rs b/bindings/core/src/method/utils.rs index 243db233ba..706111a7d2 100644 --- a/bindings/core/src/method/utils.rs +++ b/bindings/core/src/method/utils.rs @@ -173,7 +173,7 @@ pub enum UtilsMethod { output: Output, }, /// Verifies the semantic of a transaction. - /// Expected response: [`TransactionFailureReason`](crate::Response::TransactionFailureReason) + /// Expected response: [`Ok`](crate::Response::Ok) #[serde(rename_all = "camelCase")] VerifyTransactionSemantic { transaction: TransactionDto, diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index edcf5d5f4e..414866b1b4 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -130,7 +130,9 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result), // Responses in client and wallet /// Response for: diff --git a/bindings/nodejs/lib/utils/utils.ts b/bindings/nodejs/lib/utils/utils.ts index 3dd0414cc7..25263e415f 100644 --- a/bindings/nodejs/lib/utils/utils.ts +++ b/bindings/nodejs/lib/utils/utils.ts @@ -559,7 +559,7 @@ export class Utils { * @param unlocks The unlocks. * @param manaRewards The total mana rewards claimed in the transaction. * - * @returns The conflict reason. + * @returns void. */ static verifyTransactionSemantic( transaction: SignedTransactionPayload, @@ -567,8 +567,8 @@ export class Utils { protocolParameters: ProtocolParameters, unlocks?: Unlock[], manaRewards?: { [outputId: HexEncodedString]: NumericString }, - ): string { - const conflictReason = callUtilsMethod({ + ): void { + return callUtilsMethod({ name: 'verifyTransactionSemantic', data: { transaction, @@ -578,7 +578,6 @@ export class Utils { manaRewards, }, }); - return conflictReason; } /** diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 88a3794717..08e68490c0 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -241,10 +241,10 @@ def verify_secp256k1_ecdsa_signature( @staticmethod def verify_transaction_semantic( - transaction: Transaction, inputs: List[InputSigningData], protocol_parameters: ProtocolParameters, unlocks: Optional[List[Unlock]] = None, mana_rewards: Optional[dict[OutputId, int]] = None) -> str: + transaction: Transaction, inputs: List[InputSigningData], protocol_parameters: ProtocolParameters, unlocks: Optional[List[Unlock]] = None, mana_rewards: Optional[dict[OutputId, int]] = None): """Verifies the semantic of a transaction. """ - return _call_method('verifyTransactionSemantic', { + _call_method('verifyTransactionSemantic', { 'transaction': transaction, 'inputs': inputs, 'unlocks': unlocks, diff --git a/sdk/src/client/api/block_builder/transaction.rs b/sdk/src/client/api/block_builder/transaction.rs index 9e9cedb501..e886255f96 100644 --- a/sdk/src/client/api/block_builder/transaction.rs +++ b/sdk/src/client/api/block_builder/transaction.rs @@ -8,7 +8,7 @@ use alloc::collections::BTreeMap; use packable::PackableExt; use crate::{ - client::{secret::types::InputSigningData, Error, Result}, + client::{secret::types::InputSigningData, Error}, types::block::{ output::{Output, OutputId}, payload::signed_transaction::{SignedTransactionPayload, Transaction}, @@ -33,7 +33,7 @@ pub fn verify_semantic( transaction_payload: &SignedTransactionPayload, mana_rewards: BTreeMap, protocol_parameters: ProtocolParameters, -) -> crate::client::Result> { +) -> Result<(), TransactionFailureReason> { let inputs = input_signing_data .iter() .map(|input| (input.output_id(), &input.output)) @@ -51,7 +51,9 @@ pub fn verify_semantic( } /// Verifies that the signed transaction payload doesn't exceed the block size limit with 8 parents. -pub fn validate_signed_transaction_payload_length(signed_transaction_payload: &SignedTransactionPayload) -> Result<()> { +pub fn validate_signed_transaction_payload_length( + signed_transaction_payload: &SignedTransactionPayload, +) -> crate::client::error::Result<()> { let signed_transaction_payload_bytes = signed_transaction_payload.pack_to_vec(); if signed_transaction_payload_bytes.len() > MAX_TX_LENGTH_FOR_BLOCK_WITH_8_PARENTS { return Err(Error::InvalidSignedTransactionPayloadLength { @@ -65,7 +67,7 @@ pub fn validate_signed_transaction_payload_length(signed_transaction_payload: &S /// Verifies that the transaction doesn't exceed the block size limit with 8 parents. /// Assuming one signature unlock and otherwise reference/account/nft unlocks. `validate_transaction_payload_length()` /// should later be used to check the length again with the correct unlocks. -pub fn validate_transaction_length(transaction: &Transaction) -> Result<()> { +pub fn validate_transaction_length(transaction: &Transaction) -> crate::client::error::Result<()> { let transaction_bytes = transaction.pack_to_vec(); // Assuming there is only 1 signature unlock and the rest is reference/account/nft unlocks diff --git a/sdk/src/client/error.rs b/sdk/src/client/error.rs index 9db4610d5c..f40f7b41bd 100644 --- a/sdk/src/client/error.rs +++ b/sdk/src/client/error.rs @@ -130,7 +130,7 @@ pub enum Error { }, /// The semantic validation of a transaction failed. #[error("the semantic validation of a transaction failed with conflict reason: {} - {0:?}", *.0 as u8)] - TransactionSemantic(TransactionFailureReason), + TransactionSemantic(#[from] TransactionFailureReason), /// Unpack error #[error("{0}")] Unpack(#[from] packable::error::UnpackError), diff --git a/sdk/src/client/secret/mod.rs b/sdk/src/client/secret/mod.rs index c9213bff69..2bb291b1ce 100644 --- a/sdk/src/client/secret/mod.rs +++ b/sdk/src/client/secret/mod.rs @@ -671,12 +671,11 @@ where validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic(&inputs_data, &tx_payload, mana_rewards, protocol_parameters.clone())?; - - if let Some(conflict) = conflict { - log::debug!("[sign_transaction] conflict: {conflict:?} for {:#?}", tx_payload); - return Err(Error::TransactionSemantic(conflict)); - } + verify_semantic(&inputs_data, &tx_payload, mana_rewards, protocol_parameters.clone()) + .inspect_err(|e| { + log::debug!("[sign_transaction] conflict: {e:?} for {tx_payload:#?}"); + }) + .map_err(Error::TransactionSemantic)?; Ok(tx_payload) } diff --git a/sdk/src/types/block/error.rs b/sdk/src/types/block/error.rs index 1c0bebccea..785a4fc480 100644 --- a/sdk/src/types/block/error.rs +++ b/sdk/src/types/block/error.rs @@ -29,6 +29,7 @@ use crate::types::block::{ InputCount, OutputCount, }, protocol::ProtocolParametersHash, + semantic::TransactionFailureReason, unlock::{UnlockCount, UnlockIndex, UnlocksCount}, }; @@ -212,6 +213,7 @@ pub enum Error { BlockSlotBeforeTransactionCreationSlot, TransactionCommitmentSlotNotInBlockSlotInterval, TransactionCommitmentSlotAfterBlockCommitmentSlot, + TransactionFailureReason(TransactionFailureReason), } #[cfg(feature = "std")] @@ -463,6 +465,9 @@ impl fmt::Display for Error { Self::TransactionCommitmentSlotAfterBlockCommitmentSlot => { write!(f, "the transaction commitment slot is after the block commitment slot") } + Self::TransactionFailureReason(r) => { + write!(f, "transaction failure reason: {r}") + } } } } @@ -479,6 +484,12 @@ impl From for Error { } } +impl From for Error { + fn from(error: TransactionFailureReason) -> Self { + Self::TransactionFailureReason(error) + } +} + impl From for Error { fn from(error: Infallible) -> Self { match error {} diff --git a/sdk/src/types/block/semantic/error.rs b/sdk/src/types/block/semantic/error.rs index b0b2f1ac32..b94236ff8b 100644 --- a/sdk/src/types/block/semantic/error.rs +++ b/sdk/src/types/block/semantic/error.rs @@ -257,6 +257,9 @@ impl fmt::Display for TransactionFailureReason { } } +#[cfg(feature = "std")] +impl std::error::Error for TransactionFailureReason {} + impl TryFrom for TransactionFailureReason { type Error = Error; diff --git a/sdk/src/types/block/semantic/mod.rs b/sdk/src/types/block/semantic/mod.rs index 3191a3af6c..236e9efbf6 100644 --- a/sdk/src/types/block/semantic/mod.rs +++ b/sdk/src/types/block/semantic/mod.rs @@ -14,12 +14,11 @@ pub use self::{error::TransactionFailureReason, state_transition::StateTransitio use crate::types::block::{ address::Address, context_input::RewardContextInput, - output::{feature::Features, AccountId, AnchorOutput, ChainId, FoundryId, Output, OutputId, TokenId}, + output::{feature::Features, AccountId, ChainId, FoundryId, Output, OutputId, TokenId}, payload::signed_transaction::{Transaction, TransactionCapabilityFlag, TransactionId, TransactionSigningHash}, protocol::ProtocolParameters, slot::SlotCommitmentId, unlock::Unlock, - Error, }; /// @@ -107,7 +106,7 @@ impl<'a> SemanticValidationContext<'a> { } /// - pub fn validate(mut self) -> Result, Error> { + pub fn validate(mut self) -> Result<(), TransactionFailureReason> { self.commitment_context_input = self .transaction .context_inputs() @@ -125,7 +124,7 @@ impl<'a> SemanticValidationContext<'a> { if let Some(output_id) = self.inputs.get(reward_context_input.index() as usize).map(|v| v.0) { self.reward_context_inputs.insert(*output_id, *reward_context_input); } else { - return Ok(Some(TransactionFailureReason::RewardInputReferenceInvalid)); + return Err(TransactionFailureReason::RewardInputReferenceInvalid); } } @@ -135,7 +134,7 @@ impl<'a> SemanticValidationContext<'a> { for (index, (output_id, consumed_output)) in self.inputs.iter().enumerate() { if output_id.transaction_id().slot_index() > self.transaction.creation_slot() { - return Ok(Some(TransactionFailureReason::InputCreationAfterTxCreation)); + return Err(TransactionFailureReason::InputCreationAfterTxCreation); } let (amount, consumed_native_token, unlock_conditions) = match consumed_output { @@ -145,28 +144,33 @@ impl<'a> SemanticValidationContext<'a> { let account_id = output.account_id_non_null(output_id); if self.commitment_context_input.is_none() { - return Ok(Some(TransactionFailureReason::BlockIssuerCommitmentInputMissing)); + return Err(TransactionFailureReason::BlockIssuerCommitmentInputMissing); } if !bic_context_inputs.contains(&account_id) { - return Ok(Some(TransactionFailureReason::BlockIssuanceCreditInputMissing)); + return Err(TransactionFailureReason::BlockIssuanceCreditInputMissing); } let entry = self.block_issuer_mana.entry(account_id).or_default(); entry.0 = entry .0 - .checked_add(consumed_output.available_mana( - &self.protocol_parameters, - output_id.transaction_id().slot_index(), - self.transaction.creation_slot(), - )?) - .ok_or(Error::ConsumedManaOverflow)?; + .checked_add( + consumed_output + .available_mana( + &self.protocol_parameters, + output_id.transaction_id().slot_index(), + self.transaction.creation_slot(), + ) + // Unwrap is fine as we already checked both slot indices against each others. + .unwrap(), + ) + .ok_or(TransactionFailureReason::ManaOverflow)?; } if output.features().staking().is_some() && self.commitment_context_input.is_none() { - return Ok(Some(TransactionFailureReason::StakingCommitmentInputMissing)); + return Err(TransactionFailureReason::StakingCommitmentInputMissing); } (output.amount(), None, output.unlock_conditions()) } - Output::Anchor(_) => return Err(Error::UnsupportedOutputKind(AnchorOutput::KIND)), + Output::Anchor(_) => return Err(TransactionFailureReason::SemanticValidationFailed), Output::Foundry(output) => (output.amount(), output.native_token(), output.unlock_conditions()), Output::Nft(output) => (output.amount(), None, output.unlock_conditions()), Output::Delegation(output) => (output.amount(), None, output.unlock_conditions()), @@ -174,7 +178,7 @@ impl<'a> SemanticValidationContext<'a> { if unlock_conditions.addresses().any(Address::is_implicit_account_creation) { if has_implicit_account_creation_address { - return Ok(Some(TransactionFailureReason::MultipleImplicitAccountCreationAddresses)); + return Err(TransactionFailureReason::MultipleImplicitAccountCreationAddresses); } else { has_implicit_account_creation_address = true; } @@ -185,10 +189,10 @@ impl<'a> SemanticValidationContext<'a> { if let Some(timelock) = unlock_conditions.timelock() { if let Some(commitment_slot_index) = commitment_slot_index { if timelock.is_timelocked(commitment_slot_index, self.protocol_parameters.min_committable_age()) { - return Ok(Some(TransactionFailureReason::TimelockNotExpired)); + return Err(TransactionFailureReason::TimelockNotExpired); } } else { - return Ok(Some(TransactionFailureReason::TimelockCommitmentInputMissing)); + return Err(TransactionFailureReason::TimelockCommitmentInputMissing); } } @@ -205,35 +209,40 @@ impl<'a> SemanticValidationContext<'a> { *amount = amount .checked_add(storage_deposit_return.amount()) - .ok_or(Error::StorageDepositReturnOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; } } - None => return Ok(Some(TransactionFailureReason::ExpirationNotUnlockable)), + None => return Err(TransactionFailureReason::ExpirationNotUnlockable), _ => {} } } else { - return Ok(Some(TransactionFailureReason::ExpirationCommitmentInputMissing)); + return Err(TransactionFailureReason::ExpirationCommitmentInputMissing); } } self.input_amount = self .input_amount .checked_add(amount) - .ok_or(Error::ConsumedAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; self.input_mana = self .input_mana - .checked_add(consumed_output.available_mana( - &self.protocol_parameters, - output_id.transaction_id().slot_index(), - self.transaction.creation_slot(), - )?) - .ok_or(Error::ConsumedManaOverflow)?; + .checked_add( + consumed_output + .available_mana( + &self.protocol_parameters, + output_id.transaction_id().slot_index(), + self.transaction.creation_slot(), + ) + // Unwrap is fine as we already checked both slot indices against each others. + .unwrap(), + ) + .ok_or(TransactionFailureReason::ManaOverflow)?; if let Some(mana_rewards) = self.mana_rewards.get(*output_id) { self.input_mana .checked_add(*mana_rewards) - .ok_or(Error::ConsumedManaOverflow)?; + .ok_or(TransactionFailureReason::ManaOverflow)?; } if let Some(consumed_native_token) = consumed_native_token { @@ -244,16 +253,16 @@ impl<'a> SemanticValidationContext<'a> { *native_token_amount = native_token_amount .checked_add(consumed_native_token.amount()) - .ok_or(Error::ConsumedNativeTokensAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; } if let Some(unlocks) = self.unlocks { if unlocks.len() != self.inputs.len() { - return Ok(Some(TransactionFailureReason::SemanticValidationFailed)); + return Err(TransactionFailureReason::SemanticValidationFailed); } if let Err(conflict) = self.output_unlock(consumed_output, output_id, &unlocks[index]) { - return Ok(Some(conflict)); + return Err(conflict); } } } @@ -263,7 +272,7 @@ impl<'a> SemanticValidationContext<'a> { self.output_mana = self .output_mana .checked_add(mana_allotment.mana()) - .ok_or(Error::CreatedManaOverflow)?; + .ok_or(TransactionFailureReason::ManaOverflow)?; } // Validation of outputs. @@ -275,7 +284,7 @@ impl<'a> SemanticValidationContext<'a> { *amount = amount .checked_add(output.amount()) - .ok_or(Error::CreatedAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; } ( @@ -290,34 +299,37 @@ impl<'a> SemanticValidationContext<'a> { let account_id = output.account_id_non_null(&OutputId::new(self.transaction_id, index as u16)); if self.commitment_context_input.is_none() { - return Ok(Some(TransactionFailureReason::BlockIssuerCommitmentInputMissing)); + return Err(TransactionFailureReason::BlockIssuerCommitmentInputMissing); } if !bic_context_inputs.contains(&account_id) { - return Ok(Some(TransactionFailureReason::BlockIssuanceCreditInputMissing)); + return Err(TransactionFailureReason::BlockIssuanceCreditInputMissing); } let entry = self.block_issuer_mana.entry(account_id).or_default(); - entry.1 = entry.1.checked_add(output.mana()).ok_or(Error::CreatedManaOverflow)?; + entry.1 = entry + .1 + .checked_add(output.mana()) + .ok_or(TransactionFailureReason::ManaOverflow)?; if let Some(allotment) = self.transaction.allotments().get(&account_id) { entry.1 = entry .1 .checked_add(allotment.mana()) - .ok_or(Error::CreatedManaOverflow)?; + .ok_or(TransactionFailureReason::ManaOverflow)?; } } if output.features().staking().is_some() { if self.commitment_context_input.is_none() { - return Ok(Some(TransactionFailureReason::StakingCommitmentInputMissing)); + return Err(TransactionFailureReason::StakingCommitmentInputMissing); } if output.features().block_issuer().is_none() { - return Ok(Some(TransactionFailureReason::StakingBlockIssuerFeatureMissing)); + return Err(TransactionFailureReason::StakingBlockIssuerFeatureMissing); } } (output.amount(), output.mana(), None, Some(output.features())) } - Output::Anchor(_) => return Err(Error::UnsupportedOutputKind(AnchorOutput::KIND)), + Output::Anchor(_) => return Err(TransactionFailureReason::SemanticValidationFailed), Output::Foundry(output) => (output.amount(), 0, output.native_token(), Some(output.features())), Output::Nft(output) => (output.amount(), output.mana(), None, Some(output.features())), Output::Delegation(output) => (output.amount(), 0, None, None), @@ -325,7 +337,7 @@ impl<'a> SemanticValidationContext<'a> { if let Some(sender) = features.and_then(Features::sender) { if !self.unlocked_addresses.contains(sender.address()) { - return Ok(Some(TransactionFailureReason::SenderFeatureNotUnlocked)); + return Err(TransactionFailureReason::SenderFeatureNotUnlocked); } } @@ -343,10 +355,10 @@ impl<'a> SemanticValidationContext<'a> { entry.1 = entry .1 .checked_add(created_output.mana()) - .ok_or(Error::CreatedAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; } } else { - return Ok(Some(TransactionFailureReason::BlockIssuerCommitmentInputMissing)); + return Err(TransactionFailureReason::BlockIssuerCommitmentInputMissing); } } } @@ -356,10 +368,13 @@ impl<'a> SemanticValidationContext<'a> { self.output_amount = self .output_amount .checked_add(amount) - .ok_or(Error::CreatedAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; // Add stored mana - self.output_mana = self.output_mana.checked_add(mana).ok_or(Error::CreatedManaOverflow)?; + self.output_mana = self + .output_mana + .checked_add(mana) + .ok_or(TransactionFailureReason::ManaOverflow)?; if let Some(created_native_token) = created_native_token { let native_token_amount = self @@ -369,8 +384,7 @@ impl<'a> SemanticValidationContext<'a> { *native_token_amount = native_token_amount .checked_add(created_native_token.amount()) - // TODO should be a tx failure reason ? - .ok_or(Error::CreatedNativeTokensAmountOverflow)?; + .ok_or(TransactionFailureReason::SemanticValidationFailed)?; } } @@ -378,31 +392,31 @@ impl<'a> SemanticValidationContext<'a> { for (return_address, return_amount) in self.storage_deposit_returns.iter() { if let Some(deposit_amount) = self.simple_deposits.get(return_address) { if deposit_amount < return_amount { - return Ok(Some(TransactionFailureReason::ReturnAmountNotFulFilled)); + return Err(TransactionFailureReason::ReturnAmountNotFulFilled); } } else { - return Ok(Some(TransactionFailureReason::ReturnAmountNotFulFilled)); + return Err(TransactionFailureReason::ReturnAmountNotFulFilled); } } // Validation of amounts. if self.input_amount != self.output_amount { - return Ok(Some(TransactionFailureReason::InputOutputBaseTokenMismatch)); + return Err(TransactionFailureReason::InputOutputBaseTokenMismatch); } if self.input_mana != self.output_mana { if self.input_mana > self.output_mana { if !self.transaction.has_capability(TransactionCapabilityFlag::BurnMana) { - return Ok(Some(TransactionFailureReason::CapabilitiesManaBurningNotAllowed)); + return Err(TransactionFailureReason::CapabilitiesManaBurningNotAllowed); } } else { - return Ok(Some(TransactionFailureReason::InputOutputManaMismatch)); + return Err(TransactionFailureReason::InputOutputManaMismatch); } } for (account_input_mana, account_output_mana) in self.block_issuer_mana.values() { if self.input_mana - account_input_mana < self.output_mana - account_output_mana { - return Ok(Some(TransactionFailureReason::ManaMovedOffBlockIssuerAccount)); + return Err(TransactionFailureReason::ManaMovedOffBlockIssuerAccount); } } @@ -415,29 +429,25 @@ impl<'a> SemanticValidationContext<'a> { .output_chains .contains_key(&ChainId::from(FoundryId::from(*token_id))) { - return Ok(Some(TransactionFailureReason::NativeTokenSumUnbalanced)); + return Err(TransactionFailureReason::NativeTokenSumUnbalanced); } } // Validation of state transitions and destructions. for (chain_id, current_state) in self.input_chains.iter() { - if let Err(e) = self.verify_state_transition( + self.verify_state_transition( Some(*current_state), self.output_chains.get(chain_id).map(|(id, o)| (id, *o)), - ) { - return Ok(Some(e)); - } + )?; } // Validation of state creations. for (chain_id, next_state) in self.output_chains.iter() { if self.input_chains.get(chain_id).is_none() { - if let Err(e) = self.verify_state_transition(None, Some((&next_state.0, next_state.1))) { - return Ok(Some(e)); - } + self.verify_state_transition(None, Some((&next_state.0, next_state.1)))?; } } - Ok(None) + Ok(()) } } diff --git a/sdk/src/wallet/operations/transaction/mod.rs b/sdk/src/wallet/operations/transaction/mod.rs index 36adc8e521..ec976c0c7b 100644 --- a/sdk/src/wallet/operations/transaction/mod.rs +++ b/sdk/src/wallet/operations/transaction/mod.rs @@ -121,9 +121,9 @@ where &signed_transaction_data.payload, signed_transaction_data.mana_rewards, self.client().get_protocol_parameters().await?, - )?; + ); - if let Some(conflict) = conflict { + if let Err(conflict) = conflict { log::debug!( "[TRANSACTION] conflict: {conflict:?} for {:?}", signed_transaction_data.payload diff --git a/sdk/tests/client/signing/account.rs b/sdk/tests/client/signing/account.rs index 9dcc6e045c..409aa6c1db 100644 --- a/sdk/tests/client/signing/account.rs +++ b/sdk/tests/client/signing/account.rs @@ -105,17 +105,13 @@ async fn sign_account_state_transition() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } @@ -239,16 +235,12 @@ async fn account_reference_unlocks() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } diff --git a/sdk/tests/client/signing/basic.rs b/sdk/tests/client/signing/basic.rs index 887174a560..7c2e6ce4f2 100644 --- a/sdk/tests/client/signing/basic.rs +++ b/sdk/tests/client/signing/basic.rs @@ -100,17 +100,13 @@ async fn single_ed25519_unlock() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } @@ -225,17 +221,13 @@ async fn ed25519_reference_unlocks() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } @@ -336,16 +328,12 @@ async fn two_signature_unlocks() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } diff --git a/sdk/tests/client/signing/delegation.rs b/sdk/tests/client/signing/delegation.rs index 5adbbe804f..8e6ebe9e39 100644 --- a/sdk/tests/client/signing/delegation.rs +++ b/sdk/tests/client/signing/delegation.rs @@ -110,17 +110,13 @@ async fn valid_creation() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } @@ -203,11 +199,11 @@ async fn creation_missing_commitment_input() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); assert_eq!( conflict, - Some(TransactionFailureReason::DelegationCommitmentInputMissing) + Err(TransactionFailureReason::DelegationCommitmentInputMissing) ); Ok(()) @@ -292,9 +288,9 @@ async fn non_null_id_creation() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::NewChainOutputHasNonZeroedId)); + assert_eq!(conflict, Err(TransactionFailureReason::NewChainOutputHasNonZeroedId)); Ok(()) } @@ -378,9 +374,9 @@ async fn mismatch_amount_creation() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationAmountMismatch)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationAmountMismatch)); Ok(()) } @@ -464,9 +460,9 @@ async fn non_zero_end_epoch_creation() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationEndEpochNotZero)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationEndEpochNotZero)); Ok(()) } @@ -551,9 +547,9 @@ async fn invalid_start_epoch_creation() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationStartEpochInvalid)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationStartEpochInvalid)); Ok(()) } @@ -649,11 +645,11 @@ async fn delay_not_null_id() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); assert_eq!( conflict, - Some(TransactionFailureReason::DelegationOutputTransitionedTwice) + Err(TransactionFailureReason::DelegationOutputTransitionedTwice) ); Ok(()) @@ -750,9 +746,9 @@ async fn delay_modified_amount() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationModified)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationModified)); Ok(()) } @@ -848,9 +844,9 @@ async fn delay_modified_validator() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationModified)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationModified)); Ok(()) } @@ -946,9 +942,9 @@ async fn delay_modified_start_epoch() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationModified)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationModified)); Ok(()) } @@ -1044,9 +1040,9 @@ async fn delay_pre_registration_slot_end_epoch() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationEndEpochInvalid)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationEndEpochInvalid)); Ok(()) } @@ -1138,17 +1134,13 @@ async fn destroy_null_id() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } @@ -1238,9 +1230,9 @@ async fn destroy_reward_missing() -> Result<()> { &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, - )?; + ); - assert_eq!(conflict, Some(TransactionFailureReason::DelegationRewardInputMissing)); + assert_eq!(conflict, Err(TransactionFailureReason::DelegationRewardInputMissing)); Ok(()) } diff --git a/sdk/tests/client/signing/mod.rs b/sdk/tests/client/signing/mod.rs index 2a25165ad3..83be3697fc 100644 --- a/sdk/tests/client/signing/mod.rs +++ b/sdk/tests/client/signing/mod.rs @@ -487,16 +487,12 @@ async fn all_combined() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) } diff --git a/sdk/tests/client/signing/nft.rs b/sdk/tests/client/signing/nft.rs index 1954198dc8..c76c6a13bc 100644 --- a/sdk/tests/client/signing/nft.rs +++ b/sdk/tests/client/signing/nft.rs @@ -159,16 +159,12 @@ async fn nft_reference_unlocks() -> Result<()> { validate_signed_transaction_payload_length(&tx_payload)?; - let conflict = verify_semantic( + verify_semantic( &prepared_transaction_data.inputs_data, &tx_payload, prepared_transaction_data.mana_rewards, protocol_parameters, )?; - if let Some(conflict) = conflict { - panic!("{conflict:?}, with {tx_payload:#?}"); - } - Ok(()) }