From 32473d99760b5ef98fe50869df28f0bdbf732c09 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Fri, 10 Jun 2022 09:36:07 -0400 Subject: [PATCH] Route networking through Wallet, not Coin --- coins/monero/src/wallet/mod.rs | 2 ++ coins/monero/src/wallet/send/mod.rs | 2 ++ processor/src/coins/monero.rs | 43 ++++++++++++----------------- processor/src/lib.rs | 17 ++++++++---- processor/src/tests/mod.rs | 5 ++-- processor/src/wallet.rs | 28 +++++++++++++++++-- 6 files changed, 61 insertions(+), 36 deletions(-) diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index 88d4ff61..e717fe4c 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -14,6 +14,8 @@ pub(crate) use decoys::Decoys; mod send; pub use send::{TransactionError, SignableTransaction}; +#[cfg(feature = "multisig")] +pub use send::TransactionMachine; fn key_image_sort(x: &EdwardsPoint, y: &EdwardsPoint) -> std::cmp::Ordering { x.compress().to_bytes().cmp(&y.compress().to_bytes()).reverse() diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 53688db0..6a8c14dd 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -36,6 +36,8 @@ use crate::frost::MultisigError; #[cfg(feature = "multisig")] mod multisig; +#[cfg(feature = "multisig")] +pub use multisig::TransactionMachine; #[allow(non_snake_case)] #[derive(Clone, PartialEq, Debug)] diff --git a/processor/src/coins/monero.rs b/processor/src/coins/monero.rs index a5f6fb68..f1d96bc5 100644 --- a/processor/src/coins/monero.rs +++ b/processor/src/coins/monero.rs @@ -6,23 +6,17 @@ use rand_core::OsRng; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar}; use dalek_ff_group as dfg; -use frost::{MultisigKeys, sign::StateMachine}; +use frost::MultisigKeys; use monero::{PublicKey, network::Network, util::address::Address}; use monero_serai::{ frost::Ed25519, transaction::{Timelock, Transaction}, rpc::Rpc, - wallet::{SpendableOutput, SignableTransaction as MSignableTransaction} + wallet::{SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine} }; -use crate::{ - Transcript, - CoinError, SignError, - Network as NetworkTrait, - Output as OutputTrait, Coin, - view_key -}; +use crate::{Transcript, CoinError, Output as OutputTrait, Coin, view_key}; #[derive(Clone, Debug)] pub struct Output(SpendableOutput); @@ -85,9 +79,12 @@ impl Monero { impl Coin for Monero { type Curve = Ed25519; - type Output = Output; + type Transaction = Transaction; type Block = Vec; + + type Output = Output; type SignableTransaction = SignableTransaction; + type TransactionMachine = TransactionMachine; type Address = Address; @@ -153,32 +150,26 @@ impl Coin for Monero { ) } - async fn attempt_send( + async fn attempt_send( &self, - network: &mut N, transaction: SignableTransaction, included: &[u16] - ) -> Result<(Vec, Vec<::Id>), SignError> { - let mut attempt = transaction.3.clone().multisig( + ) -> Result { + transaction.3.clone().multisig( &mut OsRng, &self.rpc, (*transaction.0).clone(), transaction.1.clone(), transaction.2, included.to_vec() - ).await.map_err(|_| SignError::CoinError(CoinError::ConnectionError))?; + ).await.map_err(|_| CoinError::ConnectionError) + } - let commitments = network.round( - attempt.preprocess(&mut OsRng).unwrap() - ).await.map_err(|e| SignError::NetworkError(e))?; - let shares = network.round( - attempt.sign(commitments, b"").map_err(|e| SignError::FrostError(e))? - ).await.map_err(|e| SignError::NetworkError(e))?; - let tx = attempt.complete(shares).map_err(|e| SignError::FrostError(e))?; - - self.rpc.publish_transaction( - &tx - ).await.map_err(|_| SignError::CoinError(CoinError::ConnectionError))?; + async fn publish_transaction( + &self, + tx: &Self::Transaction + ) -> Result<(Vec, Vec<::Id>), CoinError> { + self.rpc.publish_transaction(&tx).await.map_err(|_| CoinError::ConnectionError)?; Ok(( tx.hash().to_vec(), diff --git a/processor/src/lib.rs b/processor/src/lib.rs index 47e12e85..65862aed 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -3,7 +3,7 @@ use std::{marker::Send, sync::Arc, collections::HashMap}; use async_trait::async_trait; use thiserror::Error; -use frost::{Curve, FrostError, MultisigKeys}; +use frost::{Curve, FrostError, MultisigKeys, sign::StateMachine}; pub(crate) use monero_serai::frost::Transcript; @@ -51,9 +51,12 @@ pub trait Output: Sized + Clone { pub trait Coin { type Curve: Curve; - type Output: Output; + type Transaction; type Block; + + type Output: Output; type SignableTransaction; + type TransactionMachine: StateMachine; type Address: Send; @@ -82,12 +85,16 @@ pub trait Coin { payments: &[(Self::Address, u64)] ) -> Result; - async fn attempt_send( + async fn attempt_send( &self, - network: &mut N, transaction: Self::SignableTransaction, included: &[u16] - ) -> Result<(Vec, Vec<::Id>), SignError>; + ) -> Result; + + async fn publish_transaction( + &self, + tx: &Self::Transaction + ) -> Result<(Vec, Vec<::Id>), CoinError>; #[cfg(test)] async fn mine_block(&self, address: Self::Address); diff --git a/processor/src/tests/mod.rs b/processor/src/tests/mod.rs index d69cc8f4..c23b8309 100644 --- a/processor/src/tests/mod.rs +++ b/processor/src/tests/mod.rs @@ -88,8 +88,7 @@ async fn test_send(coin: C) { coin.test_send(wallets[0].address()).await; let mut futures = vec![]; - for (i, network) in networks.iter_mut().enumerate() { - let wallet = &mut wallets[i]; + for (network, wallet) in networks.iter_mut().zip(wallets.iter_mut()) { wallet.poll().await.unwrap(); let height = coin.get_height().await.unwrap(); @@ -98,7 +97,7 @@ async fn test_send(coin: C) { 1, vec![(wallet.address(), 10000000000)] ).await.unwrap().1.swap_remove(0); - futures.push(coin.attempt_send(network, signable, &[1, 2, 3])); + futures.push(wallet.attempt_send(network, signable, &[1, 2, 3])); } println!( diff --git a/processor/src/wallet.rs b/processor/src/wallet.rs index 5e0928fc..27a1cb83 100644 --- a/processor/src/wallet.rs +++ b/processor/src/wallet.rs @@ -1,10 +1,12 @@ use std::{sync::Arc, collections::HashMap}; +use rand_core::OsRng; + use transcript::Transcript as TranscriptTrait; -use frost::{Curve, MultisigKeys}; +use frost::{Curve, MultisigKeys, sign::StateMachine}; -use crate::{Transcript, CoinError, Output, Coin}; +use crate::{Transcript, CoinError, SignError, Output, Coin, Network}; pub struct WalletKeys { keys: MultisigKeys, @@ -333,4 +335,26 @@ impl Wallet { Ok((payments, txs)) } + + pub async fn attempt_send( + &mut self, + network: &mut N, + prepared: C::SignableTransaction, + included: &[u16] + ) -> Result<(Vec, Vec<::Id>), SignError> { + let mut attempt = self.coin.attempt_send( + prepared, + included + ).await.map_err(|e| SignError::CoinError(e))?; + + let commitments = network.round( + attempt.preprocess(&mut OsRng).unwrap() + ).await.map_err(|e| SignError::NetworkError(e))?; + let shares = network.round( + attempt.sign(commitments, b"").map_err(|e| SignError::FrostError(e))? + ).await.map_err(|e| SignError::NetworkError(e))?; + let tx = attempt.complete(shares).map_err(|e| SignError::FrostError(e))?; + + self.coin.publish_transaction(&tx).await.map_err(|e| SignError::CoinError(e)) + } }