Test Eventuality completion via CoordinatorMessage::Completed

This commit is contained in:
Luke Parker 2023-07-30 07:00:54 -04:00
parent e010d66c5d
commit 9b79c4dc0c
No known key found for this signature in database
2 changed files with 84 additions and 10 deletions

View file

@ -324,12 +324,14 @@ impl Coordinator {
let rpc_url = network_rpc(self.network, ops, &self.network_handle); let rpc_url = network_rpc(self.network, ops, &self.network_handle);
match self.network { match self.network {
NetworkId::Bitcoin => { NetworkId::Bitcoin => {
use bitcoin_serai::rpc::Rpc; use bitcoin_serai::{
bitcoin::{consensus::Decodable, Transaction},
rpc::Rpc,
};
let rpc = let rpc =
Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC"); Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC");
let _: String = rpc.send_raw_transaction(&Transaction::consensus_decode(&mut &*tx).unwrap()).await.unwrap();
rpc.rpc_call("sendrawtransaction", serde_json::json!([hex::encode(tx)])).await.unwrap();
} }
NetworkId::Ethereum => todo!(), NetworkId::Ethereum => todo!(),
NetworkId::Monero => { NetworkId::Monero => {
@ -341,4 +343,39 @@ impl Coordinator {
NetworkId::Serai => panic!("processor tests broadcasting block to Serai"), NetworkId::Serai => panic!("processor tests broadcasting block to Serai"),
} }
} }
pub async fn get_transaction(&self, ops: &DockerOperations, tx: &[u8]) -> Option<Vec<u8>> {
let rpc_url = network_rpc(self.network, ops, &self.network_handle);
match self.network {
NetworkId::Bitcoin => {
use bitcoin_serai::{bitcoin::consensus::Encodable, rpc::Rpc};
let rpc =
Rpc::new(rpc_url).await.expect("couldn't connect to the coordinator's Bitcoin RPC");
let mut hash = [0; 32];
hash.copy_from_slice(tx);
if let Ok(tx) = rpc.get_transaction(&hash).await {
let mut buf = vec![];
tx.consensus_encode(&mut buf).unwrap();
Some(buf)
} else {
None
}
}
NetworkId::Ethereum => todo!(),
NetworkId::Monero => {
use monero_serai::rpc::HttpRpc;
let rpc = HttpRpc::new(rpc_url).expect("couldn't connect to the coordinator's Monero RPC");
let mut hash = [0; 32];
hash.copy_from_slice(tx);
if let Ok(tx) = rpc.get_transaction(hash).await {
Some(tx.serialize())
} else {
None
}
}
NetworkId::Serai => panic!("processor tests broadcasting block to Serai"),
}
}
} }

View file

@ -1,5 +1,5 @@
use std::{ use std::{
collections::HashMap, collections::{HashSet, HashMap},
time::{SystemTime, Duration}, time::{SystemTime, Duration},
}; };
@ -250,15 +250,52 @@ fn send_test() {
(id, preprocesses) = (id, preprocesses) =
recv_sign_preprocesses(&mut coordinators, key_pair.1.to_vec(), attempt).await; recv_sign_preprocesses(&mut coordinators, key_pair.1.to_vec(), attempt).await;
} }
let participating = preprocesses.keys().cloned().collect::<Vec<_>>();
let tx_id = sign_tx(&mut coordinators, id, preprocesses).await; let tx_id = sign_tx(&mut coordinators, id.clone(), preprocesses).await;
// Make sure all participating nodes published the TX
let participating =
participating.iter().map(|p| usize::from(u16::from(*p) - 1)).collect::<HashSet<_>>();
for participant in &participating {
assert!(coordinators[*participant].get_transaction(&ops, &tx_id).await.is_some());
}
// Publish this transaction to the left out nodes
let tx = coordinators[*participating.iter().next().unwrap()]
.get_transaction(&ops, &tx_id)
.await
.unwrap();
for (i, coordinator) in coordinators.iter_mut().enumerate() {
if !participating.contains(&i) {
coordinator.publish_transacton(&ops, &tx).await;
// Tell them of it as a completion of the relevant signing nodess
coordinator
.send_message(messages::sign::CoordinatorMessage::Completed {
key: key_pair.1.to_vec(),
id: id.id,
tx: tx_id.clone(),
})
.await;
// Verify they send Completed back
match coordinator.recv_message().await {
messages::ProcessorMessage::Sign(messages::sign::ProcessorMessage::Completed {
key,
id: this_id,
tx: this_tx,
}) => {
assert_eq!(&key, &id.key);
assert_eq!(&this_id, &id.id);
assert_eq!(this_tx, tx_id);
}
_ => panic!("processor didn't send Completed"),
}
}
}
// TODO: Test callimg Sign again yields tx_id again
// TODO: Make sure all participating nodes published the TX
// TODO: Send this TX to the left out node and make sure they can complete the Eventuality
// TODO: Test the Eventuality from the blockchain, instead of from the coordinator // TODO: Test the Eventuality from the blockchain, instead of from the coordinator
// TODO: Test what happenns when Completed is sent with a non-existent TX ID
let _ = tx_id; // TODO: Test what happenns when Completed is sent with a non-completing TX ID
}); });
} }
} }