mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-10 21:04:40 +00:00
Fix Monero's Extra::fee_weight and handling of data limits
This commit is contained in:
parent
c182b804bc
commit
534e1bb11d
3 changed files with 20 additions and 11 deletions
|
@ -172,15 +172,20 @@ impl Extra {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub(crate) fn fee_weight(outputs: usize, payment_id: bool, data: &[Vec<u8>]) -> usize {
|
||||
pub(crate) fn fee_weight(
|
||||
outputs: usize,
|
||||
additional: bool,
|
||||
payment_id: bool,
|
||||
data: &[Vec<u8>]
|
||||
) -> usize {
|
||||
// PublicKey, key
|
||||
(1 + 32) +
|
||||
// PublicKeys, length, additional keys
|
||||
(1 + 1 + (outputs.saturating_sub(1) * 32)) +
|
||||
(if additional { 1 + 1 + (outputs * 32) } else { 0 }) +
|
||||
// PaymentId (Nonce), length, encrypted, ID
|
||||
(if payment_id { 1 + 1 + 1 + 8 } else { 0 }) +
|
||||
// Nonce, length, data (if existent)
|
||||
data.iter().map(|v| 1 + varint_len(v.len()) + v.len()).sum::<usize>()
|
||||
// Nonce, length, ARBITRARY_DATA_MARKER, data
|
||||
data.iter().map(|v| 1 + varint_len(1 + v.len()) + 1 + v.len()).sum::<usize>()
|
||||
}
|
||||
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
|
|
|
@ -337,7 +337,8 @@ impl SignableTransaction {
|
|||
has_payment_id |= outputs == 2;
|
||||
|
||||
// Calculate the extra length
|
||||
let extra = Extra::fee_weight(outputs, has_payment_id, data.as_ref());
|
||||
// Assume additional keys are needed in order to cause a worst-case estimation
|
||||
let extra = Extra::fee_weight(outputs, true, has_payment_id, data.as_ref());
|
||||
|
||||
// https://github.com/monero-project/monero/pull/8733
|
||||
const MAX_EXTRA_SIZE: usize = 1060;
|
||||
|
@ -541,7 +542,7 @@ impl SignableTransaction {
|
|||
}
|
||||
|
||||
// Include data if present
|
||||
let extra_len = Extra::fee_weight(Rs_len, id.is_some(), data.as_ref());
|
||||
let extra_len = Extra::fee_weight(Rs_len, additional, id.is_some(), data.as_ref());
|
||||
for part in data.drain(..) {
|
||||
let mut arb = vec![ARBITRARY_DATA_MARKER];
|
||||
arb.extend(part);
|
||||
|
|
|
@ -30,10 +30,13 @@ test!(
|
|||
add_multiple_data_less_than_max,
|
||||
(
|
||||
|_, mut builder: Builder, addr| async move {
|
||||
let data = vec![b'\0'; MAX_ARBITRARY_DATA_SIZE - 1];
|
||||
let mut data = vec![];
|
||||
for b in 1 ..= 3 {
|
||||
data.push(vec![b; MAX_ARBITRARY_DATA_SIZE - 1]);
|
||||
}
|
||||
|
||||
// Add tx multiple times
|
||||
for _ in 0 .. 5 {
|
||||
// Add data multiple times
|
||||
for data in &data {
|
||||
let result = builder.add_data(data.clone());
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
@ -41,10 +44,10 @@ test!(
|
|||
builder.add_payment(addr, 5);
|
||||
(builder.build().unwrap(), data)
|
||||
},
|
||||
|_, tx: Transaction, mut scanner: Scanner, data: Vec<u8>| async move {
|
||||
|_, tx: Transaction, mut scanner: Scanner, data: Vec<Vec<u8>>| async move {
|
||||
let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0);
|
||||
assert_eq!(output.commitment().amount, 5);
|
||||
assert_eq!(output.arbitrary_data(), vec![data; 5]);
|
||||
assert_eq!(output.arbitrary_data(), data);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue