mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-22 02:34:55 +00:00
Route networking through Wallet, not Coin
This commit is contained in:
parent
4b8822cb74
commit
32473d9976
6 changed files with 61 additions and 36 deletions
|
@ -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()
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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<Transaction>;
|
||||
|
||||
type Output = Output;
|
||||
type SignableTransaction = SignableTransaction;
|
||||
type TransactionMachine = TransactionMachine;
|
||||
|
||||
type Address = Address;
|
||||
|
||||
|
@ -153,32 +150,26 @@ impl Coin for Monero {
|
|||
)
|
||||
}
|
||||
|
||||
async fn attempt_send<N: NetworkTrait>(
|
||||
async fn attempt_send(
|
||||
&self,
|
||||
network: &mut N,
|
||||
transaction: SignableTransaction,
|
||||
included: &[u16]
|
||||
) -> Result<(Vec<u8>, Vec<<Self::Output as OutputTrait>::Id>), SignError> {
|
||||
let mut attempt = transaction.3.clone().multisig(
|
||||
) -> Result<Self::TransactionMachine, CoinError> {
|
||||
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<u8>, Vec<<Self::Output as OutputTrait>::Id>), CoinError> {
|
||||
self.rpc.publish_transaction(&tx).await.map_err(|_| CoinError::ConnectionError)?;
|
||||
|
||||
Ok((
|
||||
tx.hash().to_vec(),
|
||||
|
|
|
@ -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<Signature = Self::Transaction>;
|
||||
|
||||
type Address: Send;
|
||||
|
||||
|
@ -82,12 +85,16 @@ pub trait Coin {
|
|||
payments: &[(Self::Address, u64)]
|
||||
) -> Result<Self::SignableTransaction, CoinError>;
|
||||
|
||||
async fn attempt_send<N: Network>(
|
||||
async fn attempt_send(
|
||||
&self,
|
||||
network: &mut N,
|
||||
transaction: Self::SignableTransaction,
|
||||
included: &[u16]
|
||||
) -> Result<(Vec<u8>, Vec<<Self::Output as Output>::Id>), SignError>;
|
||||
) -> Result<Self::TransactionMachine, CoinError>;
|
||||
|
||||
async fn publish_transaction(
|
||||
&self,
|
||||
tx: &Self::Transaction
|
||||
) -> Result<(Vec<u8>, Vec<<Self::Output as Output>::Id>), CoinError>;
|
||||
|
||||
#[cfg(test)]
|
||||
async fn mine_block(&self, address: Self::Address);
|
||||
|
|
|
@ -88,8 +88,7 @@ async fn test_send<C: Coin + Clone>(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<C: Coin + Clone>(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!(
|
||||
|
|
|
@ -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<C: Curve> {
|
||||
keys: MultisigKeys<C>,
|
||||
|
@ -333,4 +335,26 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
|
||||
Ok((payments, txs))
|
||||
}
|
||||
|
||||
pub async fn attempt_send<N: Network>(
|
||||
&mut self,
|
||||
network: &mut N,
|
||||
prepared: C::SignableTransaction,
|
||||
included: &[u16]
|
||||
) -> Result<(Vec<u8>, Vec<<C::Output as Output>::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))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue