mirror of
https://github.com/lightninglabs/pool.git
synced 2026-08-18 13:08:33 +02:00
order+rpcserver: use account version in fee estimation
This commit is contained in:
parent
a6c18a9bb1
commit
1e7c00a586
5 changed files with 54 additions and 18 deletions
|
|
@ -230,7 +230,7 @@ func (v *batchVerifier) Verify(batch *Batch, bestHeight uint32) error {
|
|||
|
||||
// Now that we know how many channels were created from the
|
||||
// given account, let's also account for the chain fees.
|
||||
tally.ChainFees(batch.BatchTxFeeRate)
|
||||
tally.ChainFees(batch.BatchTxFeeRate, acct.Version)
|
||||
|
||||
// Even if the account output is dust, we should arrive at the
|
||||
// same number with our tally as the server.
|
||||
|
|
|
|||
|
|
@ -275,8 +275,12 @@ type Order interface {
|
|||
Digest() ([hashSize]byte, error)
|
||||
|
||||
// ReservedValue returns the maximum value that could be deducted from
|
||||
// the account if the order is is matched, and therefore has to be
|
||||
// reserved to ensure the trader can afford it.
|
||||
// the account if the order is matched, and therefore has to be
|
||||
// reserved to ensure the trader can afford it. This always uses the
|
||||
// worst-case fee estimation using the version 0 p2wsh script witness
|
||||
// size calculation for the account spend.
|
||||
//
|
||||
// TODO(guggero): Update to be more precise for p2tr accounts.
|
||||
ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount
|
||||
}
|
||||
|
||||
|
|
@ -453,10 +457,13 @@ func (a *Ask) Digest() ([hashSize]byte, error) {
|
|||
// account if the given order is matched under the worst case fee conditions.
|
||||
// This usually means the order is partially matched with the minimum match
|
||||
// size, all in different batches, leading to maximum chain and execution fees
|
||||
// being paid.
|
||||
// being paid. This always uses the worst-case fee estimation using the version
|
||||
// 0 p2wsh script witness size calculation for the account spend.
|
||||
//
|
||||
// The passed function should be set to either calculate the maker or taker
|
||||
// balance delta for a single match of the given amount.
|
||||
//
|
||||
// TODO(guggero): Update to be more precise for p2tr accounts.
|
||||
func reservedValue(o Order,
|
||||
perMatchDelta func(btcutil.Amount) btcutil.Amount) btcutil.Amount {
|
||||
|
||||
|
|
@ -490,9 +497,13 @@ func reservedValue(o Order,
|
|||
|
||||
// Subtract the worst case chain fee from the balance.
|
||||
maxFeeRate := o.Details().MaxBatchFeeRate
|
||||
balanceDelta -= maxNumMatches * EstimateTraderFee(1, maxFeeRate)
|
||||
balanceDelta -= maxNumMatches * EstimateTraderFee(
|
||||
1, maxFeeRate, account.VersionInitialNoVersion,
|
||||
)
|
||||
if rem > 0 {
|
||||
balanceDelta -= EstimateTraderFee(1, maxFeeRate)
|
||||
balanceDelta -= EstimateTraderFee(
|
||||
1, maxFeeRate, account.VersionInitialNoVersion,
|
||||
)
|
||||
}
|
||||
|
||||
// If the balance delta is negative, meaning this order will decrease
|
||||
|
|
@ -507,7 +518,7 @@ func reservedValue(o Order,
|
|||
}
|
||||
|
||||
// ReservedValue returns the maximum value that could be deducted from a single
|
||||
// account if the ask is is matched under the worst case fee conditions.
|
||||
// account if the ask is matched under the worst case fee conditions.
|
||||
func (a *Ask) ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount {
|
||||
// For an ask the clearing price will be no lower than the ask's fixed
|
||||
// rate, resulting in the smallest gain for the asker.
|
||||
|
|
@ -681,7 +692,7 @@ func (b *Bid) Digest() ([hashSize]byte, error) {
|
|||
}
|
||||
|
||||
// ReservedValue returns the maximum value that could be deducted from a single
|
||||
// account if the bid is is matched under the worst case fee conditions.
|
||||
// account if the bid is matched under the worst case fee conditions.
|
||||
func (b *Bid) ReservedValue(feeSchedule terms.FeeSchedule) btcutil.Amount {
|
||||
// For a bid, the final clearing price is never higher that the bid's
|
||||
// fixed rate, resulting in the highest possible premium paid by the
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/lightninglabs/pool/account"
|
||||
"github.com/lightninglabs/pool/terms"
|
||||
)
|
||||
|
||||
|
|
@ -15,8 +16,9 @@ func TestOrderReservedValue(t *testing.T) {
|
|||
simpleFeeSchedule := terms.NewLinearFeeSchedule(1, 100)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
order Order
|
||||
name string
|
||||
order Order
|
||||
accountVersion account.Version
|
||||
}{
|
||||
{
|
||||
name: "bid 1 unit",
|
||||
|
|
@ -236,7 +238,7 @@ func TestOrderReservedValue(t *testing.T) {
|
|||
LumpSumPremium(amt, o.LeaseDuration)
|
||||
exeFee := executionFee(amt, simpleFeeSchedule)
|
||||
chainFee := EstimateTraderFee(
|
||||
1, o.MaxBatchFeeRate,
|
||||
1, o.MaxBatchFeeRate, tc.accountVersion,
|
||||
)
|
||||
|
||||
// For bids the lump sum, chain fee and the
|
||||
|
|
@ -274,7 +276,7 @@ func TestOrderReservedValue(t *testing.T) {
|
|||
LumpSumPremium(amt, 144)
|
||||
exeFee := executionFee(amt, simpleFeeSchedule)
|
||||
chainFee := EstimateTraderFee(
|
||||
1, o.MaxBatchFeeRate,
|
||||
1, o.MaxBatchFeeRate, tc.accountVersion,
|
||||
)
|
||||
|
||||
// For asks the amount itself, the chain fee
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package order
|
|||
import (
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/lightninglabs/pool/account"
|
||||
"github.com/lightninglabs/pool/poolscript"
|
||||
"github.com/lightninglabs/pool/terms"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
|
|
@ -65,8 +66,8 @@ func PerBlockPremium(amt btcutil.Amount, fixedRate uint32) float64 {
|
|||
// EstimateTraderFee calculates the chain fees a trader has to pay for their
|
||||
// part of a batch transaction. The more outputs a trader creates (channels),
|
||||
// the higher fee they will pay.
|
||||
func EstimateTraderFee(numTraderChans uint32,
|
||||
feeRate chainfee.SatPerKWeight) btcutil.Amount {
|
||||
func EstimateTraderFee(numTraderChans uint32, feeRate chainfee.SatPerKWeight,
|
||||
accountVersion account.Version) btcutil.Amount {
|
||||
|
||||
var weightEstimate int64
|
||||
|
||||
|
|
@ -90,7 +91,13 @@ func EstimateTraderFee(numTraderChans uint32,
|
|||
|
||||
// Finally, we tack on the size of the witness spending the account
|
||||
// outpoint.
|
||||
weightEstimate += poolscript.MultiSigWitnessSize
|
||||
switch accountVersion {
|
||||
case account.VersionTaprootEnabled:
|
||||
weightEstimate += poolscript.TaprootMultiSigWitnessSize
|
||||
|
||||
default:
|
||||
weightEstimate += poolscript.MultiSigWitnessSize
|
||||
}
|
||||
|
||||
return feeRate.FeeForWeight(weightEstimate)
|
||||
}
|
||||
|
|
@ -124,7 +131,12 @@ func NewQuote(amt, minChanAmt btcutil.Amount, rate FixedRatePremium,
|
|||
exeFee := schedule.BaseFee() + schedule.ExecutionFee(amt)
|
||||
|
||||
maxNumMatches := amt / minChanAmt
|
||||
chainFee := maxNumMatches * EstimateTraderFee(1, maxBatchFeeRate)
|
||||
|
||||
// For an order quote we always return the worst case fees, which means
|
||||
// with a legacy account.
|
||||
chainFee := maxNumMatches * EstimateTraderFee(
|
||||
1, maxBatchFeeRate, account.VersionInitialNoVersion,
|
||||
)
|
||||
|
||||
return &Quote{
|
||||
TotalPremium: rate.LumpSumPremium(amt, leaseDuration),
|
||||
|
|
@ -251,8 +263,12 @@ func (t *AccountTally) CalcTakerDelta(feeSchedule terms.FeeSchedule,
|
|||
// ChainFees estimates the chain fees that need to be paid for the number of
|
||||
// channels created for this account and subtracts that value from the ending
|
||||
// balance.
|
||||
func (t *AccountTally) ChainFees(feeRate chainfee.SatPerKWeight) {
|
||||
chainFeesDue := EstimateTraderFee(t.NumChansCreated, feeRate)
|
||||
func (t *AccountTally) ChainFees(feeRate chainfee.SatPerKWeight,
|
||||
accountVersion account.Version) {
|
||||
|
||||
chainFeesDue := EstimateTraderFee(
|
||||
t.NumChansCreated, feeRate, accountVersion,
|
||||
)
|
||||
t.EndingBalance -= chainFeesDue
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2270,8 +2270,15 @@ func (s *rpcServer) prepareLeasesResponse(ctx context.Context,
|
|||
|
||||
// Estimate the chain fees paid for the number of
|
||||
// channels created in this batch and tally them.
|
||||
//
|
||||
// TODO(guggero): This is just an approximation! We
|
||||
// should properly calculate the fees _per account_ as
|
||||
// that's what we do on the server side. Then we can
|
||||
// also take a look at the actual account version at the
|
||||
// time of the batch.
|
||||
chainFee := order.EstimateTraderFee(
|
||||
uint32(numChans), batch.BatchTxFeeRate,
|
||||
account.VersionInitialNoVersion,
|
||||
)
|
||||
|
||||
// We'll need to compute the chain fee paid for each
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue