From a717d119b6c31eadfaa52e6969da9c4348a86121 Mon Sep 17 00:00:00 2001 From: imabdulbasit Date: Wed, 18 Oct 2023 21:33:35 +0500 Subject: [PATCH] Fix: out of order signed messages from fireblocks --- api/src/events/processor.rs | 1 - api/src/events/solana.rs | 127 +++++++++++++++++++++++------------- 2 files changed, 81 insertions(+), 47 deletions(-) diff --git a/api/src/events/processor.rs b/api/src/events/processor.rs index 9675499..d2b5905 100644 --- a/api/src/events/processor.rs +++ b/api/src/events/processor.rs @@ -1,6 +1,5 @@ use fireblocks::Fireblocks; use hub_core::{ - bs58, prelude::*, producer::{Producer, SendError}, thiserror, uuid, diff --git a/api/src/events/solana.rs b/api/src/events/solana.rs index 3c18e1d..64e1e69 100644 --- a/api/src/events/solana.rs +++ b/api/src/events/solana.rs @@ -1,4 +1,4 @@ -use std::time::Instant; +use std::{collections::HashMap, time::Instant}; use hex::FromHex; use hub_core::{ @@ -219,53 +219,88 @@ impl<'a> Solana<'a> { .await .into_iter() .map(|r| r.map(|d| d.signed_messages)) - .collect::>>()?; - - let signatures = futs_result[0] - .clone() - .into_iter() - .zip(futs_result[1].clone().into_iter()) - .zip(payload.mint_transactions.into_iter()) - .collect::>(); - - for ((sig1, sig2), mint_transaction) in signatures { - let mut signatures = Vec::new(); - let key = key.clone(); - - let SolanaMintTransaction { - serialized_message, - mint_id, - signer_signature, - } = mint_transaction; - - let sig1_bytes = <[u8; 64]>::from_hex(sig1.signature.full_sig)?; - signatures.push(bs58::encode(sig1_bytes).into_string()); - - let sig2_bytes = <[u8; 64]>::from_hex(sig2.signature.full_sig)?; - signatures.push(bs58::encode(sig2_bytes).into_string()); + .collect::>>(); + + match futs_result { + Ok(results) => { + let mut hashmap = HashMap::new(); + for messages in results { + for msg in messages { + let bytes = <[u8; 64]>::from_hex(msg.signature.full_sig)?; + let signature = bs58::encode(bytes).into_string(); + + hashmap + .entry(msg.content) + .or_insert(Vec::new()) + .push(signature); + } + } + + for tx in payload.mint_transactions { + let key = key.clone(); + + let SolanaMintTransaction { + mint_id, + signer_signature, + serialized_message, + } = tx; + + let hex_message = hex::encode(serialized_message.clone()); + + let mut signatures = hashmap + .get(&hex_message) + .ok_or(ProcessorError::MissingSignedMessage)? + .clone(); + + // Uncompressed mint message needs to be signed by mint key pair + if let Some(signer_signature) = signer_signature { + signatures.insert(1, signer_signature); + } + + let txn = SolanaTransactionResult { + serialized_message: Some(serialized_message), + signed_message_signatures: signatures, + status: TransactionStatus::Completed.into(), + }; + + let evt = Event::SolanaMintOpenDropSigned(txn); + self.producer() + .send( + Some(&TreasuryEvents { event: Some(evt) }), + Some(&TreasuryEventKey { + id: mint_id, + user_id: key.user_id, + project_id: key.project_id, + }), + ) + .await?; + } + }, - // Uncompressed mint message needs to be signed by mint key pair - if let Some(signer_signature) = signer_signature { - signatures.insert(1, signer_signature); - } + Err(e) => { + error!("Error signing mint batch: {:?}", e); - let txn = SolanaTransactionResult { - serialized_message: Some(serialized_message), - signed_message_signatures: signatures, - status: TransactionStatus::Completed.into(), - }; - - let evt = Event::SolanaMintOpenDropSigned(txn); - self.producer() - .send( - Some(&TreasuryEvents { event: Some(evt) }), - Some(&TreasuryEventKey { - id: mint_id, - user_id: key.user_id, - project_id: key.project_id, - }), - ) - .await?; + let txn = SolanaTransactionResult { + serialized_message: None, + signed_message_signatures: vec![], + status: TransactionStatus::Failed.into(), + }; + + for tx in payload.mint_transactions { + let evt = Event::SolanaMintOpenDropSigned(txn.clone()); + let key = key.clone(); + self.producer() + .send( + Some(&TreasuryEvents { event: Some(evt) }), + Some(&TreasuryEventKey { + id: tx.mint_id, + user_id: key.user_id, + project_id: key.project_id, + }), + ) + .await?; + } + }, } Ok(())