mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
support add/read multiple arbitrary tx data (#189)
* support add/read multiple arbitrary tx data * fix clippy errors * resolve pr issues
This commit is contained in:
@@ -4,7 +4,10 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
use crate::{
|
||||
Protocol,
|
||||
wallet::{address::MoneroAddress, Fee, SpendableOutput, SignableTransaction, TransactionError},
|
||||
wallet::{
|
||||
address::MoneroAddress, Fee, SpendableOutput, SignableTransaction, TransactionError,
|
||||
extra::MAX_TX_EXTRA_NONCE_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
||||
@@ -15,14 +18,14 @@ struct SignableTransactionBuilderInternal {
|
||||
inputs: Vec<SpendableOutput>,
|
||||
payments: Vec<(MoneroAddress, u64)>,
|
||||
change_address: Option<MoneroAddress>,
|
||||
data: Option<Vec<u8>>,
|
||||
data: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl SignableTransactionBuilderInternal {
|
||||
// Takes in the change address so users don't miss that they have to manually set one
|
||||
// If they don't, all leftover funds will become part of the fee
|
||||
fn new(protocol: Protocol, fee: Fee, change_address: Option<MoneroAddress>) -> Self {
|
||||
Self { protocol, fee, inputs: vec![], payments: vec![], change_address, data: None }
|
||||
Self { protocol, fee, inputs: vec![], payments: vec![], change_address, data: vec![] }
|
||||
}
|
||||
|
||||
fn add_input(&mut self, input: SpendableOutput) {
|
||||
@@ -39,8 +42,8 @@ impl SignableTransactionBuilderInternal {
|
||||
self.payments.extend(payments);
|
||||
}
|
||||
|
||||
fn set_data(&mut self, data: Vec<u8>) {
|
||||
self.data = Some(data);
|
||||
fn add_data(&mut self, data: Vec<u8>) {
|
||||
self.data.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,9 +103,12 @@ impl SignableTransactionBuilder {
|
||||
self.shallow_copy()
|
||||
}
|
||||
|
||||
pub fn set_data(&mut self, data: Vec<u8>) -> Self {
|
||||
self.0.write().unwrap().set_data(data);
|
||||
self.shallow_copy()
|
||||
pub fn add_data(&mut self, data: Vec<u8>) -> Result<Self, TransactionError> {
|
||||
if data.len() > MAX_TX_EXTRA_NONCE_SIZE {
|
||||
Err(TransactionError::TooMuchData)?;
|
||||
}
|
||||
self.0.write().unwrap().add_data(data);
|
||||
Ok(self.shallow_copy())
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<SignableTransaction, TransactionError> {
|
||||
|
||||
@@ -24,7 +24,7 @@ use crate::{
|
||||
rpc::{Rpc, RpcError},
|
||||
wallet::{
|
||||
address::MoneroAddress, SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort,
|
||||
uniqueness, shared_key, commitment_mask, amount_encryption,
|
||||
uniqueness, shared_key, commitment_mask, amount_encryption, extra::MAX_TX_EXTRA_NONCE_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -177,7 +177,7 @@ pub struct SignableTransaction {
|
||||
protocol: Protocol,
|
||||
inputs: Vec<SpendableOutput>,
|
||||
payments: Vec<(MoneroAddress, u64)>,
|
||||
data: Option<Vec<u8>>,
|
||||
data: Vec<Vec<u8>>,
|
||||
fee: u64,
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ impl SignableTransaction {
|
||||
inputs: Vec<SpendableOutput>,
|
||||
mut payments: Vec<(MoneroAddress, u64)>,
|
||||
change_address: Option<MoneroAddress>,
|
||||
data: Option<Vec<u8>>,
|
||||
data: Vec<Vec<u8>>,
|
||||
fee_rate: Fee,
|
||||
) -> Result<SignableTransaction, TransactionError> {
|
||||
// Make sure there's only one payment ID
|
||||
@@ -220,8 +220,10 @@ impl SignableTransaction {
|
||||
Err(TransactionError::NoOutputs)?;
|
||||
}
|
||||
|
||||
if data.as_ref().map(|v| v.len()).unwrap_or(0) > 255 {
|
||||
Err(TransactionError::TooMuchData)?;
|
||||
for part in &data {
|
||||
if part.len() > MAX_TX_EXTRA_NONCE_SIZE {
|
||||
Err(TransactionError::TooMuchData)?;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO TX MAX SIZE
|
||||
@@ -313,8 +315,8 @@ impl SignableTransaction {
|
||||
extra.push(ExtraField::Nonce(id_vec));
|
||||
|
||||
// Include data if present
|
||||
if let Some(data) = self.data.take() {
|
||||
extra.push(ExtraField::Nonce(data));
|
||||
for part in self.data.drain(..) {
|
||||
extra.push(ExtraField::Nonce(part));
|
||||
}
|
||||
|
||||
let mut serialized = Vec::with_capacity(Extra::fee_weight(outputs.len(), self.data.as_ref()));
|
||||
|
||||
Reference in New Issue
Block a user