Skip to content

Commit

Permalink
Merge pull request #136 from holaplex/abdul/fix-out-of-order
Browse files Browse the repository at this point in the history
Fix: out of order signed messages from fireblocks
  • Loading branch information
imabdulbasit authored Oct 18, 2023
2 parents db8377a + a717d11 commit e6e5ce7
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 47 deletions.
1 change: 0 additions & 1 deletion api/src/events/processor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use fireblocks::Fireblocks;
use hub_core::{
bs58,
prelude::*,
producer::{Producer, SendError},
thiserror, uuid,
Expand Down
127 changes: 81 additions & 46 deletions api/src/events/solana.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::Instant;
use std::{collections::HashMap, time::Instant};

use hex::FromHex;
use hub_core::{
Expand Down Expand Up @@ -219,53 +219,88 @@ impl<'a> Solana<'a> {
.await
.into_iter()
.map(|r| r.map(|d| d.signed_messages))
.collect::<Result<Vec<_>>>()?;

let signatures = futs_result[0]
.clone()
.into_iter()
.zip(futs_result[1].clone().into_iter())
.zip(payload.mint_transactions.into_iter())
.collect::<Vec<_>>();

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::<Result<Vec<_>>>();

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(())
Expand Down

0 comments on commit e6e5ce7

Please sign in to comment.