Reorganize processor's handling of coins

This commit is contained in:
Luke Parker 2022-06-24 19:53:41 -04:00
parent 60254a0171
commit 020d246b8f
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
6 changed files with 99 additions and 94 deletions

84
processor/src/coin/mod.rs Normal file
View file

@ -0,0 +1,84 @@
use std::{marker::Send, sync::Arc};
use async_trait::async_trait;
use thiserror::Error;
use transcript::RecommendedTranscript;
use frost::{curve::Curve, MultisigKeys, sign::PreprocessMachine};
pub mod monero;
pub use self::monero::Monero;
#[derive(Clone, Error, Debug)]
pub enum CoinError {
#[error("failed to connect to coin daemon")]
ConnectionError
}
pub trait Output: Sized + Clone {
type Id: AsRef<[u8]>;
fn id(&self) -> Self::Id;
fn amount(&self) -> u64;
fn serialize(&self) -> Vec<u8>;
fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self>;
}
#[async_trait]
pub trait Coin {
type Curve: Curve;
type Fee: Copy;
type Transaction;
type Block;
type Output: Output;
type SignableTransaction;
type TransactionMachine: PreprocessMachine<Signature = Self::Transaction>;
type Address: Send;
const ID: &'static [u8];
const CONFIRMATIONS: usize;
const MAX_INPUTS: usize;
const MAX_OUTPUTS: usize; // TODO: Decide if this includes change or not
// Doesn't have to take self, enables some level of caching which is pleasant
fn address(&self, key: <Self::Curve as Curve>::G) -> Self::Address;
async fn get_height(&self) -> Result<usize, CoinError>;
async fn get_block(&self, height: usize) -> Result<Self::Block, CoinError>;
async fn get_outputs(
&self,
block: &Self::Block,
key: <Self::Curve as Curve>::G
) -> Vec<Self::Output>;
async fn prepare_send(
&self,
keys: Arc<MultisigKeys<Self::Curve>>,
transcript: RecommendedTranscript,
height: usize,
inputs: Vec<Self::Output>,
payments: &[(Self::Address, u64)],
fee: Self::Fee
) -> Result<Self::SignableTransaction, CoinError>;
async fn attempt_send(
&self,
transaction: Self::SignableTransaction,
included: &[u16]
) -> 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);
#[cfg(test)]
async fn test_send(&self, key: Self::Address);
}

View file

@ -15,7 +15,7 @@ use monero_serai::{
wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine} wallet::{Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine}
}; };
use crate::{CoinError, Output as OutputTrait, Coin, view_key}; use crate::{coin::{CoinError, Output as OutputTrait, Coin}, view_key};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Output(SpendableOutput); pub struct Output(SpendableOutput);

View file

@ -1 +0,0 @@
pub mod monero;

View file

@ -1,107 +1,33 @@
use std::{marker::Send, sync::Arc, collections::HashMap}; use std::{marker::Send, collections::HashMap};
use async_trait::async_trait; use async_trait::async_trait;
use thiserror::Error; use thiserror::Error;
use transcript::RecommendedTranscript; use frost::{curve::Curve, FrostError};
use frost::{curve::Curve, FrostError, MultisigKeys, sign::PreprocessMachine};
mod coins; mod coin;
use coin::{CoinError, Coin};
mod wallet; mod wallet;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
#[derive(Clone, Error, Debug)]
pub enum CoinError {
#[error("failed to connect to coin daemon")]
ConnectionError
}
#[derive(Clone, Error, Debug)] #[derive(Clone, Error, Debug)]
pub enum NetworkError {} pub enum NetworkError {}
#[derive(Clone, Error, Debug)]
pub enum SignError {
#[error("coin had an error {0}")]
CoinError(CoinError),
#[error("network had an error {0}")]
NetworkError(NetworkError),
#[error("FROST had an error {0}")]
FrostError(FrostError)
}
#[async_trait] #[async_trait]
pub trait Network: Send { pub trait Network: Send {
async fn round(&mut self, data: Vec<u8>) -> Result<HashMap<u16, Vec<u8>>, NetworkError>; async fn round(&mut self, data: Vec<u8>) -> Result<HashMap<u16, Vec<u8>>, NetworkError>;
} }
pub trait Output: Sized + Clone { #[derive(Clone, Error, Debug)]
type Id: AsRef<[u8]>; pub enum SignError {
#[error("FROST had an error {0}")]
fn id(&self) -> Self::Id; FrostError(FrostError),
fn amount(&self) -> u64; #[error("coin had an error {0}")]
CoinError(CoinError),
fn serialize(&self) -> Vec<u8>; #[error("network had an error {0}")]
fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self>; NetworkError(NetworkError)
}
#[async_trait]
pub trait Coin {
type Curve: Curve;
type Fee: Copy;
type Transaction;
type Block;
type Output: Output;
type SignableTransaction;
type TransactionMachine: PreprocessMachine<Signature = Self::Transaction>;
type Address: Send;
const ID: &'static [u8];
const CONFIRMATIONS: usize;
const MAX_INPUTS: usize;
const MAX_OUTPUTS: usize; // TODO: Decide if this includes change or not
// Doesn't have to take self, enables some level of caching which is pleasant
fn address(&self, key: <Self::Curve as Curve>::G) -> Self::Address;
async fn get_height(&self) -> Result<usize, CoinError>;
async fn get_block(&self, height: usize) -> Result<Self::Block, CoinError>;
async fn get_outputs(
&self,
block: &Self::Block,
key: <Self::Curve as Curve>::G
) -> Vec<Self::Output>;
async fn prepare_send(
&self,
keys: Arc<MultisigKeys<Self::Curve>>,
transcript: RecommendedTranscript,
height: usize,
inputs: Vec<Self::Output>,
payments: &[(Self::Address, u64)],
fee: Self::Fee
) -> Result<Self::SignableTransaction, CoinError>;
async fn attempt_send(
&self,
transaction: Self::SignableTransaction,
included: &[u16]
) -> 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);
#[cfg(test)]
async fn test_send(&self, key: Self::Address);
} }
// Generate a static view key for a given chain in a globally consistent manner // Generate a static view key for a given chain in a globally consistent manner

View file

@ -8,11 +8,7 @@ use group::Group;
use frost::curve::Curve; use frost::curve::Curve;
use crate::{ use crate::{NetworkError, Network, coin::{Coin, Monero}, wallet::{WalletKeys, MemCoinDb, Wallet}};
NetworkError, Network,
Coin, coins::monero::Monero,
wallet::{WalletKeys, MemCoinDb, Wallet}
};
#[derive(Clone)] #[derive(Clone)]
struct LocalNetwork { struct LocalNetwork {

View file

@ -6,7 +6,7 @@ use transcript::{Transcript, RecommendedTranscript};
use frost::{curve::Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}}; use frost::{curve::Curve, MultisigKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
use crate::{CoinError, SignError, Output, Coin, Network}; use crate::{coin::{CoinError, Output, Coin}, SignError, Network};
pub struct WalletKeys<C: Curve> { pub struct WalletKeys<C: Curve> {
keys: MultisigKeys<C>, keys: MultisigKeys<C>,