mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Monero prepare_send
This commit is contained in:
@@ -37,11 +37,11 @@ pub struct TransactionMachine {
|
|||||||
impl SignableTransaction {
|
impl SignableTransaction {
|
||||||
pub async fn multisig<R: RngCore + CryptoRng>(
|
pub async fn multisig<R: RngCore + CryptoRng>(
|
||||||
mut self,
|
mut self,
|
||||||
mut transcript: Transcript,
|
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
rpc: &Rpc,
|
rpc: &Rpc,
|
||||||
height: usize,
|
|
||||||
keys: MultisigKeys<Ed25519>,
|
keys: MultisigKeys<Ed25519>,
|
||||||
|
mut transcript: Transcript,
|
||||||
|
height: usize,
|
||||||
mut included: Vec<u16>
|
mut included: Vec<u16>
|
||||||
) -> Result<TransactionMachine, TransactionError> {
|
) -> Result<TransactionMachine, TransactionError> {
|
||||||
let mut images = vec![];
|
let mut images = vec![];
|
||||||
|
|||||||
@@ -145,11 +145,11 @@ async fn send_core(test: usize, multisig: bool) {
|
|||||||
machines.insert(
|
machines.insert(
|
||||||
i,
|
i,
|
||||||
signable.clone().multisig(
|
signable.clone().multisig(
|
||||||
Transcript::new(b"Monero Serai Test Transaction"),
|
|
||||||
&mut OsRng,
|
&mut OsRng,
|
||||||
&rpc,
|
&rpc,
|
||||||
rpc.get_height().await.unwrap() - 10,
|
|
||||||
(*keys[&i]).clone(),
|
(*keys[&i]).clone(),
|
||||||
|
Transcript::new(b"Monero Serai Test Transaction"),
|
||||||
|
rpc.get_height().await.unwrap() - 10,
|
||||||
(1 ..= THRESHOLD).collect::<Vec<_>>()
|
(1 ..= THRESHOLD).collect::<Vec<_>>()
|
||||||
).await.unwrap()
|
).await.unwrap()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,20 +3,24 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rand_core::{RngCore, CryptoRng};
|
use rand_core::{RngCore, CryptoRng};
|
||||||
|
|
||||||
use curve25519_dalek::{scalar::Scalar, edwards::CompressedEdwardsY};
|
use curve25519_dalek::{
|
||||||
|
constants::ED25519_BASEPOINT_TABLE,
|
||||||
|
scalar::Scalar,
|
||||||
|
edwards::CompressedEdwardsY
|
||||||
|
};
|
||||||
|
|
||||||
use dalek_ff_group as dfg;
|
use dalek_ff_group as dfg;
|
||||||
use frost::MultisigKeys;
|
use frost::MultisigKeys;
|
||||||
|
|
||||||
use monero::util::address::Address;
|
use monero::{PublicKey, network::Network, util::address::Address};
|
||||||
use monero_serai::{
|
use monero_serai::{
|
||||||
frost::Ed25519,
|
frost::Ed25519,
|
||||||
transaction::{Timelock, Transaction},
|
transaction::{Timelock, Transaction},
|
||||||
rpc::Rpc,
|
rpc::Rpc,
|
||||||
wallet::{SpendableOutput, SignableTransaction}
|
wallet::{SpendableOutput, SignableTransaction as MSignableTransaction}
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Output as OutputTrait, CoinError, Coin, view_key};
|
use crate::{Transcript, Output as OutputTrait, CoinError, Coin, view_key};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Output(SpendableOutput);
|
pub struct Output(SpendableOutput);
|
||||||
@@ -49,16 +53,26 @@ impl From<SpendableOutput> for Output {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SignableTransaction(
|
||||||
|
Arc<MultisigKeys<Ed25519>>,
|
||||||
|
Transcript,
|
||||||
|
usize,
|
||||||
|
MSignableTransaction
|
||||||
|
);
|
||||||
|
|
||||||
pub struct Monero {
|
pub struct Monero {
|
||||||
rpc: Rpc,
|
rpc: Rpc,
|
||||||
view: Scalar
|
view: Scalar,
|
||||||
|
view_pub: CompressedEdwardsY
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Monero {
|
impl Monero {
|
||||||
pub fn new(url: String) -> Monero {
|
pub fn new(url: String) -> Monero {
|
||||||
|
let view = view_key::<Monero>(0).0;
|
||||||
Monero {
|
Monero {
|
||||||
rpc: Rpc::new(url),
|
rpc: Rpc::new(url),
|
||||||
view: *view_key::<Monero>(0)
|
view,
|
||||||
|
view_pub: (&view * &ED25519_BASEPOINT_TABLE).compress()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,21 +123,55 @@ impl Coin for Monero {
|
|||||||
|
|
||||||
async fn prepare_send(
|
async fn prepare_send(
|
||||||
&self,
|
&self,
|
||||||
_keys: Arc<MultisigKeys<Ed25519>>,
|
keys: Arc<MultisigKeys<Ed25519>>,
|
||||||
_label: Vec<u8>,
|
transcript: Transcript,
|
||||||
_height: usize,
|
height: usize,
|
||||||
_inputs: Vec<Output>,
|
mut inputs: Vec<Output>,
|
||||||
_payments: &[(Address, u64)]
|
payments: &[(Address, u64)]
|
||||||
) -> Result<SignableTransaction, CoinError> {
|
) -> Result<SignableTransaction, CoinError> {
|
||||||
todo!()
|
let spend = keys.group_key().0.compress();
|
||||||
|
Ok(
|
||||||
|
SignableTransaction(
|
||||||
|
keys,
|
||||||
|
transcript,
|
||||||
|
height,
|
||||||
|
MSignableTransaction::new(
|
||||||
|
inputs.drain(..).map(|input| input.0).collect(),
|
||||||
|
payments.to_vec(),
|
||||||
|
Address::standard(
|
||||||
|
Network::Mainnet,
|
||||||
|
PublicKey { point: spend },
|
||||||
|
PublicKey { point: self.view_pub }
|
||||||
|
),
|
||||||
|
100000000
|
||||||
|
).map_err(|_| CoinError::ConnectionError)?
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn attempt_send<R: RngCore + CryptoRng + std::marker::Send>(
|
async fn attempt_send<R: RngCore + CryptoRng + std::marker::Send>(
|
||||||
&self,
|
&self,
|
||||||
_rng: &mut R,
|
rng: &mut R,
|
||||||
_transaction: SignableTransaction,
|
transaction: SignableTransaction,
|
||||||
_included: &[u16]
|
included: &[u16]
|
||||||
) -> Result<(Vec<u8>, Vec<<Self::Output as OutputTrait>::Id>), CoinError> {
|
) -> Result<(Vec<u8>, Vec<<Self::Output as OutputTrait>::Id>), CoinError> {
|
||||||
todo!()
|
let attempt = transaction.3.clone().multisig(
|
||||||
|
rng,
|
||||||
|
&self.rpc,
|
||||||
|
(*transaction.0).clone(),
|
||||||
|
transaction.1.clone(),
|
||||||
|
transaction.2,
|
||||||
|
included.to_vec()
|
||||||
|
).await.map_err(|_| CoinError::ConnectionError)?;
|
||||||
|
|
||||||
|
/*
|
||||||
|
let tx = None;
|
||||||
|
self.rpc.publish_transaction(tx).await.map_err(|_| CoinError::ConnectionError)?;
|
||||||
|
Ok(
|
||||||
|
tx.hash().to_vec(),
|
||||||
|
tx.outputs.iter().map(|output| output.key.compress().to_bytes().collect())
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
Ok((vec![], vec![]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use rand_core::{RngCore, CryptoRng};
|
|||||||
|
|
||||||
use frost::{Curve, MultisigKeys};
|
use frost::{Curve, MultisigKeys};
|
||||||
|
|
||||||
|
pub(crate) use monero_serai::frost::Transcript;
|
||||||
|
|
||||||
mod coins;
|
mod coins;
|
||||||
mod wallet;
|
mod wallet;
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ pub trait Coin {
|
|||||||
async fn prepare_send(
|
async fn prepare_send(
|
||||||
&self,
|
&self,
|
||||||
keys: Arc<MultisigKeys<Self::Curve>>,
|
keys: Arc<MultisigKeys<Self::Curve>>,
|
||||||
label: Vec<u8>,
|
transcript: Transcript,
|
||||||
height: usize,
|
height: usize,
|
||||||
inputs: Vec<Self::Output>,
|
inputs: Vec<Self::Output>,
|
||||||
payments: &[(Self::Address, u64)]
|
payments: &[(Self::Address, u64)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::rc::Rc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
|
||||||
@@ -11,6 +11,6 @@ async fn test() {
|
|||||||
let mut keys = frost::tests::key_gen::<_, <Monero as Coin>::Curve>(&mut OsRng);
|
let mut keys = frost::tests::key_gen::<_, <Monero as Coin>::Curve>(&mut OsRng);
|
||||||
let mut wallet = Wallet::new(MemCoinDb::new(), monero);
|
let mut wallet = Wallet::new(MemCoinDb::new(), monero);
|
||||||
wallet.acknowledge_height(0, 0);
|
wallet.acknowledge_height(0, 0);
|
||||||
wallet.add_keys(&WalletKeys::new(Rc::try_unwrap(keys.remove(&1).take().unwrap()).unwrap(), 0));
|
wallet.add_keys(&WalletKeys::new(Arc::try_unwrap(keys.remove(&1).take().unwrap()).unwrap(), 0));
|
||||||
dbg!(0);
|
dbg!(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use std::{sync::Arc, collections::HashMap};
|
use std::{sync::Arc, collections::HashMap};
|
||||||
|
|
||||||
use transcript::{Transcript, DigestTranscript};
|
use transcript::Transcript as TranscriptTrait;
|
||||||
|
|
||||||
use frost::{Curve, MultisigKeys};
|
use frost::{Curve, MultisigKeys};
|
||||||
|
|
||||||
use crate::{CoinError, Output, Coin};
|
use crate::{Transcript, CoinError, Output, Coin};
|
||||||
|
|
||||||
pub struct WalletKeys<C: Curve> {
|
pub struct WalletKeys<C: Curve> {
|
||||||
keys: MultisigKeys<C>,
|
keys: MultisigKeys<C>,
|
||||||
@@ -25,7 +26,7 @@ impl<C: Curve> WalletKeys<C> {
|
|||||||
// function as well, although that degree of influence means key gen is broken already
|
// function as well, although that degree of influence means key gen is broken already
|
||||||
fn bind(&self, chain: &[u8]) -> MultisigKeys<C> {
|
fn bind(&self, chain: &[u8]) -> MultisigKeys<C> {
|
||||||
const DST: &[u8] = b"Serai Processor Wallet Chain Bind";
|
const DST: &[u8] = b"Serai Processor Wallet Chain Bind";
|
||||||
let mut transcript = DigestTranscript::<blake2::Blake2b512>::new(DST);
|
let mut transcript = Transcript::new(DST);
|
||||||
transcript.append_message(b"chain", chain);
|
transcript.append_message(b"chain", chain);
|
||||||
transcript.append_message(b"curve", C::ID);
|
transcript.append_message(b"curve", C::ID);
|
||||||
transcript.append_message(b"group_key", &C::G_to_bytes(&self.keys.group_key()));
|
transcript.append_message(b"group_key", &C::G_to_bytes(&self.keys.group_key()));
|
||||||
@@ -223,13 +224,22 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||||||
let inputs = outputs.drain(.. inputs.len()).collect();
|
let inputs = outputs.drain(.. inputs.len()).collect();
|
||||||
let payments = payments.drain(.. these_payments.len()).collect::<Vec<_>>();
|
let payments = payments.drain(.. these_payments.len()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut transcript = Transcript::new(b"Serai Processor Wallet Send");
|
||||||
|
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()
|
||||||
|
);
|
||||||
let tx = self.coin.prepare_send(
|
let tx = self.coin.prepare_send(
|
||||||
keys.clone(),
|
keys.clone(),
|
||||||
format!(
|
transcript,
|
||||||
"Serai Processor Wallet Send (height {}, index {})",
|
|
||||||
canonical,
|
|
||||||
txs.len()
|
|
||||||
).as_bytes().to_vec(),
|
|
||||||
acknowledged_height,
|
acknowledged_height,
|
||||||
inputs,
|
inputs,
|
||||||
&payments
|
&payments
|
||||||
|
|||||||
Reference in New Issue
Block a user