mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
Sync rest of repo with monero-serai changes
This commit is contained in:
@@ -33,6 +33,7 @@ pub use eventuality::Eventuality;
|
||||
|
||||
#[cfg(feature = "multisig")]
|
||||
mod multisig;
|
||||
pub use multisig::TransactionMachine;
|
||||
|
||||
pub(crate) fn key_image_sort(x: &EdwardsPoint, y: &EdwardsPoint) -> core::cmp::Ordering {
|
||||
x.compress().to_bytes().cmp(&y.compress().to_bytes()).reverse()
|
||||
@@ -164,8 +165,6 @@ pub enum SendError {
|
||||
error("not enough funds (inputs {inputs}, outputs {outputs}, fee {fee:?})")
|
||||
)]
|
||||
NotEnoughFunds { inputs: u64, outputs: u64, fee: Option<u64> },
|
||||
#[cfg_attr(feature = "std", error("invalid amount of key images specified"))]
|
||||
InvalidAmountOfKeyImages,
|
||||
#[cfg_attr(feature = "std", error("wrong spend private key"))]
|
||||
WrongPrivateKey,
|
||||
#[cfg_attr(
|
||||
@@ -183,7 +182,7 @@ pub enum SendError {
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||
pub struct SignableTransaction {
|
||||
rct_type: RctType,
|
||||
sender_view_key: Zeroizing<Scalar>,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
inputs: Vec<(SpendableOutput, Decoys)>,
|
||||
payments: Vec<InternalPayment>,
|
||||
data: Vec<Vec<u8>>,
|
||||
@@ -301,7 +300,7 @@ impl SignableTransaction {
|
||||
|
||||
pub fn new(
|
||||
rct_type: RctType,
|
||||
sender_view_key: Zeroizing<Scalar>,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
inputs: Vec<(SpendableOutput, Decoys)>,
|
||||
payments: Vec<(MoneroAddress, u64)>,
|
||||
change: Change,
|
||||
@@ -322,7 +321,7 @@ impl SignableTransaction {
|
||||
}
|
||||
|
||||
let mut res =
|
||||
SignableTransaction { rct_type, sender_view_key, inputs, payments, data, fee_rate };
|
||||
SignableTransaction { rct_type, outgoing_view_key, inputs, payments, data, fee_rate };
|
||||
res.validate()?;
|
||||
|
||||
// Shuffle the payments
|
||||
@@ -369,7 +368,7 @@ impl SignableTransaction {
|
||||
}
|
||||
|
||||
write_byte(&u8::from(self.rct_type), w)?;
|
||||
write_scalar(&self.sender_view_key, w)?;
|
||||
w.write_all(self.outgoing_view_key.as_slice())?;
|
||||
write_vec(write_input, &self.inputs, w)?;
|
||||
write_vec(write_payment, &self.payments, w)?;
|
||||
write_vec(|data, w| write_vec(write_byte, data, w), &self.data, w)?;
|
||||
@@ -412,7 +411,7 @@ impl SignableTransaction {
|
||||
let res = SignableTransaction {
|
||||
rct_type: RctType::try_from(read_byte(r)?)
|
||||
.map_err(|()| io::Error::other("unsupported/invalid RctType"))?,
|
||||
sender_view_key: Zeroizing::new(read_scalar(r)?),
|
||||
outgoing_view_key: Zeroizing::new(read_bytes(r)?),
|
||||
inputs: read_vec(read_input, r)?,
|
||||
payments: read_vec(read_payment, r)?,
|
||||
data: read_vec(|r| read_vec(read_byte, r), r)?,
|
||||
|
||||
@@ -16,14 +16,14 @@ use crate::{
|
||||
|
||||
fn seeded_rng(
|
||||
dst: &'static [u8],
|
||||
view_key: &Zeroizing<Scalar>,
|
||||
outgoing_view_key: &Zeroizing<[u8; 32]>,
|
||||
output_keys: impl Iterator<Item = EdwardsPoint>,
|
||||
) -> ChaCha20Rng {
|
||||
// Apply the DST
|
||||
let mut transcript = Zeroizing::new(vec![u8::try_from(dst.len()).unwrap()]);
|
||||
transcript.extend(dst);
|
||||
// Bind to the private view key to prevent foreign entities from rebuilding the transcript
|
||||
transcript.extend(view_key.to_bytes());
|
||||
// Bind to the outgoing view key to prevent foreign entities from rebuilding the transcript
|
||||
transcript.extend(outgoing_view_key.as_slice());
|
||||
// Ensure uniqueness across transactions by binding to a use-once object
|
||||
// The output key is also binding to the output's key image, making this use-once
|
||||
for key in output_keys {
|
||||
@@ -34,7 +34,11 @@ fn seeded_rng(
|
||||
|
||||
impl SignableTransaction {
|
||||
pub(crate) fn seeded_rng(&self, dst: &'static [u8]) -> ChaCha20Rng {
|
||||
seeded_rng(dst, &self.sender_view_key, self.inputs.iter().map(|(input, _)| input.output.key()))
|
||||
seeded_rng(
|
||||
dst,
|
||||
&self.outgoing_view_key,
|
||||
self.inputs.iter().map(|(input, _)| input.output.key()),
|
||||
)
|
||||
}
|
||||
|
||||
fn has_payments_to_subaddresses(&self) -> bool {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use zeroize::{Zeroize, Zeroizing};
|
||||
|
||||
use curve25519_dalek::Scalar;
|
||||
|
||||
use monero_wallet::{
|
||||
primitives::Decoys,
|
||||
ringct::RctType,
|
||||
@@ -16,7 +14,7 @@ use monero_wallet::{
|
||||
#[derive(Clone, PartialEq, Eq, Zeroize, Debug)]
|
||||
pub struct SignableTransactionBuilder {
|
||||
rct_type: RctType,
|
||||
sender_view_key: Zeroizing<Scalar>,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
inputs: Vec<(SpendableOutput, Decoys)>,
|
||||
payments: Vec<(MoneroAddress, u64)>,
|
||||
change: Change,
|
||||
@@ -27,13 +25,13 @@ pub struct SignableTransactionBuilder {
|
||||
impl SignableTransactionBuilder {
|
||||
pub fn new(
|
||||
rct_type: RctType,
|
||||
sender_view_key: Zeroizing<Scalar>,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
change: Change,
|
||||
fee_rate: FeeRate,
|
||||
) -> Self {
|
||||
Self {
|
||||
rct_type,
|
||||
sender_view_key,
|
||||
outgoing_view_key,
|
||||
inputs: vec![],
|
||||
payments: vec![],
|
||||
change,
|
||||
@@ -74,7 +72,7 @@ impl SignableTransactionBuilder {
|
||||
pub fn build(self) -> Result<SignableTransaction, SendError> {
|
||||
SignableTransaction::new(
|
||||
self.rct_type,
|
||||
self.sender_view_key,
|
||||
self.outgoing_view_key,
|
||||
self.inputs,
|
||||
self.payments,
|
||||
self.change,
|
||||
|
||||
@@ -169,7 +169,7 @@ macro_rules! test {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
use rand_core::OsRng;
|
||||
use rand_core::{RngCore, OsRng};
|
||||
|
||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar};
|
||||
|
||||
@@ -223,6 +223,8 @@ macro_rules! test {
|
||||
let rpc = rpc().await;
|
||||
|
||||
let view_priv = Zeroizing::new(Scalar::random(&mut OsRng));
|
||||
let mut outgoing_view = Zeroizing::new([0; 32]);
|
||||
OsRng.fill_bytes(outgoing_view.as_mut());
|
||||
let view = ViewPair::new(spend_pub, view_priv.clone());
|
||||
let addr = view.address(Network::Mainnet, AddressSpec::Legacy);
|
||||
|
||||
@@ -236,7 +238,7 @@ macro_rules! test {
|
||||
|
||||
let builder = SignableTransactionBuilder::new(
|
||||
rct_type,
|
||||
view_priv,
|
||||
outgoing_view,
|
||||
Change::new(
|
||||
&ViewPair::new(
|
||||
&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use rand_core::RngCore;
|
||||
|
||||
use monero_serai::transaction::Transaction;
|
||||
use monero_wallet::{rpc::Rpc, address::SubaddressIndex, extra::PaymentId};
|
||||
|
||||
|
||||
@@ -107,12 +107,14 @@ test!(
|
||||
use monero_wallet::rpc::FeePriority;
|
||||
|
||||
let view_priv = Zeroizing::new(Scalar::random(&mut OsRng));
|
||||
let mut outgoing_view = Zeroizing::new([0; 32]);
|
||||
OsRng.fill_bytes(outgoing_view.as_mut());
|
||||
let change_view =
|
||||
ViewPair::new(&Scalar::random(&mut OsRng) * ED25519_BASEPOINT_TABLE, view_priv.clone());
|
||||
|
||||
let mut builder = SignableTransactionBuilder::new(
|
||||
rct_type,
|
||||
view_priv,
|
||||
outgoing_view,
|
||||
Change::new(&change_view, false),
|
||||
rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(),
|
||||
);
|
||||
@@ -295,9 +297,11 @@ test!(
|
||||
|rct_type, rpc: SimpleRequestRpc, _, addr, outputs: Vec<ReceivedOutput>| async move {
|
||||
use monero_wallet::rpc::FeePriority;
|
||||
|
||||
let mut outgoing_view = Zeroizing::new([0; 32]);
|
||||
OsRng.fill_bytes(outgoing_view.as_mut());
|
||||
let mut builder = SignableTransactionBuilder::new(
|
||||
rct_type,
|
||||
Zeroizing::new(Scalar::random(&mut OsRng)),
|
||||
outgoing_view,
|
||||
Change::fingerprintable(None),
|
||||
rpc.get_fee_rate(FeePriority::Unimportant).await.unwrap(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user