mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-23 03:59:22 +00:00
Update BP fee_weight
Closes https://github.com/serai-dex/serai/issues/8.
This commit is contained in:
parent
755d021f8e
commit
60d93c4b2d
5 changed files with 37 additions and 33 deletions
|
@ -11,6 +11,7 @@ use crate::{Commitment, wallet::TransactionError, serialize::*};
|
|||
|
||||
pub(crate) mod scalar_vector;
|
||||
pub(crate) mod core;
|
||||
use self::core::LOG_N;
|
||||
|
||||
pub(crate) mod original;
|
||||
pub(crate) mod plus;
|
||||
|
@ -28,19 +29,23 @@ pub enum Bulletproofs {
|
|||
}
|
||||
|
||||
impl Bulletproofs {
|
||||
// TODO
|
||||
pub(crate) fn fee_weight(outputs: usize) -> usize {
|
||||
let proofs = 6 + usize::try_from(usize::BITS - (outputs - 1).leading_zeros()).unwrap();
|
||||
let len = (9 + (2 * proofs)) * 32;
|
||||
pub(crate) fn fee_weight(plus: bool, outputs: usize) -> usize {
|
||||
let fields = if plus { 6 } else { 9 };
|
||||
|
||||
let mut clawback = 0;
|
||||
let padded = 1 << (proofs - 6);
|
||||
if padded > 2 {
|
||||
const BP_BASE: usize = 368;
|
||||
clawback = ((BP_BASE * padded) - len) * 4 / 5;
|
||||
#[allow(non_snake_case)]
|
||||
let mut LR_len = usize::try_from(usize::BITS - (outputs - 1).leading_zeros()).unwrap();
|
||||
let padded_outputs = 1 << LR_len;
|
||||
LR_len += LOG_N;
|
||||
|
||||
let len = (fields + (2 * LR_len)) * 32;
|
||||
len +
|
||||
if padded_outputs <= 2 {
|
||||
0
|
||||
} else {
|
||||
let base = ((fields + (2 * (LOG_N + 1))) * 32) / 2;
|
||||
let size = (fields + (2 * LR_len)) * 32;
|
||||
((base * padded_outputs) - size) * 4 / 5
|
||||
}
|
||||
|
||||
len + clawback
|
||||
}
|
||||
|
||||
pub fn prove<R: RngCore + CryptoRng>(
|
||||
|
|
|
@ -9,6 +9,7 @@ pub mod clsag;
|
|||
pub mod bulletproofs;
|
||||
|
||||
use crate::{
|
||||
Protocol,
|
||||
serialize::*,
|
||||
ringct::{clsag::Clsag, bulletproofs::Bulletproofs},
|
||||
};
|
||||
|
@ -86,8 +87,9 @@ impl RctPrunable {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn fee_weight(ring_len: usize, inputs: usize, outputs: usize) -> usize {
|
||||
1 + Bulletproofs::fee_weight(outputs) + (inputs * (Clsag::fee_weight(ring_len) + 32))
|
||||
pub(crate) fn fee_weight(protocol: Protocol, inputs: usize, outputs: usize) -> usize {
|
||||
1 + Bulletproofs::fee_weight(protocol.bp_plus(), outputs) +
|
||||
(inputs * (Clsag::fee_weight(protocol.ring_len()) + 32))
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
|
@ -142,8 +144,8 @@ pub struct RctSignatures {
|
|||
}
|
||||
|
||||
impl RctSignatures {
|
||||
pub(crate) fn fee_weight(ring_len: usize, inputs: usize, outputs: usize) -> usize {
|
||||
RctBase::fee_weight(outputs) + RctPrunable::fee_weight(ring_len, inputs, outputs)
|
||||
pub(crate) fn fee_weight(protocol: Protocol, inputs: usize, outputs: usize) -> usize {
|
||||
RctBase::fee_weight(outputs) + RctPrunable::fee_weight(protocol, inputs, outputs)
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
|
|
|
@ -371,8 +371,7 @@ impl Rpc {
|
|||
)
|
||||
.await?;
|
||||
|
||||
// TODO: Support time based lock times. These shouldn't be needed, and it may be painful to
|
||||
// get the median time for the given height, yet we do need to in order to be complete
|
||||
// TODO: https://github.com/serai-dex/serai/issues/104
|
||||
outs
|
||||
.outs
|
||||
.iter()
|
||||
|
|
|
@ -5,7 +5,7 @@ use zeroize::Zeroize;
|
|||
use curve25519_dalek::edwards::EdwardsPoint;
|
||||
|
||||
use crate::{
|
||||
hash,
|
||||
Protocol, hash,
|
||||
serialize::*,
|
||||
ringct::{RctPrunable, RctSignatures},
|
||||
};
|
||||
|
@ -193,9 +193,14 @@ pub struct Transaction {
|
|||
}
|
||||
|
||||
impl Transaction {
|
||||
pub(crate) fn fee_weight(ring_len: usize, inputs: usize, outputs: usize, extra: usize) -> usize {
|
||||
TransactionPrefix::fee_weight(ring_len, inputs, outputs, extra) +
|
||||
RctSignatures::fee_weight(ring_len, inputs, outputs)
|
||||
pub(crate) fn fee_weight(
|
||||
protocol: Protocol,
|
||||
inputs: usize,
|
||||
outputs: usize,
|
||||
extra: usize,
|
||||
) -> usize {
|
||||
TransactionPrefix::fee_weight(protocol.ring_len(), inputs, outputs, extra) +
|
||||
RctSignatures::fee_weight(protocol, inputs, outputs)
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
|
|
|
@ -212,12 +212,8 @@ impl SignableTransaction {
|
|||
let extra = Extra::fee_weight(outputs);
|
||||
|
||||
// Calculate the fee.
|
||||
let mut fee = fee_rate.calculate(Transaction::fee_weight(
|
||||
protocol.ring_len(),
|
||||
inputs.len(),
|
||||
outputs,
|
||||
extra,
|
||||
));
|
||||
let mut fee =
|
||||
fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs, extra));
|
||||
|
||||
// Make sure we have enough funds
|
||||
let in_amount = inputs.iter().map(|input| input.commitment.amount).sum::<u64>();
|
||||
|
@ -229,12 +225,9 @@ impl SignableTransaction {
|
|||
// If we have yet to add a change output, do so if it's economically viable
|
||||
if (!change) && change_address.is_some() && (in_amount != out_amount) {
|
||||
// Check even with the new fee, there's remaining funds
|
||||
let change_fee = fee_rate.calculate(Transaction::fee_weight(
|
||||
protocol.ring_len(),
|
||||
inputs.len(),
|
||||
outputs + 1,
|
||||
extra,
|
||||
)) - fee;
|
||||
let change_fee =
|
||||
fee_rate.calculate(Transaction::fee_weight(protocol, inputs.len(), outputs + 1, extra)) -
|
||||
fee;
|
||||
if (out_amount + change_fee) < in_amount {
|
||||
change = true;
|
||||
out_amount += change_fee;
|
||||
|
|
Loading…
Reference in a new issue