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