Apply an initial set of rustfmt rules

This commit is contained in:
Luke Parker
2022-07-15 01:26:07 -04:00
parent 0b879a53fa
commit e67033a207
67 changed files with 1983 additions and 1796 deletions

View File

@@ -12,7 +12,7 @@ pub use self::monero::Monero;
#[derive(Clone, Error, Debug)]
pub enum CoinError {
#[error("failed to connect to coin daemon")]
ConnectionError
ConnectionError,
}
pub trait Output: Sized + Clone {
@@ -52,7 +52,7 @@ pub trait Coin {
async fn get_outputs(
&self,
block: &Self::Block,
key: <Self::Curve as Curve>::G
key: <Self::Curve as Curve>::G,
) -> Vec<Self::Output>;
async fn prepare_send(
@@ -62,18 +62,18 @@ pub trait Coin {
height: usize,
inputs: Vec<Self::Output>,
payments: &[(Self::Address, u64)],
fee: Self::Fee
fee: Self::Fee,
) -> Result<Self::SignableTransaction, CoinError>;
async fn attempt_send(
&self,
transaction: Self::SignableTransaction,
included: &[u16]
included: &[u16],
) -> Result<Self::TransactionMachine, CoinError>;
async fn publish_transaction(
&self,
tx: &Self::Transaction
tx: &Self::Transaction,
) -> Result<(Vec<u8>, Vec<<Self::Output as Output>::Id>), CoinError>;
#[cfg(test)]

View File

@@ -12,12 +12,16 @@ use monero_serai::{
transaction::Transaction,
rpc::Rpc,
wallet::{
ViewPair, address::{Network, AddressType, Address},
Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine
}
ViewPair,
address::{Network, AddressType, Address},
Fee, SpendableOutput, SignableTransaction as MSignableTransaction, TransactionMachine,
},
};
use crate::{coin::{CoinError, Output as OutputTrait, Coin}, view_key};
use crate::{
coin::{CoinError, Output as OutputTrait, Coin},
view_key,
};
#[derive(Clone, Debug)]
pub struct Output(SpendableOutput);
@@ -55,13 +59,13 @@ pub struct SignableTransaction(
Arc<FrostKeys<Ed25519>>,
RecommendedTranscript,
usize,
MSignableTransaction
MSignableTransaction,
);
#[derive(Clone, Debug)]
pub struct Monero {
pub(crate) rpc: Rpc,
view: Scalar
view: Scalar,
}
impl Monero {
@@ -138,47 +142,51 @@ impl Coin for Monero {
height: usize,
mut inputs: Vec<Output>,
payments: &[(Address, u64)],
fee: Fee
fee: Fee,
) -> Result<SignableTransaction, CoinError> {
let spend = keys.group_key();
Ok(
SignableTransaction(
keys,
transcript,
height,
MSignableTransaction::new(
inputs.drain(..).map(|input| input.0).collect(),
payments.to_vec(),
Some(self.address(spend)),
fee
).map_err(|_| CoinError::ConnectionError)?
Ok(SignableTransaction(
keys,
transcript,
height,
MSignableTransaction::new(
inputs.drain(..).map(|input| input.0).collect(),
payments.to_vec(),
Some(self.address(spend)),
fee,
)
)
.map_err(|_| CoinError::ConnectionError)?,
))
}
async fn attempt_send(
&self,
transaction: SignableTransaction,
included: &[u16]
included: &[u16],
) -> Result<Self::TransactionMachine, CoinError> {
transaction.3.clone().multisig(
&self.rpc,
(*transaction.0).clone(),
transaction.1.clone(),
transaction.2,
included.to_vec()
).await.map_err(|_| CoinError::ConnectionError)
transaction
.3
.clone()
.multisig(
&self.rpc,
(*transaction.0).clone(),
transaction.1.clone(),
transaction.2,
included.to_vec(),
)
.await
.map_err(|_| CoinError::ConnectionError)
}
async fn publish_transaction(
&self,
tx: &Self::Transaction
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(),
tx.prefix.outputs.iter().map(|output| output.key.compress().to_bytes()).collect()
tx.prefix.outputs.iter().map(|output| output.key.compress().to_bytes()).collect(),
))
}
@@ -186,13 +194,20 @@ impl Coin for Monero {
async fn mine_block(&self) {
#[derive(serde::Deserialize, Debug)]
struct EmptyResponse {}
let _: EmptyResponse = self.rpc.rpc_call("json_rpc", Some(serde_json::json!({
"method": "generateblocks",
"params": {
"wallet_address": self.empty_address().to_string(),
"amount_of_blocks": 10
},
}))).await.unwrap();
let _: EmptyResponse = self
.rpc
.rpc_call(
"json_rpc",
Some(serde_json::json!({
"method": "generateblocks",
"params": {
"wallet_address": self.empty_address().to_string(),
"amount_of_blocks": 10
},
})),
)
.await
.unwrap();
}
#[cfg(test)]
@@ -206,9 +221,14 @@ impl Coin for Monero {
self.mine_block().await;
}
let outputs = self.rpc
.get_block_transactions_possible(height).await.unwrap()
.swap_remove(0).scan(self.empty_view_pair(), false).ignore_timelock();
let outputs = self
.rpc
.get_block_transactions_possible(height)
.await
.unwrap()
.swap_remove(0)
.scan(self.empty_view_pair(), false)
.ignore_timelock();
let amount = outputs[0].commitment.amount;
let fee = 1000000000; // TODO
@@ -216,8 +236,12 @@ impl Coin for Monero {
outputs,
vec![(address, amount - fee)],
Some(self.empty_address()),
self.rpc.get_fee().await.unwrap()
).unwrap().sign(&mut OsRng, &self.rpc, &Scalar::one()).await.unwrap();
self.rpc.get_fee().await.unwrap(),
)
.unwrap()
.sign(&mut OsRng, &self.rpc, &Scalar::one())
.await
.unwrap();
self.rpc.publish_transaction(&tx).await.unwrap();
self.mine_block().await;
}

View File

@@ -27,7 +27,7 @@ pub enum SignError {
#[error("coin had an error {0}")]
CoinError(CoinError),
#[error("network had an error {0}")]
NetworkError(NetworkError)
NetworkError(NetworkError),
}
// Generate a static view key for a given chain in a globally consistent manner

View File

@@ -1,17 +1,25 @@
use std::{io::Cursor, sync::{Arc, RwLock}, collections::HashMap};
use std::{
io::Cursor,
sync::{Arc, RwLock},
collections::HashMap,
};
use async_trait::async_trait;
use rand::rngs::OsRng;
use crate::{NetworkError, Network, coin::{Coin, Monero}, wallet::{WalletKeys, MemCoinDb, Wallet}};
use crate::{
NetworkError, Network,
coin::{Coin, Monero},
wallet::{WalletKeys, MemCoinDb, Wallet},
};
#[derive(Clone)]
struct LocalNetwork {
i: u16,
size: u16,
round: usize,
rounds: Arc<RwLock<Vec<HashMap<u16, Cursor<Vec<u8>>>>>>
rounds: Arc<RwLock<Vec<HashMap<u16, Cursor<Vec<u8>>>>>>,
}
impl LocalNetwork {
@@ -63,9 +71,7 @@ async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
for i in 1 ..= threshold {
let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone());
wallet.acknowledge_height(0, height);
wallet.add_keys(
&WalletKeys::new(Arc::try_unwrap(keys.remove(&i).take().unwrap()).unwrap(), 0)
);
wallet.add_keys(&WalletKeys::new(Arc::try_unwrap(keys.remove(&i).take().unwrap()).unwrap(), 0));
wallets.push(wallet);
}
@@ -87,20 +93,20 @@ async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
let height = coin.get_height().await.unwrap();
wallet.acknowledge_height(1, height - 10);
let signable = wallet.prepare_sends(
1,
vec![(wallet.address(), 10000000000)],
fee
).await.unwrap().1.swap_remove(0);
futures.push(
wallet.attempt_send(network, signable, (1 ..= threshold).into_iter().collect::<Vec<_>>())
);
let signable = wallet
.prepare_sends(1, vec![(wallet.address(), 10000000000)], fee)
.await
.unwrap()
.1
.swap_remove(0);
futures.push(wallet.attempt_send(
network,
signable,
(1 ..= threshold).into_iter().collect::<Vec<_>>(),
));
}
println!(
"{:?}",
hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap().0)
);
println!("{:?}", hex::encode(futures::future::join_all(futures).await.swap_remove(0).unwrap().0));
}
#[tokio::test]

View File

@@ -5,13 +5,20 @@ use rand_core::OsRng;
use group::GroupEncoding;
use transcript::{Transcript, RecommendedTranscript};
use frost::{curve::Curve, FrostKeys, sign::{PreprocessMachine, SignMachine, SignatureMachine}};
use frost::{
curve::Curve,
FrostKeys,
sign::{PreprocessMachine, SignMachine, SignatureMachine},
};
use crate::{coin::{CoinError, Output, Coin}, SignError, Network};
use crate::{
coin::{CoinError, Output, Coin},
SignError, Network,
};
pub struct WalletKeys<C: Curve> {
keys: FrostKeys<C>,
creation_height: usize
creation_height: usize,
}
impl<C: Curve> WalletKeys<C> {
@@ -57,17 +64,12 @@ pub struct MemCoinDb {
scanned_height: usize,
// Acknowledged height for a given canonical height
acknowledged_heights: HashMap<usize, usize>,
outputs: HashMap<Vec<u8>, Vec<u8>>
outputs: HashMap<Vec<u8>, Vec<u8>>,
}
impl MemCoinDb {
pub fn new() -> MemCoinDb {
MemCoinDb {
scanned_height: 0,
acknowledged_heights: HashMap::new(),
outputs: HashMap::new()
}
MemCoinDb { scanned_height: 0, acknowledged_heights: HashMap::new(), outputs: HashMap::new() }
}
}
@@ -118,7 +120,7 @@ fn select_inputs<C: Coin>(inputs: &mut Vec<C::Output>) -> (Vec<C::Output>, u64)
fn select_outputs<C: Coin>(
payments: &mut Vec<(C::Address, u64)>,
value: &mut u64
value: &mut u64,
) -> Vec<(C::Address, u64)> {
// Prioritize large payments which will most efficiently use large inputs
payments.sort_by(|a, b| a.1.cmp(&b.1));
@@ -144,7 +146,7 @@ fn select_outputs<C: Coin>(
fn refine_inputs<C: Coin>(
selected: &mut Vec<C::Output>,
inputs: &mut Vec<C::Output>,
mut remaining: u64
mut remaining: u64,
) {
// Drop unused inputs
let mut s = 0;
@@ -180,7 +182,7 @@ fn refine_inputs<C: Coin>(
fn select_inputs_outputs<C: Coin>(
inputs: &mut Vec<C::Output>,
outputs: &mut Vec<(C::Address, u64)>
outputs: &mut Vec<(C::Address, u64)>,
) -> (Vec<C::Output>, Vec<(C::Address, u64)>) {
if inputs.len() == 0 {
return (vec![], vec![]);
@@ -202,21 +204,17 @@ pub struct Wallet<D: CoinDb, C: Coin> {
db: D,
coin: C,
keys: Vec<(Arc<FrostKeys<C::Curve>>, Vec<C::Output>)>,
pending: Vec<(usize, FrostKeys<C::Curve>)>
pending: Vec<(usize, FrostKeys<C::Curve>)>,
}
impl<D: CoinDb, C: Coin> Wallet<D, C> {
pub fn new(db: D, coin: C) -> Wallet<D, C> {
Wallet {
db,
coin,
keys: vec![],
pending: vec![]
}
Wallet { db, coin, keys: vec![], pending: vec![] }
}
pub fn scanned_height(&self) -> usize { self.db.scanned_height() }
pub fn scanned_height(&self) -> usize {
self.db.scanned_height()
}
pub fn acknowledge_height(&mut self, canonical: usize, height: usize) {
self.db.acknowledge_height(canonical, height);
if height > self.db.scanned_height() {
@@ -261,9 +259,13 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
let block = self.coin.get_block(b).await?;
for (keys, outputs) in self.keys.iter_mut() {
outputs.extend(
self.coin.get_outputs(&block, keys.group_key()).await.iter().cloned().filter(
|output| self.db.add_output(output)
)
self
.coin
.get_outputs(&block, keys.group_key())
.await
.iter()
.cloned()
.filter(|output| self.db.add_output(output)),
);
}
@@ -283,7 +285,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
&mut self,
canonical: usize,
payments: Vec<(C::Address, u64)>,
fee: C::Fee
fee: C::Fee,
) -> Result<(Vec<(C::Address, u64)>, Vec<C::SignableTransaction>), CoinError> {
if payments.len() == 0 {
return Ok((vec![], vec![]));
@@ -310,27 +312,18 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
// Create the transcript for this transaction
let mut transcript = RecommendedTranscript::new(b"Serai Processor Wallet Send");
transcript.append_message(
b"canonical_height",
&u64::try_from(canonical).unwrap().to_le_bytes()
);
transcript
.append_message(b"canonical_height", &u64::try_from(canonical).unwrap().to_le_bytes());
transcript.append_message(
b"acknowledged_height",
&u64::try_from(acknowledged_height).unwrap().to_le_bytes()
);
transcript.append_message(
b"index",
&u64::try_from(txs.len()).unwrap().to_le_bytes()
&u64::try_from(acknowledged_height).unwrap().to_le_bytes(),
);
transcript.append_message(b"index", &u64::try_from(txs.len()).unwrap().to_le_bytes());
let tx = self.coin.prepare_send(
keys.clone(),
transcript,
acknowledged_height,
inputs,
&outputs,
fee
).await?;
let tx = self
.coin
.prepare_send(keys.clone(), transcript, acknowledged_height, inputs, &outputs, fee)
.await?;
// self.db.save_tx(tx) // TODO
txs.push(tx);
}
@@ -343,12 +336,10 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
&mut self,
network: &mut N,
prepared: C::SignableTransaction,
included: Vec<u16>
included: Vec<u16>,
) -> Result<(Vec<u8>, Vec<<C::Output as Output>::Id>), SignError> {
let attempt = self.coin.attempt_send(
prepared,
&included
).await.map_err(|e| SignError::CoinError(e))?;
let attempt =
self.coin.attempt_send(prepared, &included).await.map_err(|e| SignError::CoinError(e))?;
let (attempt, commitments) = attempt.preprocess(&mut OsRng);
let commitments = network.round(commitments).await.map_err(|e| SignError::NetworkError(e))?;