mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-26 20:46:05 +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]
|
#[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
|
// PublicKey, key
|
||||||
(1 + 32) +
|
(1 + 32) +
|
||||||
// PublicKeys, length, additional keys
|
// PublicKeys, length, additional keys
|
||||||
(1 + 1 + (outputs.saturating_sub(1) * 32)) +
|
(if additional { 1 + 1 + (outputs * 32) } else { 0 }) +
|
||||||
// PaymentId (Nonce), length, encrypted, ID
|
// PaymentId (Nonce), length, encrypted, ID
|
||||||
(if payment_id { 1 + 1 + 1 + 8 } else { 0 }) +
|
(if payment_id { 1 + 1 + 1 + 8 } else { 0 }) +
|
||||||
// Nonce, length, data (if existent)
|
// Nonce, length, ARBITRARY_DATA_MARKER, data
|
||||||
data.iter().map(|v| 1 + varint_len(v.len()) + v.len()).sum::<usize>()
|
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<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
|
|
@ -337,7 +337,8 @@ impl SignableTransaction {
|
||||||
has_payment_id |= outputs == 2;
|
has_payment_id |= outputs == 2;
|
||||||
|
|
||||||
// Calculate the extra length
|
// 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
|
// https://github.com/monero-project/monero/pull/8733
|
||||||
const MAX_EXTRA_SIZE: usize = 1060;
|
const MAX_EXTRA_SIZE: usize = 1060;
|
||||||
|
@ -541,7 +542,7 @@ impl SignableTransaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include data if present
|
// 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(..) {
|
for part in data.drain(..) {
|
||||||
let mut arb = vec![ARBITRARY_DATA_MARKER];
|
let mut arb = vec![ARBITRARY_DATA_MARKER];
|
||||||
arb.extend(part);
|
arb.extend(part);
|
||||||
|
|
|
@ -30,10 +30,13 @@ test!(
|
||||||
add_multiple_data_less_than_max,
|
add_multiple_data_less_than_max,
|
||||||
(
|
(
|
||||||
|_, mut builder: Builder, addr| async move {
|
|_, 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
|
// Add data multiple times
|
||||||
for _ in 0 .. 5 {
|
for data in &data {
|
||||||
let result = builder.add_data(data.clone());
|
let result = builder.add_data(data.clone());
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
|
@ -41,10 +44,10 @@ test!(
|
||||||
builder.add_payment(addr, 5);
|
builder.add_payment(addr, 5);
|
||||||
(builder.build().unwrap(), data)
|
(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);
|
let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0);
|
||||||
assert_eq!(output.commitment().amount, 5);
|
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