mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-12 05:59:23 +00:00
Remove the DecoySelection trait
This commit is contained in:
@@ -17,7 +17,6 @@ use frost::FrostError;
|
||||
use crate::{
|
||||
io::*,
|
||||
generators::{MAX_COMMITMENTS, hash_to_point},
|
||||
primitives::Decoys,
|
||||
ringct::{
|
||||
clsag::{ClsagError, ClsagContext, Clsag},
|
||||
RctType, RctPrunable, RctProofs,
|
||||
@@ -26,7 +25,7 @@ use crate::{
|
||||
extra::MAX_ARBITRARY_DATA_SIZE,
|
||||
address::{Network, MoneroAddress},
|
||||
rpc::FeeRate,
|
||||
ViewPair, GuaranteedViewPair, WalletOutput,
|
||||
ViewPair, GuaranteedViewPair, OutputWithDecoys,
|
||||
};
|
||||
|
||||
mod tx_keys;
|
||||
@@ -231,7 +230,7 @@ pub enum SendError {
|
||||
pub struct SignableTransaction {
|
||||
rct_type: RctType,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
inputs: Vec<(WalletOutput, Decoys)>,
|
||||
inputs: Vec<OutputWithDecoys>,
|
||||
payments: Vec<InternalPayment>,
|
||||
data: Vec<Vec<u8>>,
|
||||
fee_rate: FeeRate,
|
||||
@@ -252,9 +251,9 @@ impl SignableTransaction {
|
||||
if self.inputs.is_empty() {
|
||||
Err(SendError::NoInputs)?;
|
||||
}
|
||||
for (_, decoys) in &self.inputs {
|
||||
for input in &self.inputs {
|
||||
// TODO: Add a function for the ring length
|
||||
if decoys.len() !=
|
||||
if input.decoys().len() !=
|
||||
match self.rct_type {
|
||||
RctType::ClsagBulletproof => 11,
|
||||
RctType::ClsagBulletproofPlus => 16,
|
||||
@@ -314,7 +313,7 @@ impl SignableTransaction {
|
||||
}
|
||||
|
||||
// Make sure we have enough funds
|
||||
let in_amount = self.inputs.iter().map(|(input, _)| input.commitment().amount).sum::<u64>();
|
||||
let in_amount = self.inputs.iter().map(|input| input.commitment().amount).sum::<u64>();
|
||||
let payments_amount = self
|
||||
.payments
|
||||
.iter()
|
||||
@@ -356,7 +355,7 @@ impl SignableTransaction {
|
||||
pub fn new(
|
||||
rct_type: RctType,
|
||||
outgoing_view_key: Zeroizing<[u8; 32]>,
|
||||
inputs: Vec<(WalletOutput, Decoys)>,
|
||||
inputs: Vec<OutputWithDecoys>,
|
||||
payments: Vec<(MoneroAddress, u64)>,
|
||||
change: Change,
|
||||
data: Vec<Vec<u8>>,
|
||||
@@ -406,11 +405,6 @@ impl SignableTransaction {
|
||||
/// This is not a Monero protocol defined struct, and this is accordingly not a Monero protocol
|
||||
/// defined serialization.
|
||||
pub fn write<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
fn write_input<W: io::Write>(input: &(WalletOutput, Decoys), w: &mut W) -> io::Result<()> {
|
||||
input.0.write(w)?;
|
||||
input.1.write(w)
|
||||
}
|
||||
|
||||
fn write_payment<W: io::Write>(payment: &InternalPayment, w: &mut W) -> io::Result<()> {
|
||||
match payment {
|
||||
InternalPayment::Payment(addr, amount) => {
|
||||
@@ -433,7 +427,7 @@ impl SignableTransaction {
|
||||
|
||||
write_byte(&u8::from(self.rct_type), w)?;
|
||||
w.write_all(self.outgoing_view_key.as_slice())?;
|
||||
write_vec(write_input, &self.inputs, w)?;
|
||||
write_vec(OutputWithDecoys::write, &self.inputs, w)?;
|
||||
write_vec(write_payment, &self.payments, w)?;
|
||||
write_vec(|data, w| write_vec(write_byte, data, w), &self.data, w)?;
|
||||
self.fee_rate.write(w)
|
||||
@@ -454,10 +448,6 @@ impl SignableTransaction {
|
||||
/// This is not a Monero protocol defined struct, and this is accordingly not a Monero protocol
|
||||
/// defined serialization.
|
||||
pub fn read<R: io::Read>(r: &mut R) -> io::Result<SignableTransaction> {
|
||||
fn read_input(r: &mut impl io::Read) -> io::Result<(WalletOutput, Decoys)> {
|
||||
Ok((WalletOutput::read(r)?, Decoys::read(r)?))
|
||||
}
|
||||
|
||||
fn read_address<R: io::Read>(r: &mut R) -> io::Result<MoneroAddress> {
|
||||
String::from_utf8(read_vec(read_byte, r)?)
|
||||
.ok()
|
||||
@@ -484,7 +474,7 @@ impl SignableTransaction {
|
||||
rct_type: RctType::try_from(read_byte(r)?)
|
||||
.map_err(|()| io::Error::other("unsupported/invalid RctType"))?,
|
||||
outgoing_view_key: Zeroizing::new(read_bytes(r)?),
|
||||
inputs: read_vec(read_input, r)?,
|
||||
inputs: read_vec(OutputWithDecoys::read, r)?,
|
||||
payments: read_vec(read_payment, r)?,
|
||||
data: read_vec(|r| read_vec(read_byte, r), r)?,
|
||||
fee_rate: FeeRate::read(r)?,
|
||||
@@ -522,7 +512,7 @@ impl SignableTransaction {
|
||||
) -> Result<Transaction, SendError> {
|
||||
// Calculate the key images
|
||||
let mut key_images = vec![];
|
||||
for (input, _) in &self.inputs {
|
||||
for input in &self.inputs {
|
||||
let input_key = Zeroizing::new(sender_spend_key.deref() + input.key_offset());
|
||||
if (input_key.deref() * ED25519_BASEPOINT_TABLE) != input.key() {
|
||||
Err(SendError::WrongPrivateKey)?;
|
||||
@@ -536,12 +526,12 @@ impl SignableTransaction {
|
||||
|
||||
// Prepare the CLSAG signatures
|
||||
let mut clsag_signs = Vec::with_capacity(tx.intent.inputs.len());
|
||||
for (input, decoys) in &tx.intent.inputs {
|
||||
for input in &tx.intent.inputs {
|
||||
// Re-derive the input key as this will be in a different order
|
||||
let input_key = Zeroizing::new(sender_spend_key.deref() + input.key_offset());
|
||||
clsag_signs.push((
|
||||
input_key,
|
||||
ClsagContext::new(decoys.clone(), input.commitment().clone())
|
||||
ClsagContext::new(input.decoys().clone(), input.commitment().clone())
|
||||
.map_err(SendError::ClsagError)?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -65,14 +65,14 @@ impl SignableTransaction {
|
||||
let mut clsags = vec![];
|
||||
|
||||
let mut key_image_generators_and_offsets = vec![];
|
||||
for (i, (input, decoys)) in self.inputs.iter().enumerate() {
|
||||
for input in &self.inputs {
|
||||
// Check this is the right set of keys
|
||||
let offset = keys.offset(dfg::Scalar(input.key_offset()));
|
||||
if offset.group_key().0 != input.key() {
|
||||
Err(SendError::WrongPrivateKey)?;
|
||||
}
|
||||
|
||||
let context = ClsagContext::new(decoys.clone(), input.commitment().clone())
|
||||
let context = ClsagContext::new(input.decoys().clone(), input.commitment().clone())
|
||||
.map_err(SendError::ClsagError)?;
|
||||
let (clsag, clsag_mask_send) = ClsagMultisig::new(
|
||||
RecommendedTranscript::new(b"Monero Multisignature Transaction"),
|
||||
@@ -80,7 +80,7 @@ impl SignableTransaction {
|
||||
);
|
||||
key_image_generators_and_offsets.push((
|
||||
clsag.key_image_generator(),
|
||||
keys.current_offset().unwrap_or(dfg::Scalar::ZERO).0 + self.inputs[i].0.key_offset(),
|
||||
keys.current_offset().unwrap_or(dfg::Scalar::ZERO).0 + input.key_offset(),
|
||||
));
|
||||
clsags.push((clsag_mask_send, AlgorithmMachine::new(clsag, offset)));
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ impl SignableTransaction {
|
||||
debug_assert_eq!(self.inputs.len(), key_images.len());
|
||||
|
||||
let mut res = Vec::with_capacity(self.inputs.len());
|
||||
for ((_, decoys), key_image) in self.inputs.iter().zip(key_images) {
|
||||
for (input, key_image) in self.inputs.iter().zip(key_images) {
|
||||
res.push(Input::ToKey {
|
||||
amount: None,
|
||||
key_offsets: decoys.offsets().to_vec(),
|
||||
key_offsets: input.decoys().offsets().to_vec(),
|
||||
key_image: *key_image,
|
||||
});
|
||||
}
|
||||
@@ -299,7 +299,7 @@ impl SignableTransactionWithKeyImages {
|
||||
} else {
|
||||
// If we don't have a change output, the difference is the fee
|
||||
let inputs =
|
||||
self.intent.inputs.iter().map(|input| input.0.commitment().amount).sum::<u64>();
|
||||
self.intent.inputs.iter().map(|input| input.commitment().amount).sum::<u64>();
|
||||
let payments = self
|
||||
.intent
|
||||
.payments
|
||||
|
||||
@@ -11,7 +11,7 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, Scalar, EdwardsPoint}
|
||||
use crate::{
|
||||
primitives::{keccak256, Commitment},
|
||||
ringct::EncryptedAmount,
|
||||
SharedKeyDerivations,
|
||||
SharedKeyDerivations, OutputWithDecoys,
|
||||
send::{InternalPayment, SignableTransaction, key_image_sort},
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ impl SignableTransaction {
|
||||
|
||||
// Ensure uniqueness across transactions by binding to a use-once object
|
||||
// The keys for the inputs is binding to their key images, making them use-once
|
||||
let mut input_keys = self.inputs.iter().map(|(input, _)| input.key()).collect::<Vec<_>>();
|
||||
let mut input_keys = self.inputs.iter().map(OutputWithDecoys::key).collect::<Vec<_>>();
|
||||
// We sort the inputs mid-way through TX construction, so apply our own sort to ensure a
|
||||
// consistent order
|
||||
// We use the key image sort as it's applicable and well-defined, not because these are key
|
||||
@@ -208,7 +208,7 @@ impl SignableTransaction {
|
||||
let amount = match payment {
|
||||
InternalPayment::Payment(_, amount) => *amount,
|
||||
InternalPayment::Change(_, _) => {
|
||||
let inputs = self.inputs.iter().map(|input| input.0.commitment().amount).sum::<u64>();
|
||||
let inputs = self.inputs.iter().map(|input| input.commitment().amount).sum::<u64>();
|
||||
let payments = self
|
||||
.payments
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user