Skip to content

Commit

Permalink
Improve transaction receive protocol logic
Browse files Browse the repository at this point in the history
Swapped the order around when updating the final metadata signature for
the receiver: update the unblinded output, then update the transaction.
  • Loading branch information
hansieodendaal committed Jul 7, 2021
1 parent ffd2ff6 commit 3f53928
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 40 deletions.
10 changes: 8 additions & 2 deletions base_layer/wallet/src/output_manager_service/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use tari_core::transactions::{
ReceiverTransactionProtocol,
SenderTransactionProtocol,
};
use tari_crypto::script::TariScript;
use tari_crypto::{script::TariScript, tari_utilities::hex::Hex};
use tari_service_framework::reply_channel::SenderService;
use tokio::sync::broadcast;
use tower::Service;
Expand Down Expand Up @@ -85,7 +85,13 @@ impl fmt::Display for OutputManagerRequest {
GetBalance => write!(f, "GetBalance"),
AddOutput(v) => write!(f, "AddOutput ({})", v.value),
AddOutputWithTxId((t, v)) => write!(f, "AddOutputWithTxId ({}: {})", t, v.value),
UpdateOutputMetadataSignature(v) => write!(f, "UpdateOutputMetadataSignature ({:?})", v.metadata_signature),
UpdateOutputMetadataSignature(v) => write!(
f,
"UpdateOutputMetadataSignature ({}, {}, {})",
v.metadata_signature.public_nonce().to_hex(),
v.metadata_signature.u().to_hex(),
v.metadata_signature.v().to_hex()
),
GetRecipientTransaction(_) => write!(f, "GetRecipientTransaction"),
ConfirmTransaction(v) => write!(f, "ConfirmTransaction ({})", v.0),
ConfirmPendingTransaction(v) => write!(f, "ConfirmPendingTransaction ({})", v),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,11 @@ where TBackend: TransactionBackend + 'static
self.source_pubkey.clone()
);

finalized_transaction
.validate_internal_consistency(&self.resources.factories, None)
.map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?;

// Find your own output in the transaction
let rtp_output = match inbound_tx.receiver_protocol.state.clone() {
RecipientState::Finalized(s) => s.output,
RecipientState::Failed(_) => {
Expand All @@ -396,12 +401,47 @@ where TBackend: TransactionBackend + 'static

let finalized_outputs = finalized_transaction.body.outputs();

if !finalized_outputs.iter().any(|o| o.hash() == rtp_output.hash()) {
warn!(
target: LOG_TARGET,
"Finalized Transaction does not contain the Receiver's output"
);
continue;
// Update output metadata signature if not valid
match finalized_outputs
.iter()
.find(|output| output.hash() == rtp_output.hash())
{
Some(v) => {
if rtp_output.verify_metadata_signature().is_err() {
match self
.resources
.output_manager_service
.update_output_metadata_signature(v.clone())
.await
.map_err(|e| {
TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e))
}) {
Ok(..) => {
debug!(
target: LOG_TARGET,
"Updated metadata signature (TxId: {}) for output {}", self.id, v
);
},
Err(e) => {
warn!(
target: LOG_TARGET,
"Could not update metadata signature (TxId: {}) for output {} ({}, {})",
self.id,
v,
e.id,
e.error.to_string()
);
},
}
}
},
None => {
warn!(
target: LOG_TARGET,
"Finalized Transaction does not contain the Receiver's output"
);
continue;
},
}

let completed_transaction = CompletedTransaction::new(
Expand All @@ -418,44 +458,12 @@ where TBackend: TransactionBackend + 'static
None,
);

finalized_transaction
.validate_internal_consistency(&Default::default(), None)
.map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?;
self.resources
.db
.complete_inbound_transaction(self.id, completed_transaction.clone())
.await
.map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))?;

// Update output metadata signature if not valid
if let Some(v) = finalized_outputs
.iter()
.find(|output| output.hash() == rtp_output.hash())
{
if rtp_output.verify_metadata_signature().is_err() {
match self
.resources
.output_manager_service
.update_output_metadata_signature(v.clone())
.await
.map_err(|e| TransactionServiceProtocolError::new(self.id, TransactionServiceError::from(e)))
{
Ok(..) => {
debug!(target: LOG_TARGET, "Updated metadata signature for output {}", v);
},
Err(e) => {
warn!(
target: LOG_TARGET,
"Could not updated metadata signature for output {} ({}, {})",
v,
e.id,
e.error.to_string()
);
},
}
}
}

info!(
target: LOG_TARGET,
"Inbound Transaction with TX_ID = {} from {} moved to Completed Transactions",
Expand Down

0 comments on commit 3f53928

Please sign in to comment.