Merge pull request #3653 from Roasbeef/external-funding-chainfees
chainfees: create new chainfees package extracting fees from lnwallet
This commit is contained in:
commit
4592f87033
@ -21,6 +21,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -78,7 +79,7 @@ type BreachConfig struct {
|
||||
// Estimator is used by the breach arbiter to determine an appropriate
|
||||
// fee level when generating, signing, and broadcasting sweep
|
||||
// transactions.
|
||||
Estimator lnwallet.FeeEstimator
|
||||
Estimator chainfee.Estimator
|
||||
|
||||
// GenSweepScript generates the receiving scripts for swept outputs.
|
||||
GenSweepScript func() ([]byte, error)
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
)
|
||||
@ -1675,7 +1676,7 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
|
||||
ba := newBreachArbiter(&BreachConfig{
|
||||
CloseLink: func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {},
|
||||
DB: db,
|
||||
Estimator: lnwallet.NewStaticFeeEstimator(12500, 0),
|
||||
Estimator: chainfee.NewStaticEstimator(12500, 0),
|
||||
GenSweepScript: func() ([]byte, error) { return nil, nil },
|
||||
ContractBreaches: contractBreaches,
|
||||
Signer: signer,
|
||||
@ -1824,7 +1825,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(12500, 0)
|
||||
estimator := chainfee.NewStaticEstimator(12500, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing/chainview"
|
||||
)
|
||||
@ -55,11 +56,11 @@ const (
|
||||
|
||||
// defaultBitcoinStaticFeePerKW is the fee rate of 50 sat/vbyte
|
||||
// expressed in sat/kw.
|
||||
defaultBitcoinStaticFeePerKW = lnwallet.SatPerKWeight(12500)
|
||||
defaultBitcoinStaticFeePerKW = chainfee.SatPerKWeight(12500)
|
||||
|
||||
// defaultLitecoinStaticFeePerKW is the fee rate of 200 sat/vbyte
|
||||
// expressed in sat/kw.
|
||||
defaultLitecoinStaticFeePerKW = lnwallet.SatPerKWeight(50000)
|
||||
defaultLitecoinStaticFeePerKW = chainfee.SatPerKWeight(50000)
|
||||
|
||||
// btcToLtcConversionRate is a fixed ratio used in order to scale up
|
||||
// payments when running on the Litecoin chain.
|
||||
@ -112,7 +113,7 @@ func (c chainCode) String() string {
|
||||
type chainControl struct {
|
||||
chainIO lnwallet.BlockChainIO
|
||||
|
||||
feeEstimator lnwallet.FeeEstimator
|
||||
feeEstimator chainfee.Estimator
|
||||
|
||||
signer input.Signer
|
||||
|
||||
@ -161,7 +162,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
FeeRate: cfg.Bitcoin.FeeRate,
|
||||
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
|
||||
}
|
||||
cc.feeEstimator = lnwallet.NewStaticFeeEstimator(
|
||||
cc.feeEstimator = chainfee.NewStaticEstimator(
|
||||
defaultBitcoinStaticFeePerKW, 0,
|
||||
)
|
||||
case litecoinChain:
|
||||
@ -171,7 +172,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
FeeRate: cfg.Litecoin.FeeRate,
|
||||
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
|
||||
}
|
||||
cc.feeEstimator = lnwallet.NewStaticFeeEstimator(
|
||||
cc.feeEstimator = chainfee.NewStaticEstimator(
|
||||
defaultLitecoinStaticFeePerKW, 0,
|
||||
)
|
||||
default:
|
||||
@ -219,8 +220,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
if cfg.NeutrinoMode.FeeURL != "" {
|
||||
ltndLog.Infof("Using API fee estimator!")
|
||||
|
||||
estimator := lnwallet.NewWebAPIFeeEstimator(
|
||||
lnwallet.SparseConfFeeSource{
|
||||
estimator := chainfee.NewWebAPIEstimator(
|
||||
chainfee.SparseConfFeeSource{
|
||||
URL: cfg.NeutrinoMode.FeeURL,
|
||||
},
|
||||
defaultBitcoinStaticFeePerKW,
|
||||
@ -323,8 +324,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
// if we're using bitcoind as a backend, then we can
|
||||
// use live fee estimates, rather than a statically
|
||||
// coded value.
|
||||
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
||||
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = chainfee.NewBitcoindEstimator(
|
||||
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||
)
|
||||
if err != nil {
|
||||
@ -340,8 +341,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
// if we're using litecoind as a backend, then we can
|
||||
// use live fee estimates, rather than a statically
|
||||
// coded value.
|
||||
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
||||
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = chainfee.NewBitcoindEstimator(
|
||||
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||
)
|
||||
if err != nil {
|
||||
@ -445,8 +446,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
// if we're using btcd as a backend, then we can use
|
||||
// live fee estimates, rather than a statically coded
|
||||
// value.
|
||||
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = lnwallet.NewBtcdFeeEstimator(
|
||||
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
|
||||
cc.feeEstimator, err = chainfee.NewBtcdEstimator(
|
||||
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -150,7 +151,7 @@ type channelCloser struct {
|
||||
// passed configuration, and delivery+fee preference. The final argument should
|
||||
// only be populated iff, we're the initiator of this closing request.
|
||||
func newChannelCloser(cfg chanCloseCfg, deliveryScript []byte,
|
||||
idealFeePerKw lnwallet.SatPerKWeight, negotiationHeight uint32,
|
||||
idealFeePerKw chainfee.SatPerKWeight, negotiationHeight uint32,
|
||||
closeReq *htlcswitch.ChanClose) *channelCloser {
|
||||
|
||||
// Given the target fee-per-kw, we'll compute what our ideal _total_
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
)
|
||||
@ -131,7 +132,7 @@ type ChainArbitratorConfig struct {
|
||||
Signer input.Signer
|
||||
|
||||
// FeeEstimator will be used to return fee estimates.
|
||||
FeeEstimator lnwallet.FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// ChainIO allows us to query the state of the current main chain.
|
||||
ChainIO lnwallet.BlockChainIO
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"golang.org/x/crypto/salsa20"
|
||||
@ -230,7 +231,7 @@ type fundingConfig struct {
|
||||
|
||||
// FeeEstimator calculates appropriate fee rates based on historical
|
||||
// transaction information.
|
||||
FeeEstimator lnwallet.FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// Notifier is used by the FundingManager to determine when the
|
||||
// channel's funding transaction has been confirmed on the blockchain
|
||||
@ -1218,7 +1219,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
||||
NodeAddr: fmsg.peer.Address(),
|
||||
LocalFundingAmt: 0,
|
||||
RemoteFundingAmt: amt,
|
||||
CommitFeePerKw: lnwallet.SatPerKWeight(msg.FeePerKiloWeight),
|
||||
CommitFeePerKw: chainfee.SatPerKWeight(msg.FeePerKiloWeight),
|
||||
FundingFeePerKw: 0,
|
||||
PushMSat: msg.PushAmount,
|
||||
Flags: msg.ChannelFlags,
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -218,7 +219,7 @@ func createTestWallet(cdb *channeldb.DB, netParams *chaincfg.Params,
|
||||
notifier chainntnfs.ChainNotifier, wc lnwallet.WalletController,
|
||||
signer input.Signer, keyRing keychain.SecretKeyRing,
|
||||
bio lnwallet.BlockChainIO,
|
||||
estimator lnwallet.FeeEstimator) (*lnwallet.LightningWallet, error) {
|
||||
estimator chainfee.Estimator) (*lnwallet.LightningWallet, error) {
|
||||
|
||||
wallet, err := lnwallet.NewLightningWallet(lnwallet.Config{
|
||||
Database: cdb,
|
||||
@ -247,7 +248,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
||||
options ...cfgOption) (*testNode, error) {
|
||||
|
||||
netParams := activeNetParams.Params
|
||||
estimator := lnwallet.NewStaticFeeEstimator(62500, 0)
|
||||
estimator := chainfee.NewStaticEstimator(62500, 0)
|
||||
|
||||
chainNotifier := &mockNotifier{
|
||||
oneConfChannel: make(chan *chainntnfs.TxConfirmation, 1),
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/queue"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
@ -199,7 +200,7 @@ type ChannelLinkConfig struct {
|
||||
// FeeEstimator is an instance of a live fee estimator which will be
|
||||
// used to dynamically regulate the current fee of the commitment
|
||||
// transaction to ensure timely confirmation.
|
||||
FeeEstimator lnwallet.FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// hodl.Mask is a bitvector composed of hodl.Flags, specifying breakpoints
|
||||
// for HTLC forwarding internal to the switch.
|
||||
@ -570,7 +571,7 @@ func (l *channelLink) markReestablished() {
|
||||
// chain in a timely manner. The returned value is expressed in fee-per-kw, as
|
||||
// this is the native rate used when computing the fee for commitment
|
||||
// transactions, and the second-level HTLC transactions.
|
||||
func (l *channelLink) sampleNetworkFee() (lnwallet.SatPerKWeight, error) {
|
||||
func (l *channelLink) sampleNetworkFee() (chainfee.SatPerKWeight, error) {
|
||||
// We'll first query for the sat/kw recommended to be confirmed within 3
|
||||
// blocks.
|
||||
feePerKw, err := l.cfg.FeeEstimator.EstimateFeePerKW(3)
|
||||
@ -587,7 +588,7 @@ func (l *channelLink) sampleNetworkFee() (lnwallet.SatPerKWeight, error) {
|
||||
// shouldAdjustCommitFee returns true if we should update our commitment fee to
|
||||
// match that of the network fee. We'll only update our commitment fee if the
|
||||
// network fee is +/- 10% to our network fee.
|
||||
func shouldAdjustCommitFee(netFee, chanFee lnwallet.SatPerKWeight) bool {
|
||||
func shouldAdjustCommitFee(netFee, chanFee chainfee.SatPerKWeight) bool {
|
||||
switch {
|
||||
// If the network fee is greater than the commitment fee, then we'll
|
||||
// switch to it if it's at least 10% greater than the commit fee.
|
||||
@ -1061,7 +1062,7 @@ out:
|
||||
// fee rate to our max fee allocation.
|
||||
commitFee := l.channel.CommitFeeRate()
|
||||
maxFee := l.channel.MaxFeeRate(l.cfg.MaxFeeAllocation)
|
||||
newCommitFee := lnwallet.SatPerKWeight(
|
||||
newCommitFee := chainfee.SatPerKWeight(
|
||||
math.Min(float64(netFee), float64(maxFee)),
|
||||
)
|
||||
if !shouldAdjustCommitFee(newCommitFee, commitFee) {
|
||||
@ -1892,7 +1893,7 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
|
||||
case *lnwire.UpdateFee:
|
||||
// We received fee update from peer. If we are the initiator we
|
||||
// will fail the channel, if not we will apply the update.
|
||||
fee := lnwallet.SatPerKWeight(msg.FeePerKw)
|
||||
fee := chainfee.SatPerKWeight(msg.FeePerKw)
|
||||
if err := l.channel.ReceiveUpdateFee(fee); err != nil {
|
||||
l.fail(LinkFailureError{code: ErrInvalidUpdate},
|
||||
"error receiving fee update: %v", err)
|
||||
@ -2392,7 +2393,7 @@ func (l *channelLink) HandleChannelUpdate(message lnwire.Message) {
|
||||
|
||||
// updateChannelFee updates the commitment fee-per-kw on this channel by
|
||||
// committing to an update_fee message.
|
||||
func (l *channelLink) updateChannelFee(feePerKw lnwallet.SatPerKWeight) error {
|
||||
func (l *channelLink) updateChannelFee(feePerKw chainfee.SatPerKWeight) error {
|
||||
|
||||
l.log.Infof("updating commit fee to %v sat/kw", feePerKw)
|
||||
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
)
|
||||
@ -1959,7 +1960,7 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) {
|
||||
// incoming HTLCs automatically.
|
||||
coreLink.cfg.HodlMask = hodl.MaskFromFlags(hodl.ExitSettle)
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -2379,7 +2380,7 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) {
|
||||
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
||||
)
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -2630,7 +2631,7 @@ func TestChannelLinkTrimCircuitsPending(t *testing.T) {
|
||||
|
||||
// Compute the static fees that will be used to determine the
|
||||
// correctness of Alice's bandwidth when forwarding HTLCs.
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -2909,7 +2910,7 @@ func TestChannelLinkTrimCircuitsNoCommit(t *testing.T) {
|
||||
|
||||
// Compute the static fees that will be used to determine the
|
||||
// correctness of Alice's bandwidth when forwarding HTLCs.
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -3167,7 +3168,7 @@ func TestChannelLinkBandwidthChanReserve(t *testing.T) {
|
||||
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
||||
)
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -3554,8 +3555,8 @@ func TestChannelRetransmission(t *testing.T) {
|
||||
// deviates from our current fee by more 10% or more.
|
||||
func TestShouldAdjustCommitFee(t *testing.T) {
|
||||
tests := []struct {
|
||||
netFee lnwallet.SatPerKWeight
|
||||
chanFee lnwallet.SatPerKWeight
|
||||
netFee chainfee.SatPerKWeight
|
||||
chanFee chainfee.SatPerKWeight
|
||||
shouldAdjust bool
|
||||
}{
|
||||
|
||||
@ -3837,7 +3838,7 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
||||
|
||||
// triggerFeeUpdate is a helper closure to determine whether a fee
|
||||
// update was triggered and completed properly.
|
||||
triggerFeeUpdate := func(feeEstimate, newFeeRate lnwallet.SatPerKWeight,
|
||||
triggerFeeUpdate := func(feeEstimate, newFeeRate chainfee.SatPerKWeight,
|
||||
shouldUpdate bool) {
|
||||
|
||||
t.Helper()
|
||||
@ -3898,7 +3899,7 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
||||
// Triggering the link to update the fee of the channel with a fee rate
|
||||
// that exceeds its maximum fee allocation should result in a fee rate
|
||||
// corresponding to the maximum fee allocation.
|
||||
const maxFeeRate lnwallet.SatPerKWeight = 207182320
|
||||
const maxFeeRate chainfee.SatPerKWeight = 207182320
|
||||
triggerFeeUpdate(maxFeeRate+1, maxFeeRate, true)
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
)
|
||||
@ -70,13 +70,13 @@ func (m *mockPreimageCache) SubscribeUpdates() *contractcourt.WitnessSubscriptio
|
||||
}
|
||||
|
||||
type mockFeeEstimator struct {
|
||||
byteFeeIn chan lnwallet.SatPerKWeight
|
||||
byteFeeIn chan chainfee.SatPerKWeight
|
||||
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
func (m *mockFeeEstimator) EstimateFeePerKW(
|
||||
numBlocks uint32) (lnwallet.SatPerKWeight, error) {
|
||||
numBlocks uint32) (chainfee.SatPerKWeight, error) {
|
||||
|
||||
select {
|
||||
case feeRate := <-m.byteFeeIn:
|
||||
@ -86,7 +86,7 @@ func (m *mockFeeEstimator) EstimateFeePerKW(
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mockFeeEstimator) RelayFeePerKW() lnwallet.SatPerKWeight {
|
||||
func (m *mockFeeEstimator) RelayFeePerKW() chainfee.SatPerKWeight {
|
||||
return 1e3
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ func (m *mockFeeEstimator) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ lnwallet.FeeEstimator = (*mockFeeEstimator)(nil)
|
||||
var _ chainfee.Estimator = (*mockFeeEstimator)(nil)
|
||||
|
||||
type mockForwardingLog struct {
|
||||
sync.Mutex
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
)
|
||||
@ -102,7 +103,7 @@ type ChanClose struct {
|
||||
// This value is only utilized if the closure type is CloseRegular.
|
||||
// This will be the starting offered fee when the fee negotiation
|
||||
// process for the cooperative closure transaction kicks off.
|
||||
TargetFeePerKw lnwallet.SatPerKWeight
|
||||
TargetFeePerKw chainfee.SatPerKWeight
|
||||
|
||||
// Updates is used by request creator to receive the notifications about
|
||||
// execution of the close channel request.
|
||||
@ -1368,7 +1369,7 @@ func (s *Switch) teardownCircuit(pkt *htlcPacket) error {
|
||||
// then the last parameter should be the ideal fee-per-kw that will be used as
|
||||
// a starting point for close negotiation.
|
||||
func (s *Switch) CloseLink(chanPoint *wire.OutPoint, closeType ChannelCloseType,
|
||||
targetFeePerKw lnwallet.SatPerKWeight) (chan interface{},
|
||||
targetFeePerKw chainfee.SatPerKWeight) (chan interface{},
|
||||
chan error) {
|
||||
|
||||
// TODO(roasbeef) abstract out the close updates.
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
@ -286,7 +287,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte,
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
@ -1078,7 +1079,7 @@ func newHopNetwork() *hopNetwork {
|
||||
obfuscator := NewMockObfuscator()
|
||||
|
||||
feeEstimator := &mockFeeEstimator{
|
||||
byteFeeIn: make(chan lnwallet.SatPerKWeight),
|
||||
byteFeeIn: make(chan chainfee.SatPerKWeight),
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ package walletrpc
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/macaroons"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
)
|
||||
@ -30,7 +31,7 @@ type Config struct {
|
||||
|
||||
// FeeEstimator is an instance of the primary fee estimator instance
|
||||
// the WalletKit will use to respond to fee estimation requests.
|
||||
FeeEstimator lnwallet.FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// Wallet is the primary wallet that the WalletKit will use to proxy
|
||||
// any relevant requests to.
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/sweep"
|
||||
"google.golang.org/grpc"
|
||||
"gopkg.in/macaroon-bakery.v2/bakery"
|
||||
@ -303,7 +304,7 @@ func (w *WalletKit) SendOutputs(ctx context.Context,
|
||||
// Now that we have the outputs mapped, we can request that the wallet
|
||||
// attempt to create this transaction.
|
||||
tx, err := w.cfg.Wallet.SendOutputs(
|
||||
outputsToCreate, lnwallet.SatPerKWeight(req.SatPerKw),
|
||||
outputsToCreate, chainfee.SatPerKWeight(req.SatPerKw),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -468,7 +469,7 @@ func (w *WalletKit) BumpFee(ctx context.Context,
|
||||
}
|
||||
|
||||
// Construct the request's fee preference.
|
||||
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
feePreference := sweep.FeePreference{
|
||||
ConfTarget: uint32(in.TargetConf),
|
||||
FeeRate: satPerKw,
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/btcsuite/btcwallet/walletdb"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -289,7 +290,7 @@ func (b *BtcWallet) IsOurAddress(a btcutil.Address) bool {
|
||||
//
|
||||
// This is a part of the WalletController interface.
|
||||
func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
||||
feeRate lnwallet.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
|
||||
// Convert our fee rate from sat/kw to sat/kb since it's required by
|
||||
// SendOutputs.
|
||||
@ -314,7 +315,7 @@ func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
||||
//
|
||||
// This is a part of the WalletController interface.
|
||||
func (b *BtcWallet) CreateSimpleTx(outputs []*wire.TxOut,
|
||||
feeRate lnwallet.SatPerKWeight, dryRun bool) (*txauthor.AuthoredTx, error) {
|
||||
feeRate chainfee.SatPerKWeight, dryRun bool) (*txauthor.AuthoredTx, error) {
|
||||
|
||||
// The fee rate is passed in using units of sat/kw, so we'll convert
|
||||
// this to sat/KB as the CreateSimpleTx method requires this unit.
|
||||
|
@ -1,4 +1,4 @@
|
||||
package lnwallet
|
||||
package chainfee
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -10,85 +10,41 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
const (
|
||||
// FeePerKwFloor is the lowest fee rate in sat/kw that we should use for
|
||||
// determining transaction fees.
|
||||
FeePerKwFloor SatPerKWeight = 253
|
||||
|
||||
// maxBlockTarget is the highest number of blocks confirmations that
|
||||
// a WebAPIFeeEstimator will cache fees for. This number is chosen
|
||||
// a WebAPIEstimator will cache fees for. This number is chosen
|
||||
// because it's the highest number of confs bitcoind will return a fee
|
||||
// estimate for.
|
||||
maxBlockTarget uint32 = 1009
|
||||
|
||||
// minBlockTarget is the lowest number of blocks confirmations that
|
||||
// a WebAPIFeeEstimator will cache fees for. Requesting an estimate for
|
||||
// a WebAPIEstimator will cache fees for. Requesting an estimate for
|
||||
// less than this will result in an error.
|
||||
minBlockTarget uint32 = 2
|
||||
|
||||
// minFeeUpdateTimeout represents the minimum interval in which a
|
||||
// WebAPIFeeEstimator will request fresh fees from its API.
|
||||
// WebAPIEstimator will request fresh fees from its API.
|
||||
minFeeUpdateTimeout = 5 * time.Minute
|
||||
|
||||
// maxFeeUpdateTimeout represents the maximum interval in which a
|
||||
// WebAPIFeeEstimator will request fresh fees from its API.
|
||||
// WebAPIEstimator will request fresh fees from its API.
|
||||
maxFeeUpdateTimeout = 20 * time.Minute
|
||||
)
|
||||
|
||||
// SatPerKVByte represents a fee rate in sat/kb.
|
||||
type SatPerKVByte btcutil.Amount
|
||||
|
||||
// FeeForVSize calculates the fee resulting from this fee rate and the given
|
||||
// vsize in vbytes.
|
||||
func (s SatPerKVByte) FeeForVSize(vbytes int64) btcutil.Amount {
|
||||
return btcutil.Amount(s) * btcutil.Amount(vbytes) / 1000
|
||||
}
|
||||
|
||||
// FeePerKWeight converts the current fee rate from sat/kb to sat/kw.
|
||||
func (s SatPerKVByte) FeePerKWeight() SatPerKWeight {
|
||||
return SatPerKWeight(s / blockchain.WitnessScaleFactor)
|
||||
}
|
||||
|
||||
// String returns a human-readable string of the fee rate.
|
||||
func (s SatPerKVByte) String() string {
|
||||
return fmt.Sprintf("%v sat/kb", int64(s))
|
||||
}
|
||||
|
||||
// SatPerKWeight represents a fee rate in sat/kw.
|
||||
type SatPerKWeight btcutil.Amount
|
||||
|
||||
// FeeForWeight calculates the fee resulting from this fee rate and the given
|
||||
// weight in weight units (wu).
|
||||
func (s SatPerKWeight) FeeForWeight(wu int64) btcutil.Amount {
|
||||
// The resulting fee is rounded down, as specified in BOLT#03.
|
||||
return btcutil.Amount(s) * btcutil.Amount(wu) / 1000
|
||||
}
|
||||
|
||||
// FeePerKVByte converts the current fee rate from sat/kw to sat/kb.
|
||||
func (s SatPerKWeight) FeePerKVByte() SatPerKVByte {
|
||||
return SatPerKVByte(s * blockchain.WitnessScaleFactor)
|
||||
}
|
||||
|
||||
// String returns a human-readable string of the fee rate.
|
||||
func (s SatPerKWeight) String() string {
|
||||
return fmt.Sprintf("%v sat/kw", int64(s))
|
||||
}
|
||||
|
||||
// FeeEstimator provides the ability to estimate on-chain transaction fees for
|
||||
// Estimator provides the ability to estimate on-chain transaction fees for
|
||||
// various combinations of transaction sizes and desired confirmation time
|
||||
// (measured by number of blocks).
|
||||
type FeeEstimator interface {
|
||||
type Estimator interface {
|
||||
// EstimateFeePerKW takes in a target for the number of blocks until an
|
||||
// initial confirmation and returns the estimated fee expressed in
|
||||
// sat/kw.
|
||||
EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error)
|
||||
|
||||
// Start signals the FeeEstimator to start any processes or goroutines
|
||||
// Start signals the Estimator to start any processes or goroutines
|
||||
// it needs to perform its duty.
|
||||
Start() error
|
||||
|
||||
@ -102,11 +58,11 @@ type FeeEstimator interface {
|
||||
RelayFeePerKW() SatPerKWeight
|
||||
}
|
||||
|
||||
// StaticFeeEstimator will return a static value for all fee calculation
|
||||
// requests. It is designed to be replaced by a proper fee calculation
|
||||
// implementation. The fees are not accessible directly, because changing them
|
||||
// would not be thread safe.
|
||||
type StaticFeeEstimator struct {
|
||||
// StaticEstimator will return a static value for all fee calculation requests.
|
||||
// It is designed to be replaced by a proper fee calculation implementation.
|
||||
// The fees are not accessible directly, because changing them would not be
|
||||
// thread safe.
|
||||
type StaticEstimator struct {
|
||||
// feePerKW is the static fee rate in satoshis-per-vbyte that will be
|
||||
// returned by this fee estimator.
|
||||
feePerKW SatPerKWeight
|
||||
@ -116,11 +72,10 @@ type StaticFeeEstimator struct {
|
||||
relayFee SatPerKWeight
|
||||
}
|
||||
|
||||
// NewStaticFeeEstimator returns a new static fee estimator instance.
|
||||
func NewStaticFeeEstimator(feePerKW,
|
||||
relayFee SatPerKWeight) *StaticFeeEstimator {
|
||||
// NewStaticEstimator returns a new static fee estimator instance.
|
||||
func NewStaticEstimator(feePerKW, relayFee SatPerKWeight) *StaticEstimator {
|
||||
|
||||
return &StaticFeeEstimator{
|
||||
return &StaticEstimator{
|
||||
feePerKW: feePerKW,
|
||||
relayFee: relayFee,
|
||||
}
|
||||
@ -128,43 +83,43 @@ func NewStaticFeeEstimator(feePerKW,
|
||||
|
||||
// EstimateFeePerKW will return a static value for fee calculations.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (e StaticFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (e StaticEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
return e.feePerKW, nil
|
||||
}
|
||||
|
||||
// RelayFeePerKW returns the minimum fee rate required for transactions to be
|
||||
// relayed.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (e StaticFeeEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (e StaticEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
return e.relayFee
|
||||
}
|
||||
|
||||
// Start signals the FeeEstimator to start any processes or goroutines
|
||||
// Start signals the Estimator to start any processes or goroutines
|
||||
// it needs to perform its duty.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (e StaticFeeEstimator) Start() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (e StaticEstimator) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops any spawned goroutines and cleans up the resources used
|
||||
// by the fee estimator.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (e StaticFeeEstimator) Stop() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (e StaticEstimator) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// A compile-time assertion to ensure that StaticFeeEstimator implements the
|
||||
// FeeEstimator interface.
|
||||
var _ FeeEstimator = (*StaticFeeEstimator)(nil)
|
||||
// Estimator interface.
|
||||
var _ Estimator = (*StaticEstimator)(nil)
|
||||
|
||||
// BtcdFeeEstimator is an implementation of the FeeEstimator interface backed
|
||||
// BtcdEstimator is an implementation of the Estimator interface backed
|
||||
// by the RPC interface of an active btcd node. This implementation will proxy
|
||||
// any fee estimation requests to btcd's RPC interface.
|
||||
type BtcdFeeEstimator struct {
|
||||
type BtcdEstimator struct {
|
||||
// fallbackFeePerKW is the fall back fee rate in sat/kw that is returned
|
||||
// if the fee estimator does not yet have enough data to actually
|
||||
// produce fee estimates.
|
||||
@ -179,13 +134,13 @@ type BtcdFeeEstimator struct {
|
||||
btcdConn *rpcclient.Client
|
||||
}
|
||||
|
||||
// NewBtcdFeeEstimator creates a new BtcdFeeEstimator given a fully populated
|
||||
// NewBtcdEstimator creates a new BtcdEstimator given a fully populated
|
||||
// rpc config that is able to successfully connect and authenticate with the
|
||||
// btcd node, and also a fall back fee rate. The fallback fee rate is used in
|
||||
// the occasion that the estimator has insufficient data, or returns zero for a
|
||||
// fee estimate.
|
||||
func NewBtcdFeeEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
fallBackFeeRate SatPerKWeight) (*BtcdFeeEstimator, error) {
|
||||
func NewBtcdEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
fallBackFeeRate SatPerKWeight) (*BtcdEstimator, error) {
|
||||
|
||||
rpcConfig.DisableConnectOnNew = true
|
||||
rpcConfig.DisableAutoReconnect = false
|
||||
@ -194,17 +149,17 @@ func NewBtcdFeeEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BtcdFeeEstimator{
|
||||
return &BtcdEstimator{
|
||||
fallbackFeePerKW: fallBackFeeRate,
|
||||
btcdConn: chainConn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start signals the FeeEstimator to start any processes or goroutines
|
||||
// Start signals the Estimator to start any processes or goroutines
|
||||
// it needs to perform its duty.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BtcdFeeEstimator) Start() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BtcdEstimator) Start() error {
|
||||
if err := b.btcdConn.Connect(20); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -233,7 +188,7 @@ func (b *BtcdFeeEstimator) Start() error {
|
||||
b.minFeePerKW = FeePerKwFloor
|
||||
}
|
||||
|
||||
walletLog.Debugf("Using minimum fee rate of %v sat/kw",
|
||||
log.Debugf("Using minimum fee rate of %v sat/kw",
|
||||
int64(b.minFeePerKW))
|
||||
|
||||
return nil
|
||||
@ -242,8 +197,8 @@ func (b *BtcdFeeEstimator) Start() error {
|
||||
// Stop stops any spawned goroutines and cleans up the resources used
|
||||
// by the fee estimator.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BtcdFeeEstimator) Stop() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BtcdEstimator) Stop() error {
|
||||
b.btcdConn.Shutdown()
|
||||
|
||||
return nil
|
||||
@ -252,15 +207,15 @@ func (b *BtcdFeeEstimator) Stop() error {
|
||||
// EstimateFeePerKW takes in a target for the number of blocks until an initial
|
||||
// confirmation and returns the estimated fee expressed in sat/kw.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BtcdFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BtcdEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
feeEstimate, err := b.fetchEstimate(numBlocks)
|
||||
switch {
|
||||
// If the estimator doesn't have enough data, or returns an error, then
|
||||
// to return a proper value, then we'll return the default fall back
|
||||
// fee rate.
|
||||
case err != nil:
|
||||
walletLog.Errorf("unable to query estimator: %v", err)
|
||||
log.Errorf("unable to query estimator: %v", err)
|
||||
fallthrough
|
||||
|
||||
case feeEstimate == 0:
|
||||
@ -273,14 +228,14 @@ func (b *BtcdFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, er
|
||||
// RelayFeePerKW returns the minimum fee rate required for transactions to be
|
||||
// relayed.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BtcdFeeEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BtcdEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
return b.minFeePerKW
|
||||
}
|
||||
|
||||
// fetchEstimate returns a fee estimate for a transaction to be confirmed in
|
||||
// confTarget blocks. The estimate is returned in sat/kw.
|
||||
func (b *BtcdFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
|
||||
func (b *BtcdEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
|
||||
// First, we'll fetch the estimate for our confirmation target.
|
||||
btcPerKB, err := b.btcdConn.EstimateFee(int64(confTarget))
|
||||
if err != nil {
|
||||
@ -300,26 +255,26 @@ func (b *BtcdFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, erro
|
||||
|
||||
// Finally, we'll enforce our fee floor.
|
||||
if satPerKw < b.minFeePerKW {
|
||||
walletLog.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
||||
log.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
||||
"using fee floor of %v sat/kw instead", satPerKw,
|
||||
b.minFeePerKW)
|
||||
satPerKw = b.minFeePerKW
|
||||
}
|
||||
|
||||
walletLog.Debugf("Returning %v sat/kw for conf target of %v",
|
||||
log.Debugf("Returning %v sat/kw for conf target of %v",
|
||||
int64(satPerKw), confTarget)
|
||||
|
||||
return satPerKw, nil
|
||||
}
|
||||
|
||||
// A compile-time assertion to ensure that BtcdFeeEstimator implements the
|
||||
// FeeEstimator interface.
|
||||
var _ FeeEstimator = (*BtcdFeeEstimator)(nil)
|
||||
// A compile-time assertion to ensure that BtcdEstimator implements the
|
||||
// Estimator interface.
|
||||
var _ Estimator = (*BtcdEstimator)(nil)
|
||||
|
||||
// BitcoindFeeEstimator is an implementation of the FeeEstimator interface
|
||||
// backed by the RPC interface of an active bitcoind node. This implementation
|
||||
// will proxy any fee estimation requests to bitcoind's RPC interface.
|
||||
type BitcoindFeeEstimator struct {
|
||||
// BitcoindEstimator is an implementation of the Estimator interface backed by
|
||||
// the RPC interface of an active bitcoind node. This implementation will proxy
|
||||
// any fee estimation requests to bitcoind's RPC interface.
|
||||
type BitcoindEstimator struct {
|
||||
// fallbackFeePerKW is the fallback fee rate in sat/kw that is returned
|
||||
// if the fee estimator does not yet have enough data to actually
|
||||
// produce fee estimates.
|
||||
@ -334,13 +289,13 @@ type BitcoindFeeEstimator struct {
|
||||
bitcoindConn *rpcclient.Client
|
||||
}
|
||||
|
||||
// NewBitcoindFeeEstimator creates a new BitcoindFeeEstimator given a fully
|
||||
// populated rpc config that is able to successfully connect and authenticate
|
||||
// with the bitcoind node, and also a fall back fee rate. The fallback fee rate
|
||||
// is used in the occasion that the estimator has insufficient data, or returns
|
||||
// zero for a fee estimate.
|
||||
func NewBitcoindFeeEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
fallBackFeeRate SatPerKWeight) (*BitcoindFeeEstimator, error) {
|
||||
// NewBitcoindEstimator creates a new BitcoindEstimator given a fully populated
|
||||
// rpc config that is able to successfully connect and authenticate with the
|
||||
// bitcoind node, and also a fall back fee rate. The fallback fee rate is used
|
||||
// in the occasion that the estimator has insufficient data, or returns zero
|
||||
// for a fee estimate.
|
||||
func NewBitcoindEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
fallBackFeeRate SatPerKWeight) (*BitcoindEstimator, error) {
|
||||
|
||||
rpcConfig.DisableConnectOnNew = true
|
||||
rpcConfig.DisableAutoReconnect = false
|
||||
@ -351,17 +306,17 @@ func NewBitcoindFeeEstimator(rpcConfig rpcclient.ConnConfig,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BitcoindFeeEstimator{
|
||||
return &BitcoindEstimator{
|
||||
fallbackFeePerKW: fallBackFeeRate,
|
||||
bitcoindConn: chainConn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Start signals the FeeEstimator to start any processes or goroutines
|
||||
// Start signals the Estimator to start any processes or goroutines
|
||||
// it needs to perform its duty.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BitcoindFeeEstimator) Start() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BitcoindEstimator) Start() error {
|
||||
// Once the connection to the backend node has been established, we'll
|
||||
// query it for its minimum relay fee. Since the `getinfo` RPC has been
|
||||
// deprecated for `bitcoind`, we'll need to send a `getnetworkinfo`
|
||||
@ -396,7 +351,7 @@ func (b *BitcoindFeeEstimator) Start() error {
|
||||
b.minFeePerKW = FeePerKwFloor
|
||||
}
|
||||
|
||||
walletLog.Debugf("Using minimum fee rate of %v sat/kw",
|
||||
log.Debugf("Using minimum fee rate of %v sat/kw",
|
||||
int64(b.minFeePerKW))
|
||||
|
||||
return nil
|
||||
@ -405,23 +360,23 @@ func (b *BitcoindFeeEstimator) Start() error {
|
||||
// Stop stops any spawned goroutines and cleans up the resources used
|
||||
// by the fee estimator.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BitcoindFeeEstimator) Stop() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BitcoindEstimator) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EstimateFeePerKW takes in a target for the number of blocks until an initial
|
||||
// confirmation and returns the estimated fee expressed in sat/kw.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BitcoindFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BitcoindEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
feeEstimate, err := b.fetchEstimate(numBlocks)
|
||||
switch {
|
||||
// If the estimator doesn't have enough data, or returns an error, then
|
||||
// to return a proper value, then we'll return the default fall back
|
||||
// fee rate.
|
||||
case err != nil:
|
||||
walletLog.Errorf("unable to query estimator: %v", err)
|
||||
log.Errorf("unable to query estimator: %v", err)
|
||||
fallthrough
|
||||
|
||||
case feeEstimate == 0:
|
||||
@ -434,14 +389,14 @@ func (b *BitcoindFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight
|
||||
// RelayFeePerKW returns the minimum fee rate required for transactions to be
|
||||
// relayed.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (b *BitcoindFeeEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (b *BitcoindEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
return b.minFeePerKW
|
||||
}
|
||||
|
||||
// fetchEstimate returns a fee estimate for a transaction to be confirmed in
|
||||
// confTarget blocks. The estimate is returned in sat/kw.
|
||||
func (b *BitcoindFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
|
||||
func (b *BitcoindEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight, error) {
|
||||
// First, we'll send an "estimatesmartfee" command as a raw request,
|
||||
// since it isn't supported by btcd but is available in bitcoind.
|
||||
target, err := json.Marshal(uint64(confTarget))
|
||||
@ -478,26 +433,26 @@ func (b *BitcoindFeeEstimator) fetchEstimate(confTarget uint32) (SatPerKWeight,
|
||||
|
||||
// Finally, we'll enforce our fee floor.
|
||||
if satPerKw < b.minFeePerKW {
|
||||
walletLog.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
||||
log.Debugf("Estimated fee rate of %v sat/kw is too low, "+
|
||||
"using fee floor of %v sat/kw instead", satPerKw,
|
||||
b.minFeePerKW)
|
||||
|
||||
satPerKw = b.minFeePerKW
|
||||
}
|
||||
|
||||
walletLog.Debugf("Returning %v sat/kw for conf target of %v",
|
||||
log.Debugf("Returning %v sat/kw for conf target of %v",
|
||||
int64(satPerKw), confTarget)
|
||||
|
||||
return satPerKw, nil
|
||||
}
|
||||
|
||||
// A compile-time assertion to ensure that BitcoindFeeEstimator implements the
|
||||
// FeeEstimator interface.
|
||||
var _ FeeEstimator = (*BitcoindFeeEstimator)(nil)
|
||||
// A compile-time assertion to ensure that BitcoindEstimator implements the
|
||||
// Estimator interface.
|
||||
var _ Estimator = (*BitcoindEstimator)(nil)
|
||||
|
||||
// WebAPIFeeSource is an interface allows the WebAPIFeeEstimator to query an
|
||||
// WebAPIFeeSource is an interface allows the WebAPIEstimator to query an
|
||||
// arbitrary HTTP-based fee estimator. Each new set/network will gain an
|
||||
// implementation of this interface in order to allow the WebAPIFeeEstimator to
|
||||
// implementation of this interface in order to allow the WebAPIEstimator to
|
||||
// be fully generic in its logic.
|
||||
type WebAPIFeeSource interface {
|
||||
// GenQueryURL generates the full query URL. The value returned by this
|
||||
@ -554,9 +509,9 @@ func (s SparseConfFeeSource) ParseResponse(r io.Reader) (map[uint32]uint32, erro
|
||||
// WebAPIFeeSource interface.
|
||||
var _ WebAPIFeeSource = (*SparseConfFeeSource)(nil)
|
||||
|
||||
// WebAPIFeeEstimator is an implementation of the FeeEstimator interface that
|
||||
// WebAPIEstimator is an implementation of the Estimator interface that
|
||||
// queries an HTTP-based fee estimation from an existing web API.
|
||||
type WebAPIFeeEstimator struct {
|
||||
type WebAPIEstimator struct {
|
||||
started sync.Once
|
||||
stopped sync.Once
|
||||
|
||||
@ -581,12 +536,12 @@ type WebAPIFeeEstimator struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
// NewWebAPIFeeEstimator creates a new WebAPIFeeEstimator from a given URL and a
|
||||
// NewWebAPIEstimator creates a new WebAPIEstimator from a given URL and a
|
||||
// fallback default fee. The fees are updated whenever a new block is mined.
|
||||
func NewWebAPIFeeEstimator(
|
||||
api WebAPIFeeSource, defaultFee SatPerKWeight) *WebAPIFeeEstimator {
|
||||
func NewWebAPIEstimator(
|
||||
api WebAPIFeeSource, defaultFee SatPerKWeight) *WebAPIEstimator {
|
||||
|
||||
return &WebAPIFeeEstimator{
|
||||
return &WebAPIEstimator{
|
||||
apiSource: api,
|
||||
feeByBlockTarget: make(map[uint32]uint32),
|
||||
defaultFeePerKw: defaultFee,
|
||||
@ -597,8 +552,8 @@ func NewWebAPIFeeEstimator(
|
||||
// EstimateFeePerKW takes in a target for the number of blocks until an initial
|
||||
// confirmation and returns the estimated fee expressed in sat/kw.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (w *WebAPIFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (w *WebAPIEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight, error) {
|
||||
if numBlocks > maxBlockTarget {
|
||||
numBlocks = maxBlockTarget
|
||||
} else if numBlocks < minBlockTarget {
|
||||
@ -618,20 +573,20 @@ func (w *WebAPIFeeEstimator) EstimateFeePerKW(numBlocks uint32) (SatPerKWeight,
|
||||
satPerKw = FeePerKwFloor
|
||||
}
|
||||
|
||||
walletLog.Debugf("Web API returning %v sat/kw for conf target of %v",
|
||||
log.Debugf("Web API returning %v sat/kw for conf target of %v",
|
||||
int64(satPerKw), numBlocks)
|
||||
|
||||
return satPerKw, nil
|
||||
}
|
||||
|
||||
// Start signals the FeeEstimator to start any processes or goroutines it needs
|
||||
// Start signals the Estimator to start any processes or goroutines it needs
|
||||
// to perform its duty.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (w *WebAPIFeeEstimator) Start() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (w *WebAPIEstimator) Start() error {
|
||||
var err error
|
||||
w.started.Do(func() {
|
||||
walletLog.Infof("Starting web API fee estimator")
|
||||
log.Infof("Starting web API fee estimator")
|
||||
|
||||
w.updateFeeTicker = time.NewTicker(w.randomFeeUpdateTimeout())
|
||||
w.updateFeeEstimates()
|
||||
@ -646,10 +601,10 @@ func (w *WebAPIFeeEstimator) Start() error {
|
||||
// Stop stops any spawned goroutines and cleans up the resources used by the
|
||||
// fee estimator.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (w *WebAPIFeeEstimator) Stop() error {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (w *WebAPIEstimator) Stop() error {
|
||||
w.stopped.Do(func() {
|
||||
walletLog.Infof("Stopping web API fee estimator")
|
||||
log.Infof("Stopping web API fee estimator")
|
||||
|
||||
w.updateFeeTicker.Stop()
|
||||
|
||||
@ -662,15 +617,15 @@ func (w *WebAPIFeeEstimator) Stop() error {
|
||||
// RelayFeePerKW returns the minimum fee rate required for transactions to be
|
||||
// relayed.
|
||||
//
|
||||
// NOTE: This method is part of the FeeEstimator interface.
|
||||
func (w *WebAPIFeeEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
// NOTE: This method is part of the Estimator interface.
|
||||
func (w *WebAPIEstimator) RelayFeePerKW() SatPerKWeight {
|
||||
return FeePerKwFloor
|
||||
}
|
||||
|
||||
// randomFeeUpdateTimeout returns a random timeout between minFeeUpdateTimeout
|
||||
// and maxFeeUpdateTimeout that will be used to determine how often the Estimator
|
||||
// should retrieve fresh fees from its API.
|
||||
func (w *WebAPIFeeEstimator) randomFeeUpdateTimeout() time.Duration {
|
||||
func (w *WebAPIEstimator) randomFeeUpdateTimeout() time.Duration {
|
||||
lower := int64(minFeeUpdateTimeout)
|
||||
upper := int64(maxFeeUpdateTimeout)
|
||||
return time.Duration(prand.Int63n(upper-lower) + lower)
|
||||
@ -679,7 +634,7 @@ func (w *WebAPIFeeEstimator) randomFeeUpdateTimeout() time.Duration {
|
||||
// getCachedFee takes in a target for the number of blocks until an initial
|
||||
// confirmation and returns an estimated fee (if one was returned by the API). If
|
||||
// the fee was not previously cached, we cache it here.
|
||||
func (w *WebAPIFeeEstimator) getCachedFee(numBlocks uint32) (uint32, error) {
|
||||
func (w *WebAPIEstimator) getCachedFee(numBlocks uint32) (uint32, error) {
|
||||
w.feesMtx.Lock()
|
||||
defer w.feesMtx.Unlock()
|
||||
|
||||
@ -704,7 +659,7 @@ func (w *WebAPIFeeEstimator) getCachedFee(numBlocks uint32) (uint32, error) {
|
||||
}
|
||||
|
||||
// updateFeeEstimates re-queries the API for fresh fees and caches them.
|
||||
func (w *WebAPIFeeEstimator) updateFeeEstimates() {
|
||||
func (w *WebAPIEstimator) updateFeeEstimates() {
|
||||
// Rather than use the default http.Client, we'll make a custom one
|
||||
// which will allow us to control how long we'll wait to read the
|
||||
// response from the service. This way, if the service is down or
|
||||
@ -725,7 +680,7 @@ func (w *WebAPIFeeEstimator) updateFeeEstimates() {
|
||||
targetURL := w.apiSource.GenQueryURL()
|
||||
resp, err := netClient.Get(targetURL)
|
||||
if err != nil {
|
||||
walletLog.Errorf("unable to query web api for fee response: %v",
|
||||
log.Errorf("unable to query web api for fee response: %v",
|
||||
err)
|
||||
return
|
||||
}
|
||||
@ -735,7 +690,7 @@ func (w *WebAPIFeeEstimator) updateFeeEstimates() {
|
||||
// to parse out the body to obtain our final result.
|
||||
feesByBlockTarget, err := w.apiSource.ParseResponse(resp.Body)
|
||||
if err != nil {
|
||||
walletLog.Errorf("unable to query web api for fee response: %v",
|
||||
log.Errorf("unable to query web api for fee response: %v",
|
||||
err)
|
||||
return
|
||||
}
|
||||
@ -746,7 +701,7 @@ func (w *WebAPIFeeEstimator) updateFeeEstimates() {
|
||||
}
|
||||
|
||||
// feeUpdateManager updates the fee estimates whenever a new block comes in.
|
||||
func (w *WebAPIFeeEstimator) feeUpdateManager() {
|
||||
func (w *WebAPIEstimator) feeUpdateManager() {
|
||||
defer w.wg.Done()
|
||||
|
||||
for {
|
||||
@ -759,6 +714,6 @@ func (w *WebAPIFeeEstimator) feeUpdateManager() {
|
||||
}
|
||||
}
|
||||
|
||||
// A compile-time assertion to ensure that WebAPIFeeEstimator implements the
|
||||
// FeeEstimator interface.
|
||||
var _ FeeEstimator = (*WebAPIFeeEstimator)(nil)
|
||||
// A compile-time assertion to ensure that WebAPIEstimator implements the
|
||||
// Estimator interface.
|
||||
var _ Estimator = (*WebAPIEstimator)(nil)
|
@ -1,4 +1,4 @@
|
||||
package lnwallet_test
|
||||
package chainfee
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -9,8 +9,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
)
|
||||
|
||||
type mockSparseConfFeeSource struct {
|
||||
@ -38,9 +36,9 @@ func TestFeeRateTypes(t *testing.T) {
|
||||
const weight = vsize * 4
|
||||
|
||||
// Test the conversion from sat/kw to sat/kb.
|
||||
for feePerKw := lnwallet.SatPerKWeight(250); feePerKw < 10000; feePerKw += 50 {
|
||||
for feePerKw := SatPerKWeight(250); feePerKw < 10000; feePerKw += 50 {
|
||||
feePerKB := feePerKw.FeePerKVByte()
|
||||
if feePerKB != lnwallet.SatPerKVByte(feePerKw*4) {
|
||||
if feePerKB != SatPerKVByte(feePerKw*4) {
|
||||
t.Fatalf("expected %d sat/kb, got %d sat/kb when "+
|
||||
"converting from %d sat/kw", feePerKw*4,
|
||||
feePerKB, feePerKw)
|
||||
@ -62,9 +60,9 @@ func TestFeeRateTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test the conversion from sat/kb to sat/kw.
|
||||
for feePerKB := lnwallet.SatPerKVByte(1000); feePerKB < 40000; feePerKB += 1000 {
|
||||
for feePerKB := SatPerKVByte(1000); feePerKB < 40000; feePerKB += 1000 {
|
||||
feePerKw := feePerKB.FeePerKWeight()
|
||||
if feePerKw != lnwallet.SatPerKWeight(feePerKB/4) {
|
||||
if feePerKw != SatPerKWeight(feePerKB/4) {
|
||||
t.Fatalf("expected %d sat/kw, got %d sat/kw when "+
|
||||
"converting from %d sat/kb", feePerKB/4,
|
||||
feePerKw, feePerKB)
|
||||
@ -91,9 +89,9 @@ func TestFeeRateTypes(t *testing.T) {
|
||||
func TestStaticFeeEstimator(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const feePerKw = lnwallet.FeePerKwFloor
|
||||
const feePerKw = FeePerKwFloor
|
||||
|
||||
feeEstimator := lnwallet.NewStaticFeeEstimator(feePerKw, 0)
|
||||
feeEstimator := NewStaticEstimator(feePerKw, 0)
|
||||
if err := feeEstimator.Start(); err != nil {
|
||||
t.Fatalf("unable to start fee estimator: %v", err)
|
||||
}
|
||||
@ -116,7 +114,7 @@ func TestSparseConfFeeSource(t *testing.T) {
|
||||
|
||||
// Test that GenQueryURL returns the URL as is.
|
||||
url := "test"
|
||||
feeSource := lnwallet.SparseConfFeeSource{URL: url}
|
||||
feeSource := SparseConfFeeSource{URL: url}
|
||||
queryURL := feeSource.GenQueryURL()
|
||||
if queryURL != url {
|
||||
t.Fatalf("expected query URL of %v, got %v", url, queryURL)
|
||||
@ -166,7 +164,7 @@ func TestSparseConfFeeSource(t *testing.T) {
|
||||
func TestWebAPIFeeEstimator(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
feeFloor := uint32(lnwallet.FeePerKwFloor.FeePerKVByte())
|
||||
feeFloor := uint32(FeePerKwFloor.FeePerKVByte())
|
||||
testCases := []struct {
|
||||
name string
|
||||
target uint32
|
||||
@ -194,7 +192,7 @@ func TestWebAPIFeeEstimator(t *testing.T) {
|
||||
fees: testFees,
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewWebAPIFeeEstimator(feeSource, 10)
|
||||
estimator := NewWebAPIEstimator(feeSource, 10)
|
||||
|
||||
// Test that requesting a fee when no fees have been cached fails.
|
||||
_, err := estimator.EstimateFeePerKW(5)
|
||||
@ -210,6 +208,7 @@ func TestWebAPIFeeEstimator(t *testing.T) {
|
||||
defer estimator.Stop()
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
est, err := estimator.EstimateFeePerKW(tc.target)
|
||||
if tc.err != "" {
|
||||
@ -220,7 +219,7 @@ func TestWebAPIFeeEstimator(t *testing.T) {
|
||||
"fail, instead got: %v", err)
|
||||
}
|
||||
} else {
|
||||
exp := lnwallet.SatPerKVByte(tc.est).FeePerKWeight()
|
||||
exp := SatPerKVByte(tc.est).FeePerKWeight()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to estimate fee for "+
|
||||
"%v block target, got: %v",
|
29
lnwallet/chainfee/log.go
Normal file
29
lnwallet/chainfee/log.go
Normal file
@ -0,0 +1,29 @@
|
||||
package chainfee
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btclog"
|
||||
"github.com/lightningnetwork/lnd/build"
|
||||
)
|
||||
|
||||
// log is a logger that is initialized with no output filters. This means the
|
||||
// package will not perform any logging by default until the caller requests
|
||||
// it.
|
||||
var log btclog.Logger
|
||||
|
||||
// The default amount of logging is none.
|
||||
func init() {
|
||||
UseLogger(build.NewSubLogger("CFEE", nil))
|
||||
}
|
||||
|
||||
// DisableLog disables all library log output. Logging output is disabled by
|
||||
// default until UseLogger is called.
|
||||
func DisableLog() {
|
||||
UseLogger(btclog.Disabled)
|
||||
}
|
||||
|
||||
// UseLogger uses a specified Logger to output package logging info. This
|
||||
// should be used in preference to SetLogWriter if the caller is also using
|
||||
// btclog.
|
||||
func UseLogger(logger btclog.Logger) {
|
||||
log = logger
|
||||
}
|
53
lnwallet/chainfee/rates.go
Normal file
53
lnwallet/chainfee/rates.go
Normal file
@ -0,0 +1,53 @@
|
||||
package chainfee
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcutil"
|
||||
)
|
||||
|
||||
const (
|
||||
// FeePerKwFloor is the lowest fee rate in sat/kw that we should use for
|
||||
// determining transaction fees.
|
||||
FeePerKwFloor SatPerKWeight = 253
|
||||
)
|
||||
|
||||
// SatPerKVByte represents a fee rate in sat/kb.
|
||||
type SatPerKVByte btcutil.Amount
|
||||
|
||||
// FeeForVSize calculates the fee resulting from this fee rate and the given
|
||||
// vsize in vbytes.
|
||||
func (s SatPerKVByte) FeeForVSize(vbytes int64) btcutil.Amount {
|
||||
return btcutil.Amount(s) * btcutil.Amount(vbytes) / 1000
|
||||
}
|
||||
|
||||
// FeePerKWeight converts the current fee rate from sat/kb to sat/kw.
|
||||
func (s SatPerKVByte) FeePerKWeight() SatPerKWeight {
|
||||
return SatPerKWeight(s / blockchain.WitnessScaleFactor)
|
||||
}
|
||||
|
||||
// String returns a human-readable string of the fee rate.
|
||||
func (s SatPerKVByte) String() string {
|
||||
return fmt.Sprintf("%v sat/kb", int64(s))
|
||||
}
|
||||
|
||||
// SatPerKWeight represents a fee rate in sat/kw.
|
||||
type SatPerKWeight btcutil.Amount
|
||||
|
||||
// FeeForWeight calculates the fee resulting from this fee rate and the given
|
||||
// weight in weight units (wu).
|
||||
func (s SatPerKWeight) FeeForWeight(wu int64) btcutil.Amount {
|
||||
// The resulting fee is rounded down, as specified in BOLT#03.
|
||||
return btcutil.Amount(s) * btcutil.Amount(wu) / 1000
|
||||
}
|
||||
|
||||
// FeePerKVByte converts the current fee rate from sat/kw to sat/kb.
|
||||
func (s SatPerKWeight) FeePerKVByte() SatPerKVByte {
|
||||
return SatPerKVByte(s * blockchain.WitnessScaleFactor)
|
||||
}
|
||||
|
||||
// String returns a human-readable string of the fee rate.
|
||||
func (s SatPerKWeight) String() string {
|
||||
return fmt.Sprintf("%v sat/kw", int64(s))
|
||||
}
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -512,7 +513,7 @@ type commitment struct {
|
||||
|
||||
// feePerKw is the fee per kw used to calculate this commitment
|
||||
// transaction's fee.
|
||||
feePerKw SatPerKWeight
|
||||
feePerKw chainfee.SatPerKWeight
|
||||
|
||||
// dustLimit is the limit on the commitment transaction such that no
|
||||
// output values should be below this amount.
|
||||
@ -759,7 +760,7 @@ func (c *commitment) toDiskCommit(ourCommit bool) *channeldb.ChannelCommitment {
|
||||
// commitment struct and updateLog. This function is used when we need to
|
||||
// restore commitment state written do disk back into memory once we need to
|
||||
// restart a channel session.
|
||||
func (lc *LightningChannel) diskHtlcToPayDesc(feeRate SatPerKWeight,
|
||||
func (lc *LightningChannel) diskHtlcToPayDesc(feeRate chainfee.SatPerKWeight,
|
||||
commitHeight uint64, htlc *channeldb.HTLC, localCommitKeys,
|
||||
remoteCommitKeys *CommitmentKeyRing) (PaymentDescriptor, error) {
|
||||
|
||||
@ -824,7 +825,7 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate SatPerKWeight,
|
||||
// these payment descriptors can be re-inserted into the in-memory updateLog
|
||||
// for each side.
|
||||
func (lc *LightningChannel) extractPayDescs(commitHeight uint64,
|
||||
feeRate SatPerKWeight, htlcs []channeldb.HTLC, localCommitKeys,
|
||||
feeRate chainfee.SatPerKWeight, htlcs []channeldb.HTLC, localCommitKeys,
|
||||
remoteCommitKeys *CommitmentKeyRing) ([]PaymentDescriptor, []PaymentDescriptor, error) {
|
||||
|
||||
var (
|
||||
@ -893,7 +894,8 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool,
|
||||
// HTLC"s into PaymentDescriptor's so we can re-insert them into our
|
||||
// update log.
|
||||
incomingHtlcs, outgoingHtlcs, err := lc.extractPayDescs(
|
||||
diskCommit.CommitHeight, SatPerKWeight(diskCommit.FeePerKw),
|
||||
diskCommit.CommitHeight,
|
||||
chainfee.SatPerKWeight(diskCommit.FeePerKw),
|
||||
diskCommit.Htlcs, localCommitKeys, remoteCommitKeys,
|
||||
)
|
||||
if err != nil {
|
||||
@ -914,7 +916,7 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool,
|
||||
txn: diskCommit.CommitTx,
|
||||
sig: diskCommit.CommitSig,
|
||||
fee: diskCommit.CommitFee,
|
||||
feePerKw: SatPerKWeight(diskCommit.FeePerKw),
|
||||
feePerKw: chainfee.SatPerKWeight(diskCommit.FeePerKw),
|
||||
incomingHTLCs: incomingHtlcs,
|
||||
outgoingHTLCs: outgoingHtlcs,
|
||||
}
|
||||
@ -1508,7 +1510,7 @@ func (lc *LightningChannel) ResetState() {
|
||||
// if nothing happened.
|
||||
func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
|
||||
remoteUpdateLog *updateLog, commitHeight uint64,
|
||||
feeRate SatPerKWeight, remoteCommitKeys *CommitmentKeyRing,
|
||||
feeRate chainfee.SatPerKWeight, remoteCommitKeys *CommitmentKeyRing,
|
||||
remoteDustLimit btcutil.Amount) (*PaymentDescriptor, error) {
|
||||
|
||||
// Depending on the type of update message we'll map that to a distinct
|
||||
@ -1825,7 +1827,8 @@ func (lc *LightningChannel) restoreStateLogs(
|
||||
for _, logUpdate := range pendingRemoteCommitDiff.LogUpdates {
|
||||
payDesc, err := lc.logUpdateToPayDesc(
|
||||
&logUpdate, lc.remoteUpdateLog, pendingHeight,
|
||||
SatPerKWeight(pendingCommit.FeePerKw), pendingRemoteKeys,
|
||||
chainfee.SatPerKWeight(pendingCommit.FeePerKw),
|
||||
pendingRemoteKeys,
|
||||
lc.channelState.RemoteChanCfg.DustLimit,
|
||||
)
|
||||
if err != nil {
|
||||
@ -2108,7 +2111,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
||||
// an output on the commitment transaction.
|
||||
if htlcIsDust(
|
||||
htlc.Incoming, false,
|
||||
SatPerKWeight(revokedSnapshot.FeePerKw),
|
||||
chainfee.SatPerKWeight(revokedSnapshot.FeePerKw),
|
||||
htlc.Amt.ToSatoshis(), chanState.RemoteChanCfg.DustLimit,
|
||||
) {
|
||||
continue
|
||||
@ -2197,13 +2200,13 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
||||
|
||||
// htlcTimeoutFee returns the fee in satoshis required for an HTLC timeout
|
||||
// transaction based on the current fee rate.
|
||||
func htlcTimeoutFee(feePerKw SatPerKWeight) btcutil.Amount {
|
||||
func htlcTimeoutFee(feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
||||
return feePerKw.FeeForWeight(input.HtlcTimeoutWeight)
|
||||
}
|
||||
|
||||
// htlcSuccessFee returns the fee in satoshis required for an HTLC success
|
||||
// transaction based on the current fee rate.
|
||||
func htlcSuccessFee(feePerKw SatPerKWeight) btcutil.Amount {
|
||||
func htlcSuccessFee(feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
||||
return feePerKw.FeeForWeight(input.HtlcSuccessWeight)
|
||||
}
|
||||
|
||||
@ -2213,7 +2216,7 @@ func htlcSuccessFee(feePerKw SatPerKWeight) btcutil.Amount {
|
||||
// require as we currently used second-level HTLC transactions as off-chain
|
||||
// covenants. Depending on the two bits, we'll either be using a timeout or
|
||||
// success transaction which have different weights.
|
||||
func htlcIsDust(incoming, ourCommit bool, feePerKw SatPerKWeight,
|
||||
func htlcIsDust(incoming, ourCommit bool, feePerKw chainfee.SatPerKWeight,
|
||||
htlcAmt, dustLimit btcutil.Amount) bool {
|
||||
|
||||
// First we'll determine the fee required for this HTLC based on if this is
|
||||
@ -2254,7 +2257,7 @@ func htlcIsDust(incoming, ourCommit bool, feePerKw SatPerKWeight,
|
||||
type htlcView struct {
|
||||
ourUpdates []*PaymentDescriptor
|
||||
theirUpdates []*PaymentDescriptor
|
||||
feePerKw SatPerKWeight
|
||||
feePerKw chainfee.SatPerKWeight
|
||||
}
|
||||
|
||||
// fetchHTLCView returns all the candidate HTLC updates which should be
|
||||
@ -2785,7 +2788,7 @@ func processFeeUpdate(feeUpdate *PaymentDescriptor, nextHeight uint64,
|
||||
|
||||
// If the update wasn't already locked in, update the current fee rate
|
||||
// to reflect this update.
|
||||
view.feePerKw = SatPerKWeight(feeUpdate.Amount.ToSatoshis())
|
||||
view.feePerKw = chainfee.SatPerKWeight(feeUpdate.Amount.ToSatoshis())
|
||||
|
||||
if mutateState {
|
||||
*addHeight = nextHeight
|
||||
@ -3130,9 +3133,9 @@ func (lc *LightningChannel) validateCommitmentSanity(theirLogCounter,
|
||||
|
||||
// Ensure that the fee being applied is enough to be relayed across the
|
||||
// network in a reasonable time frame.
|
||||
if feePerKw < FeePerKwFloor {
|
||||
if feePerKw < chainfee.FeePerKwFloor {
|
||||
return fmt.Errorf("commitment fee per kw %v below fee floor %v",
|
||||
feePerKw, FeePerKwFloor)
|
||||
feePerKw, chainfee.FeePerKwFloor)
|
||||
}
|
||||
|
||||
// If the added HTLCs will decrease the balance, make sure they won't
|
||||
@ -5048,7 +5051,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Si
|
||||
// Next, we'll obtain HTLC resolutions for all the outgoing HTLC's we
|
||||
// had on their commitment transaction.
|
||||
htlcResolutions, err := extractHtlcResolutions(
|
||||
SatPerKWeight(remoteCommit.FeePerKw), false, signer,
|
||||
chainfee.SatPerKWeight(remoteCommit.FeePerKw), false, signer,
|
||||
remoteCommit.Htlcs, keyRing, &chanState.LocalChanCfg,
|
||||
&chanState.RemoteChanCfg, *commitSpend.SpenderTxHash,
|
||||
)
|
||||
@ -5245,10 +5248,11 @@ type HtlcResolutions struct {
|
||||
// newOutgoingHtlcResolution generates a new HTLC resolution capable of
|
||||
// allowing the caller to sweep an outgoing HTLC present on either their, or
|
||||
// the remote party's commitment transaction.
|
||||
func newOutgoingHtlcResolution(signer input.Signer, localChanCfg *channeldb.ChannelConfig,
|
||||
commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing,
|
||||
feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32, localCommit bool,
|
||||
) (*OutgoingHtlcResolution, error) {
|
||||
func newOutgoingHtlcResolution(signer input.Signer,
|
||||
localChanCfg *channeldb.ChannelConfig, commitHash chainhash.Hash,
|
||||
htlc *channeldb.HTLC, keyRing *CommitmentKeyRing,
|
||||
feePerKw chainfee.SatPerKWeight, csvDelay uint32,
|
||||
localCommit bool) (*OutgoingHtlcResolution, error) {
|
||||
|
||||
op := wire.OutPoint{
|
||||
Hash: commitHash,
|
||||
@ -5387,7 +5391,7 @@ func newOutgoingHtlcResolution(signer input.Signer, localChanCfg *channeldb.Chan
|
||||
// TODO(roasbeef) consolidate code with above func
|
||||
func newIncomingHtlcResolution(signer input.Signer, localChanCfg *channeldb.ChannelConfig,
|
||||
commitHash chainhash.Hash, htlc *channeldb.HTLC, keyRing *CommitmentKeyRing,
|
||||
feePerKw SatPerKWeight, dustLimit btcutil.Amount, csvDelay uint32,
|
||||
feePerKw chainfee.SatPerKWeight, csvDelay uint32,
|
||||
localCommit bool) (*IncomingHtlcResolution, error) {
|
||||
|
||||
op := wire.OutPoint{
|
||||
@ -5541,7 +5545,7 @@ func (r *OutgoingHtlcResolution) HtlcPoint() wire.OutPoint {
|
||||
// extractHtlcResolutions creates a series of outgoing HTLC resolutions, and
|
||||
// the local key used when generating the HTLC scrips. This function is to be
|
||||
// used in two cases: force close, or a unilateral close.
|
||||
func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool,
|
||||
func extractHtlcResolutions(feePerKw chainfee.SatPerKWeight, ourCommit bool,
|
||||
signer input.Signer, htlcs []channeldb.HTLC, keyRing *CommitmentKeyRing,
|
||||
localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
|
||||
commitHash chainhash.Hash) (*HtlcResolutions, error) {
|
||||
@ -5572,7 +5576,7 @@ func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool,
|
||||
// as we can satisfy the contract.
|
||||
ihr, err := newIncomingHtlcResolution(
|
||||
signer, localChanCfg, commitHash, &htlc, keyRing,
|
||||
feePerKw, dustLimit, uint32(csvDelay), ourCommit,
|
||||
feePerKw, uint32(csvDelay), ourCommit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -5584,7 +5588,7 @@ func extractHtlcResolutions(feePerKw SatPerKWeight, ourCommit bool,
|
||||
|
||||
ohr, err := newOutgoingHtlcResolution(
|
||||
signer, localChanCfg, commitHash, &htlc, keyRing,
|
||||
feePerKw, dustLimit, uint32(csvDelay), ourCommit,
|
||||
feePerKw, uint32(csvDelay), ourCommit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -5762,7 +5766,7 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer input.Si
|
||||
// outgoing HTLC's that we'll need to claim as well.
|
||||
txHash := commitTx.TxHash()
|
||||
htlcResolutions, err := extractHtlcResolutions(
|
||||
SatPerKWeight(localCommit.FeePerKw), true, signer,
|
||||
chainfee.SatPerKWeight(localCommit.FeePerKw), true, signer,
|
||||
localCommit.Htlcs, keyRing, &chanState.LocalChanCfg,
|
||||
&chanState.RemoteChanCfg, txHash,
|
||||
)
|
||||
@ -5980,7 +5984,7 @@ func (lc *LightningChannel) StateSnapshot() *channeldb.ChannelSnapshot {
|
||||
// validateFeeRate ensures that if the passed fee is applied to the channel,
|
||||
// and a new commitment is created (which evaluates this fee), then the
|
||||
// initiator of the channel does not dip below their reserve.
|
||||
func (lc *LightningChannel) validateFeeRate(feePerKw SatPerKWeight) error {
|
||||
func (lc *LightningChannel) validateFeeRate(feePerKw chainfee.SatPerKWeight) error {
|
||||
// We'll ensure that we can accommodate this new fee change, yet still
|
||||
// be above our reserve balance. Otherwise, we'll reject the fee
|
||||
// update.
|
||||
@ -6028,7 +6032,7 @@ func (lc *LightningChannel) validateFeeRate(feePerKw SatPerKWeight) error {
|
||||
// UpdateFee initiates a fee update for this channel. Must only be called by
|
||||
// the channel initiator, and must be called before sending update_fee to
|
||||
// the remote.
|
||||
func (lc *LightningChannel) UpdateFee(feePerKw SatPerKWeight) error {
|
||||
func (lc *LightningChannel) UpdateFee(feePerKw chainfee.SatPerKWeight) error {
|
||||
lc.Lock()
|
||||
defer lc.Unlock()
|
||||
|
||||
@ -6056,7 +6060,7 @@ func (lc *LightningChannel) UpdateFee(feePerKw SatPerKWeight) error {
|
||||
|
||||
// ReceiveUpdateFee handles an updated fee sent from remote. This method will
|
||||
// return an error if called as channel initiator.
|
||||
func (lc *LightningChannel) ReceiveUpdateFee(feePerKw SatPerKWeight) error {
|
||||
func (lc *LightningChannel) ReceiveUpdateFee(feePerKw chainfee.SatPerKWeight) error {
|
||||
lc.Lock()
|
||||
defer lc.Unlock()
|
||||
|
||||
@ -6212,7 +6216,7 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn,
|
||||
|
||||
// CalcFee returns the commitment fee to use for the given
|
||||
// fee rate (fee-per-kw).
|
||||
func (lc *LightningChannel) CalcFee(feeRate SatPerKWeight) btcutil.Amount {
|
||||
func (lc *LightningChannel) CalcFee(feeRate chainfee.SatPerKWeight) btcutil.Amount {
|
||||
return feeRate.FeeForWeight(input.CommitWeight)
|
||||
}
|
||||
|
||||
@ -6222,7 +6226,7 @@ func (lc *LightningChannel) CalcFee(feeRate SatPerKWeight) btcutil.Amount {
|
||||
//
|
||||
// NOTE: This should only be used for channels in which the local commitment is
|
||||
// the initiator.
|
||||
func (lc *LightningChannel) MaxFeeRate(maxAllocation float64) SatPerKWeight {
|
||||
func (lc *LightningChannel) MaxFeeRate(maxAllocation float64) chainfee.SatPerKWeight {
|
||||
lc.RLock()
|
||||
defer lc.RUnlock()
|
||||
|
||||
@ -6236,7 +6240,9 @@ func (lc *LightningChannel) MaxFeeRate(maxAllocation float64) SatPerKWeight {
|
||||
|
||||
// Ensure the fee rate doesn't dip below the fee floor.
|
||||
maxFeeRate := maxFee / (float64(weight) / 1000)
|
||||
return SatPerKWeight(math.Max(maxFeeRate, float64(FeePerKwFloor)))
|
||||
return chainfee.SatPerKWeight(
|
||||
math.Max(maxFeeRate, float64(chainfee.FeePerKwFloor)),
|
||||
)
|
||||
}
|
||||
|
||||
// RemoteNextRevocation returns the channelState's RemoteNextRevocation.
|
||||
@ -6259,11 +6265,11 @@ func (lc *LightningChannel) IsInitiator() bool {
|
||||
|
||||
// CommitFeeRate returns the current fee rate of the commitment transaction in
|
||||
// units of sat-per-kw.
|
||||
func (lc *LightningChannel) CommitFeeRate() SatPerKWeight {
|
||||
func (lc *LightningChannel) CommitFeeRate() chainfee.SatPerKWeight {
|
||||
lc.RLock()
|
||||
defer lc.RUnlock()
|
||||
|
||||
return SatPerKWeight(lc.channelState.LocalCommitment.FeePerKw)
|
||||
return chainfee.SatPerKWeight(lc.channelState.LocalCommitment.FeePerKw)
|
||||
}
|
||||
|
||||
// IsPending returns true if the channel's funding transaction has been fully
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -456,8 +457,12 @@ func TestCooperativeChannelClosure(t *testing.T) {
|
||||
aliceDeliveryScript := bobsPrivKey[:]
|
||||
bobDeliveryScript := testHdSeed[:]
|
||||
|
||||
aliceFeeRate := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)
|
||||
bobFeeRate := SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw)
|
||||
aliceFeeRate := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
bobFeeRate := chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
|
||||
// We'll store with both Alice and Bob creating a new close proposal
|
||||
// with the same fee.
|
||||
@ -596,7 +601,9 @@ func TestForceClose(t *testing.T) {
|
||||
// Factoring in the fee rate, Alice's amount should properly reflect
|
||||
// that we've added two additional HTLC to the commitment transaction.
|
||||
totalCommitWeight := input.CommitWeight + (input.HtlcWeight * 2)
|
||||
feePerKw := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)
|
||||
feePerKw := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
commitFee := feePerKw.FeeForWeight(totalCommitWeight)
|
||||
expectedAmount := (aliceChannel.Capacity / 2) - htlcAmount.ToSatoshis() - commitFee
|
||||
if aliceCommitResolution.SelfOutputSignDesc.Output.Value != int64(expectedAmount) {
|
||||
@ -1004,7 +1011,10 @@ func TestHTLCDustLimit(t *testing.T) {
|
||||
// The amount of the HTLC should be above Alice's dust limit and below
|
||||
// Bob's dust limit.
|
||||
htlcSat := (btcutil.Amount(500) + htlcTimeoutFee(
|
||||
SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)))
|
||||
chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
),
|
||||
))
|
||||
htlcAmount := lnwire.NewMSatFromSatoshis(htlcSat)
|
||||
|
||||
htlc, preimage := createHTLC(0, htlcAmount)
|
||||
@ -1102,7 +1112,7 @@ func TestHTLCSigNumber(t *testing.T) {
|
||||
}
|
||||
|
||||
// Calculate two values that will be below and above Bob's dust limit.
|
||||
estimator := NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get fee: %v", err)
|
||||
@ -1268,7 +1278,9 @@ func TestChannelBalanceDustLimit(t *testing.T) {
|
||||
aliceBalance := aliceChannel.channelState.LocalCommitment.LocalBalance.ToSatoshis()
|
||||
htlcSat := aliceBalance - defaultFee
|
||||
htlcSat += htlcSuccessFee(
|
||||
SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw),
|
||||
chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
),
|
||||
)
|
||||
|
||||
htlcAmount := lnwire.NewMSatFromSatoshis(htlcSat)
|
||||
@ -1366,7 +1378,7 @@ func TestStateUpdatePersistence(t *testing.T) {
|
||||
}
|
||||
|
||||
// Also add a fee update to the update logs.
|
||||
fee := SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
if err := aliceChannel.UpdateFee(fee); err != nil {
|
||||
t.Fatalf("unable to send fee update")
|
||||
}
|
||||
@ -1779,8 +1791,12 @@ func TestCooperativeCloseDustAdherence(t *testing.T) {
|
||||
}
|
||||
defer cleanUp()
|
||||
|
||||
aliceFeeRate := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)
|
||||
bobFeeRate := SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw)
|
||||
aliceFeeRate := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
bobFeeRate := chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
|
||||
setDustLimit := func(dustVal btcutil.Amount) {
|
||||
aliceChannel.channelState.LocalChanCfg.DustLimit = dustVal
|
||||
@ -1946,7 +1962,7 @@ func TestUpdateFeeAdjustments(t *testing.T) {
|
||||
|
||||
// We'll first try to increase the fee rate 5x, this should be able to
|
||||
// be committed without any issue.
|
||||
newFee := SatPerKWeight(baseFeeRate * 5)
|
||||
newFee := chainfee.SatPerKWeight(baseFeeRate * 5)
|
||||
|
||||
if err := aliceChannel.UpdateFee(newFee); err != nil {
|
||||
t.Fatalf("unable to alice update fee: %v", err)
|
||||
@ -1964,7 +1980,7 @@ func TestUpdateFeeAdjustments(t *testing.T) {
|
||||
// We'll now attempt to increase the fee rate 1,000,000x of the base
|
||||
// fee. This should result in an error as Alice won't be able to pay
|
||||
// this new fee rate.
|
||||
newFee = SatPerKWeight(baseFeeRate * 1000000)
|
||||
newFee = chainfee.SatPerKWeight(baseFeeRate * 1000000)
|
||||
if err := aliceChannel.UpdateFee(newFee); err == nil {
|
||||
t.Fatalf("alice should reject the fee rate")
|
||||
}
|
||||
@ -1972,7 +1988,7 @@ func TestUpdateFeeAdjustments(t *testing.T) {
|
||||
// Finally, we'll attempt to adjust the fee down and use a fee which is
|
||||
// smaller than the initial base fee rate. The fee application and
|
||||
// state transition should proceed without issue.
|
||||
newFee = SatPerKWeight(baseFeeRate / 10)
|
||||
newFee = chainfee.SatPerKWeight(baseFeeRate / 10)
|
||||
if err := aliceChannel.UpdateFee(newFee); err != nil {
|
||||
t.Fatalf("unable to alice update fee: %v", err)
|
||||
}
|
||||
@ -2048,7 +2064,7 @@ func TestUpdateFeeConcurrentSig(t *testing.T) {
|
||||
}
|
||||
|
||||
// Simulate Alice sending update fee message to bob.
|
||||
fee := SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
if err := aliceChannel.UpdateFee(fee); err != nil {
|
||||
t.Fatalf("unable to send fee update")
|
||||
}
|
||||
@ -2084,7 +2100,7 @@ func TestUpdateFeeConcurrentSig(t *testing.T) {
|
||||
t.Fatalf("bob unable to process alice's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
t.Fatalf("bob's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2095,7 +2111,7 @@ func TestUpdateFeeConcurrentSig(t *testing.T) {
|
||||
t.Fatalf("unable to generate bob revocation: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
}
|
||||
@ -2134,7 +2150,7 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
||||
}
|
||||
|
||||
// Simulate Alice sending update fee message to bob.
|
||||
fee := SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
aliceChannel.UpdateFee(fee)
|
||||
bobChannel.ReceiveUpdateFee(fee)
|
||||
|
||||
@ -2154,7 +2170,9 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
||||
t.Fatalf("bob unable to process alice's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("bob's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2165,7 +2183,9 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
||||
t.Fatalf("unable to generate bob revocation: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -2191,7 +2211,9 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
||||
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("alice's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2202,7 +2224,9 @@ func TestUpdateFeeSenderCommits(t *testing.T) {
|
||||
t.Fatalf("unable to revoke alice channel: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("alice's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -2248,7 +2272,7 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
||||
}
|
||||
|
||||
// Simulate Alice sending update fee message to bob
|
||||
fee := SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
aliceChannel.UpdateFee(fee)
|
||||
bobChannel.ReceiveUpdateFee(fee)
|
||||
|
||||
@ -2296,7 +2320,9 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
||||
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("bob's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2308,7 +2334,9 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
||||
t.Fatalf("unable to revoke alice channel: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -2333,7 +2361,9 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
||||
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("alice's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2344,7 +2374,9 @@ func TestUpdateFeeReceiverCommits(t *testing.T) {
|
||||
t.Fatalf("unable to generate bob revocation: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("Alice's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -2372,7 +2404,7 @@ func TestUpdateFeeReceiverSendsUpdate(t *testing.T) {
|
||||
|
||||
// Since Alice is the channel initiator, she should fail when receiving
|
||||
// fee update
|
||||
fee := SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
err = aliceChannel.ReceiveUpdateFee(fee)
|
||||
if err == nil {
|
||||
t.Fatalf("expected alice to fail receiving fee update")
|
||||
@ -2400,9 +2432,9 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
||||
defer cleanUp()
|
||||
|
||||
// Simulate Alice sending update fee message to bob.
|
||||
fee1 := SatPerKWeight(333)
|
||||
fee2 := SatPerKWeight(333)
|
||||
fee := SatPerKWeight(333)
|
||||
fee1 := chainfee.SatPerKWeight(333)
|
||||
fee2 := chainfee.SatPerKWeight(333)
|
||||
fee := chainfee.SatPerKWeight(333)
|
||||
aliceChannel.UpdateFee(fee1)
|
||||
aliceChannel.UpdateFee(fee2)
|
||||
aliceChannel.UpdateFee(fee)
|
||||
@ -2427,15 +2459,17 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
||||
t.Fatalf("bob unable to process alice's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("bob's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
// Alice sending more fee updates now should not mess up the old fee
|
||||
// they both committed to.
|
||||
fee3 := SatPerKWeight(444)
|
||||
fee4 := SatPerKWeight(555)
|
||||
fee5 := SatPerKWeight(666)
|
||||
fee3 := chainfee.SatPerKWeight(444)
|
||||
fee4 := chainfee.SatPerKWeight(555)
|
||||
fee5 := chainfee.SatPerKWeight(666)
|
||||
aliceChannel.UpdateFee(fee3)
|
||||
aliceChannel.UpdateFee(fee4)
|
||||
aliceChannel.UpdateFee(fee5)
|
||||
@ -2450,7 +2484,9 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
||||
t.Fatalf("unable to generate bob revocation: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -2475,7 +2511,9 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
||||
t.Fatalf("alice unable to process bob's new commitment: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) == fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) == fee {
|
||||
t.Fatalf("alice's feePerKw was unexpectedly locked in")
|
||||
}
|
||||
|
||||
@ -2486,7 +2524,9 @@ func TestUpdateFeeMultipleUpdates(t *testing.T) {
|
||||
t.Fatalf("unable to revoke alice channel: %v", err)
|
||||
}
|
||||
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != fee {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != fee {
|
||||
t.Fatalf("alice's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -3869,7 +3909,9 @@ func TestFeeUpdateRejectInsaneFee(t *testing.T) {
|
||||
|
||||
// Next, we'll try to add a fee rate to Alice which is 1,000,000x her
|
||||
// starting fee rate.
|
||||
startingFeeRate := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)
|
||||
startingFeeRate := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
newFeeRate := startingFeeRate * 1000000
|
||||
|
||||
// Both Alice and Bob should reject this new fee rate as it is far too
|
||||
@ -3895,7 +3937,9 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) {
|
||||
|
||||
// First, we'll fetch the current fee rate present within the
|
||||
// commitment transactions.
|
||||
startingFeeRate := SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw)
|
||||
startingFeeRate := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
|
||||
// Next, we'll start a commitment update, with Alice sending a new
|
||||
// update to double the fee rate of the commitment.
|
||||
@ -4034,10 +4078,14 @@ func TestChannelRetransmissionFeeUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
// Both parties should now have the latest fee rate locked-in.
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("alice's feePerKw was not locked in")
|
||||
}
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -4118,7 +4166,7 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
|
||||
|
||||
// First, we'll fetch the current fee rate present within the
|
||||
// commitment transactions.
|
||||
startingFeeRate := SatPerKWeight(
|
||||
startingFeeRate := chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
)
|
||||
newFeeRate := startingFeeRate
|
||||
@ -4247,10 +4295,14 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
// Both parties should now have the latest fee rate locked-in.
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("alice's feePerKw was not locked in")
|
||||
}
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
|
||||
@ -4272,10 +4324,14 @@ func TestFeeUpdateOldDiskFormat(t *testing.T) {
|
||||
assertLogItems(0, numHTLCs+1)
|
||||
|
||||
// ...and the final fee rate locked in.
|
||||
if SatPerKWeight(aliceChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
aliceChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("alice's feePerKw was not locked in")
|
||||
}
|
||||
if SatPerKWeight(bobChannel.channelState.LocalCommitment.FeePerKw) != newFeeRate {
|
||||
if chainfee.SatPerKWeight(
|
||||
bobChannel.channelState.LocalCommitment.FeePerKw,
|
||||
) != newFeeRate {
|
||||
t.Fatalf("bob's feePerKw was not locked in")
|
||||
}
|
||||
}
|
||||
@ -6624,7 +6680,9 @@ func TestChannelMaxFeeRate(t *testing.T) {
|
||||
}
|
||||
defer cleanUp()
|
||||
|
||||
assertMaxFeeRate := func(maxAlloc float64, expFeeRate SatPerKWeight) {
|
||||
assertMaxFeeRate := func(maxAlloc float64,
|
||||
expFeeRate chainfee.SatPerKWeight) {
|
||||
|
||||
maxFeeRate := aliceChannel.MaxFeeRate(maxAlloc)
|
||||
if maxFeeRate != expFeeRate {
|
||||
t.Fatalf("expected max fee rate of %v with max "+
|
||||
@ -6636,5 +6694,5 @@ func TestChannelMaxFeeRate(t *testing.T) {
|
||||
assertMaxFeeRate(1.0, 690607734)
|
||||
assertMaxFeeRate(0.001, 690607)
|
||||
assertMaxFeeRate(0.000001, 690)
|
||||
assertMaxFeeRate(0.0000001, FeePerKwFloor)
|
||||
assertMaxFeeRate(0.0000001, chainfee.FeePerKwFloor)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// Config is a struct which houses configuration parameters which modify the
|
||||
@ -42,7 +43,7 @@ type Config struct {
|
||||
|
||||
// FeeEstimator is the implementation that the wallet will use for the
|
||||
// calculation of on-chain transaction fees.
|
||||
FeeEstimator FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// ChainIO is an instance of the BlockChainIO interface. ChainIO is
|
||||
// used to lookup the existence of outputs within the UTXO set.
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcwallet/wallet/txauthor"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// AddressType is an enum-like type which denotes the possible address types
|
||||
@ -172,7 +173,7 @@ type WalletController interface {
|
||||
// This method also takes the target fee expressed in sat/kw that should
|
||||
// be used when crafting the transaction.
|
||||
SendOutputs(outputs []*wire.TxOut,
|
||||
feeRate SatPerKWeight) (*wire.MsgTx, error)
|
||||
feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error)
|
||||
|
||||
// CreateSimpleTx creates a Bitcoin transaction paying to the specified
|
||||
// outputs. The transaction is not broadcasted to the network. In the
|
||||
@ -184,7 +185,7 @@ type WalletController interface {
|
||||
// NOTE: The dryRun argument can be set true to create a tx that
|
||||
// doesn't alter the database. A tx created with this set to true
|
||||
// SHOULD NOT be broadcasted.
|
||||
CreateSimpleTx(outputs []*wire.TxOut, feeRate SatPerKWeight,
|
||||
CreateSimpleTx(outputs []*wire.TxOut, feeRate chainfee.SatPerKWeight,
|
||||
dryRun bool) (*txauthor.AuthoredTx, error)
|
||||
|
||||
// ListUnspentWitness returns all unspent outputs which are version 0
|
||||
|
@ -40,6 +40,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -166,7 +167,7 @@ func newPkScript(t *testing.T, w *lnwallet.LightningWallet,
|
||||
// parties to send on-chain funds to each other.
|
||||
func sendCoins(t *testing.T, miner *rpctest.Harness,
|
||||
sender, receiver *lnwallet.LightningWallet, output *wire.TxOut,
|
||||
feeRate lnwallet.SatPerKWeight) *wire.MsgTx {
|
||||
feeRate chainfee.SatPerKWeight) *wire.MsgTx { //nolint:unparam
|
||||
|
||||
t.Helper()
|
||||
|
||||
@ -330,7 +331,7 @@ func createTestWallet(tempTestDir string, miningNode *rpctest.Harness,
|
||||
WalletController: wc,
|
||||
Signer: signer,
|
||||
ChainIO: bio,
|
||||
FeeEstimator: lnwallet.NewStaticFeeEstimator(2500, 0),
|
||||
FeeEstimator: chainfee.NewStaticEstimator(2500, 0),
|
||||
DefaultConstraints: channeldb.ChannelConstraints{
|
||||
DustLimit: 500,
|
||||
MaxPendingAmount: lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) * 100,
|
||||
@ -723,7 +724,7 @@ func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness,
|
||||
t.Fatalf("unable to create amt: %v", err)
|
||||
}
|
||||
|
||||
feePerKw := lnwallet.SatPerKWeight(
|
||||
feePerKw := chainfee.SatPerKWeight(
|
||||
numBTC * numBTC * btcutil.SatoshiPerBitcoin,
|
||||
)
|
||||
req := &lnwallet.InitFundingReserveMsg{
|
||||
@ -2151,7 +2152,7 @@ func testChangeOutputSpendConfirmation(r *rpctest.Harness,
|
||||
//
|
||||
// TODO(wilmer): replace this once SendOutputs easily supports sending
|
||||
// all funds in one transaction.
|
||||
txFeeRate := lnwallet.SatPerKWeight(2500)
|
||||
txFeeRate := chainfee.SatPerKWeight(2500)
|
||||
txFee := btcutil.Amount(14380)
|
||||
output := &wire.TxOut{
|
||||
Value: int64(aliceBalance - txFee),
|
||||
@ -2247,7 +2248,7 @@ func testLastUnusedAddr(miner *rpctest.Harness,
|
||||
if err != nil {
|
||||
t.Fatalf("unable to convert addr to script: %v", err)
|
||||
}
|
||||
feeRate := lnwallet.SatPerKWeight(2500)
|
||||
feeRate := chainfee.SatPerKWeight(2500)
|
||||
output := &wire.TxOut{
|
||||
Value: 1000000,
|
||||
PkScript: addrScript,
|
||||
@ -2281,7 +2282,7 @@ func testCreateSimpleTx(r *rpctest.Harness, w *lnwallet.LightningWallet,
|
||||
// The test cases we will run through for all backends.
|
||||
testCases := []struct {
|
||||
outVals []int64
|
||||
feeRate lnwallet.SatPerKWeight
|
||||
feeRate chainfee.SatPerKWeight
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||
|
||||
"github.com/lightningnetwork/lnd/build"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// walletLog is a logger that is initialized with no output filters. This
|
||||
@ -34,6 +35,7 @@ func UseLogger(logger btclog.Logger) {
|
||||
btcwallet.UseLogger(logger)
|
||||
wtxmgr.UseLogger(logger)
|
||||
chain.UseLogger(logger)
|
||||
chainfee.UseLogger(logger)
|
||||
}
|
||||
|
||||
// logClosure is used to provide a closure over expensive logging operations
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -128,7 +129,7 @@ type ChannelReservation struct {
|
||||
// creation of all channel reservations should be carried out via the
|
||||
// lnwallet.InitChannelReservation interface.
|
||||
func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
commitFeePerKw SatPerKWeight, wallet *LightningWallet,
|
||||
commitFeePerKw chainfee.SatPerKWeight, wallet *LightningWallet,
|
||||
id uint64, pushMSat lnwire.MilliSatoshi, chainHash *chainhash.Hash,
|
||||
flags lnwire.FundingFlag,
|
||||
tweaklessCommit bool) (*ChannelReservation, error) {
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
)
|
||||
@ -233,7 +234,7 @@ func CreateTestChannels(tweaklessCommits bool) (
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
estimator := NewStaticFeeEstimator(6000, 0)
|
||||
estimator := chainfee.NewStaticEstimator(6000, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
)
|
||||
@ -800,7 +801,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) {
|
||||
height: test.commitment.CommitHeight,
|
||||
ourBalance: test.commitment.LocalBalance,
|
||||
theirBalance: test.commitment.RemoteBalance,
|
||||
feePerKw: SatPerKWeight(test.commitment.FeePerKw),
|
||||
feePerKw: chainfee.SatPerKWeight(test.commitment.FeePerKw),
|
||||
dustLimit: tc.dustLimit,
|
||||
isOurs: true,
|
||||
}
|
||||
@ -843,7 +844,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) {
|
||||
// Generate second-level HTLC transactions for HTLCs in
|
||||
// commitment tx.
|
||||
htlcResolutions, err := extractHtlcResolutions(
|
||||
SatPerKWeight(test.commitment.FeePerKw), true, signer,
|
||||
chainfee.SatPerKWeight(test.commitment.FeePerKw), true, signer,
|
||||
htlcs, keys, channel.localChanCfg, channel.remoteChanCfg,
|
||||
commitTx.TxHash(),
|
||||
)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chanvalidate"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
@ -89,11 +90,11 @@ type InitFundingReserveMsg struct {
|
||||
// of initial commitment transactions. In order to ensure timely
|
||||
// confirmation, it is recommended that this fee should be generous,
|
||||
// paying some multiple of the accepted base fee rate of the network.
|
||||
CommitFeePerKw SatPerKWeight
|
||||
CommitFeePerKw chainfee.SatPerKWeight
|
||||
|
||||
// FundingFeePerKw is the fee rate in sat/kw to use for the initial
|
||||
// funding transaction.
|
||||
FundingFeePerKw SatPerKWeight
|
||||
FundingFeePerKw chainfee.SatPerKWeight
|
||||
|
||||
// PushMSat is the number of milli-satoshis that should be pushed over
|
||||
// the responder as part of the initial channel creation.
|
||||
@ -1323,7 +1324,7 @@ type coinSelection struct {
|
||||
// returned, and the value of the resulting funding output. This method locks
|
||||
// the selected outputs, and a function closure to unlock them in case of an
|
||||
// error is returned.
|
||||
func (l *LightningWallet) selectCoinsAndChange(feeRate SatPerKWeight,
|
||||
func (l *LightningWallet) selectCoinsAndChange(feeRate chainfee.SatPerKWeight,
|
||||
amt btcutil.Amount, minConfs int32, subtractFees bool) (
|
||||
*coinSelection, error) {
|
||||
|
||||
@ -1485,7 +1486,7 @@ func selectInputs(amt btcutil.Amount, coins []*Utxo) (btcutil.Amount, []*Utxo, e
|
||||
// change output to fund amt satoshis, adhering to the specified fee rate. The
|
||||
// specified fee rate should be expressed in sat/kw for coin selection to
|
||||
// function properly.
|
||||
func coinSelect(feeRate SatPerKWeight, amt btcutil.Amount,
|
||||
func coinSelect(feeRate chainfee.SatPerKWeight, amt btcutil.Amount,
|
||||
coins []*Utxo) ([]*Utxo, btcutil.Amount, error) {
|
||||
|
||||
amtNeeded := amt
|
||||
@ -1549,7 +1550,7 @@ func coinSelect(feeRate SatPerKWeight, amt btcutil.Amount,
|
||||
// coinSelectSubtractFees attempts to select coins such that we'll spend up to
|
||||
// amt in total after fees, adhering to the specified fee rate. The selected
|
||||
// coins, the final output and change values are returned.
|
||||
func coinSelectSubtractFees(feeRate SatPerKWeight, amt,
|
||||
func coinSelectSubtractFees(feeRate chainfee.SatPerKWeight, amt,
|
||||
dustLimit btcutil.Amount, coins []*Utxo) ([]*Utxo, btcutil.Amount,
|
||||
btcutil.Amount, error) {
|
||||
|
||||
|
@ -5,12 +5,15 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// fundingFee is a helper method that returns the fee estimate used for a tx
|
||||
// with the given number of inputs and the optional change output. This matches
|
||||
// the estimate done by the wallet.
|
||||
func fundingFee(feeRate SatPerKWeight, numInput int, change bool) btcutil.Amount {
|
||||
func fundingFee(feeRate chainfee.SatPerKWeight, numInput int, // nolint:unparam
|
||||
change bool) btcutil.Amount {
|
||||
|
||||
var weightEstimate input.TxWeightEstimator
|
||||
|
||||
// All inputs.
|
||||
@ -39,7 +42,7 @@ func fundingFee(feeRate SatPerKWeight, numInput int, change bool) btcutil.Amount
|
||||
func TestCoinSelect(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const feeRate = SatPerKWeight(100)
|
||||
const feeRate = chainfee.SatPerKWeight(100)
|
||||
const dust = btcutil.Amount(100)
|
||||
|
||||
type testCase struct {
|
||||
@ -185,7 +188,7 @@ func TestCoinSelect(t *testing.T) {
|
||||
func TestCoinSelectSubtractFees(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const feeRate = SatPerKWeight(100)
|
||||
const feeRate = chainfee.SatPerKWeight(100)
|
||||
const dustLimit = btcutil.Amount(1000)
|
||||
const dust = btcutil.Amount(100)
|
||||
|
||||
|
5
mock.go
5
mock.go
@ -17,6 +17,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// The block height returned by the mock BlockChainIO's GetBestBlock.
|
||||
@ -271,13 +272,13 @@ func (*mockWalletController) IsOurAddress(a btcutil.Address) bool {
|
||||
}
|
||||
|
||||
func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
|
||||
_ lnwallet.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
_ chainfee.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (*mockWalletController) CreateSimpleTx(outputs []*wire.TxOut,
|
||||
_ lnwallet.SatPerKWeight, _ bool) (*txauthor.AuthoredTx, error) {
|
||||
_ chainfee.SatPerKWeight, _ bool) (*txauthor.AuthoredTx, error) {
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -156,7 +156,7 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
|
||||
dummyDeliveryScript),
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(12500, 0)
|
||||
estimator := chainfee.NewStaticEstimator(12500, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
@ -446,7 +446,7 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
|
||||
msg: respShutdown,
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(12500, 0)
|
||||
estimator := chainfee.NewStaticEstimator(12500, 0)
|
||||
initiatorIdealFeeRate, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to query fee estimator: %v", err)
|
||||
|
13
rpcserver.go
13
rpcserver.go
@ -44,6 +44,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/macaroons"
|
||||
"github.com/lightningnetwork/lnd/monitoring"
|
||||
@ -815,7 +816,7 @@ func addrPairsToOutputs(addrPairs map[string]int64) ([]*wire.TxOut, error) {
|
||||
// more addresses specified in the passed payment map. The payment map maps an
|
||||
// address to a specified output value to be sent to that address.
|
||||
func (r *rpcServer) sendCoinsOnChain(paymentMap map[string]int64,
|
||||
feeRate lnwallet.SatPerKWeight) (*chainhash.Hash, error) {
|
||||
feeRate chainfee.SatPerKWeight) (*chainhash.Hash, error) {
|
||||
|
||||
outputs, err := addrPairsToOutputs(paymentMap)
|
||||
if err != nil {
|
||||
@ -1000,7 +1001,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
|
||||
|
||||
// Based on the passed fee related parameters, we'll determine an
|
||||
// appropriate fee rate for this transaction.
|
||||
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
feePerKw, err := sweep.DetermineFeePerKw(
|
||||
r.server.cc.feeEstimator, sweep.FeePreference{
|
||||
ConfTarget: uint32(in.TargetConf),
|
||||
@ -1122,7 +1123,7 @@ func (r *rpcServer) SendMany(ctx context.Context,
|
||||
|
||||
// Based on the passed fee related parameters, we'll determine an
|
||||
// appropriate fee rate for this transaction.
|
||||
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
feePerKw, err := sweep.DetermineFeePerKw(
|
||||
r.server.cc.feeEstimator, sweep.FeePreference{
|
||||
ConfTarget: uint32(in.TargetConf),
|
||||
@ -1504,7 +1505,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
|
||||
|
||||
// Based on the passed fee related parameters, we'll determine an
|
||||
// appropriate fee rate for the funding transaction.
|
||||
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
feeRate, err := sweep.DetermineFeePerKw(
|
||||
r.server.cc.feeEstimator, sweep.FeePreference{
|
||||
ConfTarget: uint32(in.TargetConf),
|
||||
@ -1649,7 +1650,7 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
|
||||
|
||||
// Based on the passed fee related parameters, we'll determine an
|
||||
// appropriate fee rate for the funding transaction.
|
||||
satPerKw := lnwallet.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
|
||||
feeRate, err := sweep.DetermineFeePerKw(
|
||||
r.server.cc.feeEstimator, sweep.FeePreference{
|
||||
ConfTarget: uint32(in.TargetConf),
|
||||
@ -1847,7 +1848,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
// Based on the passed fee related parameters, we'll determine
|
||||
// an appropriate fee rate for the cooperative closure
|
||||
// transaction.
|
||||
satPerKw := lnwallet.SatPerKVByte(
|
||||
satPerKw := chainfee.SatPerKVByte(
|
||||
in.SatPerByte * 1000,
|
||||
).FeePerKWeight()
|
||||
feeRate, err := sweep.DetermineFeePerKw(
|
||||
|
@ -44,6 +44,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/nat"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
@ -1136,7 +1137,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
|
||||
if cfg.WtClient.SweepFeeRate != 0 {
|
||||
// We expose the sweep fee rate in sat/byte, but the
|
||||
// tower protocol operations on sat/kw.
|
||||
sweepRateSatPerByte := lnwallet.SatPerKVByte(
|
||||
sweepRateSatPerByte := chainfee.SatPerKVByte(
|
||||
1000 * cfg.WtClient.SweepFeeRate,
|
||||
)
|
||||
policy.SweepFeeRate = sweepRateSatPerByte.FeePerKWeight()
|
||||
@ -3071,7 +3072,7 @@ type openChanReq struct {
|
||||
|
||||
pushAmt lnwire.MilliSatoshi
|
||||
|
||||
fundingFeePerKw lnwallet.SatPerKWeight
|
||||
fundingFeePerKw chainfee.SatPerKWeight
|
||||
|
||||
private bool
|
||||
|
||||
|
@ -3,38 +3,38 @@ package sweep
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// mockFeeEstimator implements a mock fee estimator. It closely resembles
|
||||
// lnwallet.StaticFeeEstimator with the addition that fees can be changed for
|
||||
// testing purposes in a thread safe manner.
|
||||
type mockFeeEstimator struct {
|
||||
feePerKW lnwallet.SatPerKWeight
|
||||
feePerKW chainfee.SatPerKWeight
|
||||
|
||||
relayFee lnwallet.SatPerKWeight
|
||||
relayFee chainfee.SatPerKWeight
|
||||
|
||||
blocksToFee map[uint32]lnwallet.SatPerKWeight
|
||||
blocksToFee map[uint32]chainfee.SatPerKWeight
|
||||
|
||||
// A closure that when set is used instead of the
|
||||
// mockFeeEstimator.EstimateFeePerKW method.
|
||||
estimateFeePerKW func(numBlocks uint32) (lnwallet.SatPerKWeight, error)
|
||||
estimateFeePerKW func(numBlocks uint32) (chainfee.SatPerKWeight, error)
|
||||
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func newMockFeeEstimator(feePerKW,
|
||||
relayFee lnwallet.SatPerKWeight) *mockFeeEstimator {
|
||||
relayFee chainfee.SatPerKWeight) *mockFeeEstimator {
|
||||
|
||||
return &mockFeeEstimator{
|
||||
feePerKW: feePerKW,
|
||||
relayFee: relayFee,
|
||||
blocksToFee: make(map[uint32]lnwallet.SatPerKWeight),
|
||||
blocksToFee: make(map[uint32]chainfee.SatPerKWeight),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *mockFeeEstimator) updateFees(feePerKW,
|
||||
relayFee lnwallet.SatPerKWeight) {
|
||||
relayFee chainfee.SatPerKWeight) {
|
||||
|
||||
e.lock.Lock()
|
||||
defer e.lock.Unlock()
|
||||
@ -44,7 +44,7 @@ func (e *mockFeeEstimator) updateFees(feePerKW,
|
||||
}
|
||||
|
||||
func (e *mockFeeEstimator) EstimateFeePerKW(numBlocks uint32) (
|
||||
lnwallet.SatPerKWeight, error) {
|
||||
chainfee.SatPerKWeight, error) {
|
||||
|
||||
e.lock.Lock()
|
||||
defer e.lock.Unlock()
|
||||
@ -60,7 +60,7 @@ func (e *mockFeeEstimator) EstimateFeePerKW(numBlocks uint32) (
|
||||
return e.feePerKW, nil
|
||||
}
|
||||
|
||||
func (e *mockFeeEstimator) RelayFeePerKW() lnwallet.SatPerKWeight {
|
||||
func (e *mockFeeEstimator) RelayFeePerKW() chainfee.SatPerKWeight {
|
||||
e.lock.Lock()
|
||||
defer e.lock.Unlock()
|
||||
|
||||
@ -75,4 +75,4 @@ func (e *mockFeeEstimator) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ lnwallet.FeeEstimator = (*mockFeeEstimator)(nil)
|
||||
var _ chainfee.Estimator = (*mockFeeEstimator)(nil)
|
||||
|
@ -16,13 +16,14 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultMaxFeeRate is the default maximum fee rate allowed within the
|
||||
// UtxoSweeper. The current value is equivalent to a fee rate of 10,000
|
||||
// sat/vbyte.
|
||||
DefaultMaxFeeRate = lnwallet.FeePerKwFloor * 1e4
|
||||
DefaultMaxFeeRate = chainfee.FeePerKwFloor * 1e4
|
||||
|
||||
// DefaultFeeRateBucketSize is the default size of fee rate buckets
|
||||
// we'll use when clustering inputs into buckets with similar fee rates
|
||||
@ -92,7 +93,7 @@ type pendingInput struct {
|
||||
|
||||
// lastFeeRate is the most recent fee rate used for this input within a
|
||||
// transaction broadcast to the network.
|
||||
lastFeeRate lnwallet.SatPerKWeight
|
||||
lastFeeRate chainfee.SatPerKWeight
|
||||
}
|
||||
|
||||
// pendingInputs is a type alias for a set of pending inputs.
|
||||
@ -101,7 +102,7 @@ type pendingInputs = map[wire.OutPoint]*pendingInput
|
||||
// inputCluster is a helper struct to gather a set of pending inputs that should
|
||||
// be swept with the specified fee rate.
|
||||
type inputCluster struct {
|
||||
sweepFeeRate lnwallet.SatPerKWeight
|
||||
sweepFeeRate chainfee.SatPerKWeight
|
||||
inputs pendingInputs
|
||||
}
|
||||
|
||||
@ -126,7 +127,7 @@ type PendingInput struct {
|
||||
|
||||
// LastFeeRate is the most recent fee rate used for the input being
|
||||
// swept within a transaction broadcast to the network.
|
||||
LastFeeRate lnwallet.SatPerKWeight
|
||||
LastFeeRate chainfee.SatPerKWeight
|
||||
|
||||
// BroadcastAttempts is the number of attempts we've made to sweept the
|
||||
// input.
|
||||
@ -182,7 +183,7 @@ type UtxoSweeper struct {
|
||||
|
||||
currentOutputScript []byte
|
||||
|
||||
relayFeeRate lnwallet.SatPerKWeight
|
||||
relayFeeRate chainfee.SatPerKWeight
|
||||
|
||||
quit chan struct{}
|
||||
wg sync.WaitGroup
|
||||
@ -197,7 +198,7 @@ type UtxoSweeperConfig struct {
|
||||
// FeeEstimator is used when crafting sweep transactions to estimate
|
||||
// the necessary fee relative to the expected size of the sweep
|
||||
// transaction.
|
||||
FeeEstimator lnwallet.FeeEstimator
|
||||
FeeEstimator chainfee.Estimator
|
||||
|
||||
// PublishTransaction facilitates the process of broadcasting a signed
|
||||
// transaction to the appropriate network.
|
||||
@ -235,7 +236,7 @@ type UtxoSweeperConfig struct {
|
||||
|
||||
// MaxFeeRate is the the maximum fee rate allowed within the
|
||||
// UtxoSweeper.
|
||||
MaxFeeRate lnwallet.SatPerKWeight
|
||||
MaxFeeRate chainfee.SatPerKWeight
|
||||
|
||||
// FeeRateBucketSize is the default size of fee rate buckets we'll use
|
||||
// when clustering inputs into buckets with similar fee rates within the
|
||||
@ -403,7 +404,7 @@ func (s *UtxoSweeper) SweepInput(input input.Input,
|
||||
// feeRateForPreference returns a fee rate for the given fee preference. It
|
||||
// ensures that the fee rate respects the bounds of the UtxoSweeper.
|
||||
func (s *UtxoSweeper) feeRateForPreference(
|
||||
feePreference FeePreference) (lnwallet.SatPerKWeight, error) {
|
||||
feePreference FeePreference) (chainfee.SatPerKWeight, error) {
|
||||
|
||||
// Ensure a type of fee preference is specified to prevent using a
|
||||
// default below.
|
||||
@ -637,10 +638,10 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
|
||||
// bucketForFeeReate determines the proper bucket for a fee rate. This is done
|
||||
// in order to batch inputs with similar fee rates together.
|
||||
func (s *UtxoSweeper) bucketForFeeRate(
|
||||
feeRate lnwallet.SatPerKWeight) lnwallet.SatPerKWeight {
|
||||
feeRate chainfee.SatPerKWeight) chainfee.SatPerKWeight {
|
||||
|
||||
minBucket := s.relayFeeRate + lnwallet.SatPerKWeight(s.cfg.FeeRateBucketSize)
|
||||
return lnwallet.SatPerKWeight(
|
||||
minBucket := s.relayFeeRate + chainfee.SatPerKWeight(s.cfg.FeeRateBucketSize)
|
||||
return chainfee.SatPerKWeight(
|
||||
math.Ceil(float64(feeRate) / float64(minBucket)),
|
||||
)
|
||||
}
|
||||
@ -650,8 +651,8 @@ func (s *UtxoSweeper) bucketForFeeRate(
|
||||
// sweep fee rate, which is determined by calculating the average fee rate of
|
||||
// all inputs within that cluster.
|
||||
func (s *UtxoSweeper) clusterBySweepFeeRate() []inputCluster {
|
||||
bucketInputs := make(map[lnwallet.SatPerKWeight]pendingInputs)
|
||||
inputFeeRates := make(map[wire.OutPoint]lnwallet.SatPerKWeight)
|
||||
bucketInputs := make(map[chainfee.SatPerKWeight]pendingInputs)
|
||||
inputFeeRates := make(map[wire.OutPoint]chainfee.SatPerKWeight)
|
||||
|
||||
// First, we'll group together all inputs with similar fee rates. This
|
||||
// is done by determining the fee rate bucket they should belong in.
|
||||
@ -678,11 +679,11 @@ func (s *UtxoSweeper) clusterBySweepFeeRate() []inputCluster {
|
||||
// calculating the average fee rate of the inputs within each set.
|
||||
inputClusters := make([]inputCluster, 0, len(bucketInputs))
|
||||
for _, inputs := range bucketInputs {
|
||||
var sweepFeeRate lnwallet.SatPerKWeight
|
||||
var sweepFeeRate chainfee.SatPerKWeight
|
||||
for op := range inputs {
|
||||
sweepFeeRate += inputFeeRates[op]
|
||||
}
|
||||
sweepFeeRate /= lnwallet.SatPerKWeight(len(inputs))
|
||||
sweepFeeRate /= chainfee.SatPerKWeight(len(inputs))
|
||||
inputClusters = append(inputClusters, inputCluster{
|
||||
sweepFeeRate: sweepFeeRate,
|
||||
inputs: inputs,
|
||||
@ -836,7 +837,7 @@ func (s *UtxoSweeper) getInputLists(cluster inputCluster,
|
||||
|
||||
// sweep takes a set of preselected inputs, creates a sweep tx and publishes the
|
||||
// tx. The output address is only marked as used if the publish succeeds.
|
||||
func (s *UtxoSweeper) sweep(inputs inputSet, feeRate lnwallet.SatPerKWeight,
|
||||
func (s *UtxoSweeper) sweep(inputs inputSet, feeRate chainfee.SatPerKWeight,
|
||||
currentHeight int32) error {
|
||||
|
||||
// Generate an output script if there isn't an unused script available.
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -99,7 +100,7 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext {
|
||||
|
||||
backend := newMockBackend(notifier)
|
||||
|
||||
estimator := newMockFeeEstimator(10000, lnwallet.FeePerKwFloor)
|
||||
estimator := newMockFeeEstimator(10000, chainfee.FeePerKwFloor)
|
||||
|
||||
publishChan := make(chan wire.MsgTx, 2)
|
||||
ctx := &sweeperTestContext{
|
||||
@ -314,7 +315,7 @@ func assertTxSweepsInputs(t *testing.T, sweepTx *wire.MsgTx,
|
||||
// NOTE: This assumes that transactions only have one output, as this is the
|
||||
// only type of transaction the UtxoSweeper can create at the moment.
|
||||
func assertTxFeeRate(t *testing.T, tx *wire.MsgTx,
|
||||
expectedFeeRate lnwallet.SatPerKWeight, inputs ...input.Input) {
|
||||
expectedFeeRate chainfee.SatPerKWeight, inputs ...input.Input) {
|
||||
|
||||
t.Helper()
|
||||
|
||||
@ -994,11 +995,11 @@ func TestDifferentFeePreferences(t *testing.T) {
|
||||
// this to ensure the sweeper can broadcast distinct transactions for
|
||||
// each sweep with a different fee preference.
|
||||
lowFeePref := FeePreference{ConfTarget: 12}
|
||||
lowFeeRate := lnwallet.SatPerKWeight(5000)
|
||||
lowFeeRate := chainfee.SatPerKWeight(5000)
|
||||
ctx.estimator.blocksToFee[lowFeePref.ConfTarget] = lowFeeRate
|
||||
|
||||
highFeePref := FeePreference{ConfTarget: 6}
|
||||
highFeeRate := lnwallet.SatPerKWeight(10000)
|
||||
highFeeRate := chainfee.SatPerKWeight(10000)
|
||||
ctx.estimator.blocksToFee[highFeePref.ConfTarget] = highFeeRate
|
||||
|
||||
input1 := spendableInputs[0]
|
||||
@ -1116,7 +1117,7 @@ func TestBumpFeeRBF(t *testing.T) {
|
||||
ctx := createSweeperTestContext(t)
|
||||
|
||||
lowFeePref := FeePreference{ConfTarget: 144}
|
||||
lowFeeRate := lnwallet.FeePerKwFloor
|
||||
lowFeeRate := chainfee.FeePerKwFloor
|
||||
ctx.estimator.blocksToFee[lowFeePref.ConfTarget] = lowFeeRate
|
||||
|
||||
// We'll first try to bump the fee of an output currently unknown to the
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcwallet/wallet/txrules"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -31,7 +31,7 @@ type inputSet []input.Input
|
||||
// inputs are skipped. No input sets with a total value after fees below the
|
||||
// dust limit are returned.
|
||||
func generateInputPartitionings(sweepableInputs []input.Input,
|
||||
relayFeePerKW, feePerKW lnwallet.SatPerKWeight,
|
||||
relayFeePerKW, feePerKW chainfee.SatPerKWeight,
|
||||
maxInputsPerTx int) ([]inputSet, error) {
|
||||
|
||||
// Calculate dust limit based on the P2WPKH output script of the sweep
|
||||
@ -116,7 +116,7 @@ func generateInputPartitionings(sweepableInputs []input.Input,
|
||||
// minimizing any negative externalities we cause for the Bitcoin system as a
|
||||
// whole.
|
||||
func getPositiveYieldInputs(sweepableInputs []input.Input, maxInputs int,
|
||||
feePerKW lnwallet.SatPerKWeight) (int, btcutil.Amount) {
|
||||
feePerKW chainfee.SatPerKWeight) (int, btcutil.Amount) {
|
||||
|
||||
var weightEstimate input.TxWeightEstimator
|
||||
|
||||
@ -169,7 +169,7 @@ func getPositiveYieldInputs(sweepableInputs []input.Input, maxInputs int,
|
||||
|
||||
// createSweepTx builds a signed tx spending the inputs to a the output script.
|
||||
func createSweepTx(inputs []input.Input, outputPkScript []byte,
|
||||
currentBlockHeight uint32, feePerKw lnwallet.SatPerKWeight,
|
||||
currentBlockHeight uint32, feePerKw chainfee.SatPerKWeight,
|
||||
signer input.Signer) (*wire.MsgTx, error) {
|
||||
|
||||
inputs, txWeight := getWeightEstimate(inputs)
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -27,7 +28,7 @@ type FeePreference struct {
|
||||
|
||||
// FeeRate if non-zero, signals a fee pre fence expressed in the fee
|
||||
// rate expressed in sat/kw for a particular transaction.
|
||||
FeeRate lnwallet.SatPerKWeight
|
||||
FeeRate chainfee.SatPerKWeight
|
||||
}
|
||||
|
||||
// String returns a human-readable string of the fee preference.
|
||||
@ -42,8 +43,8 @@ func (p FeePreference) String() string {
|
||||
// an estimator, a confirmation target, and a manual value for sat/byte. A
|
||||
// value is chosen based on the two free parameters as one, or both of them can
|
||||
// be zero.
|
||||
func DetermineFeePerKw(feeEstimator lnwallet.FeeEstimator,
|
||||
feePref FeePreference) (lnwallet.SatPerKWeight, error) {
|
||||
func DetermineFeePerKw(feeEstimator chainfee.Estimator,
|
||||
feePref FeePreference) (chainfee.SatPerKWeight, error) {
|
||||
|
||||
switch {
|
||||
// If both values are set, then we'll return an error as we require a
|
||||
@ -70,12 +71,12 @@ func DetermineFeePerKw(feeEstimator lnwallet.FeeEstimator,
|
||||
// internally.
|
||||
case feePref.FeeRate != 0:
|
||||
feePerKW := feePref.FeeRate
|
||||
if feePerKW < lnwallet.FeePerKwFloor {
|
||||
if feePerKW < chainfee.FeePerKwFloor {
|
||||
log.Infof("Manual fee rate input of %d sat/kw is "+
|
||||
"too low, using %d sat/kw instead", feePerKW,
|
||||
lnwallet.FeePerKwFloor)
|
||||
chainfee.FeePerKwFloor)
|
||||
|
||||
feePerKW = lnwallet.FeePerKwFloor
|
||||
feePerKW = chainfee.FeePerKwFloor
|
||||
}
|
||||
|
||||
return feePerKW, nil
|
||||
@ -152,10 +153,10 @@ type WalletSweepPackage struct {
|
||||
// by the delivery address. The sweep transaction will be crafted with the
|
||||
// target fee rate, and will use the utxoSource and outpointLocker as sources
|
||||
// for wallet funds.
|
||||
func CraftSweepAllTx(feeRate lnwallet.SatPerKWeight, blockHeight uint32,
|
||||
func CraftSweepAllTx(feeRate chainfee.SatPerKWeight, blockHeight uint32,
|
||||
deliveryAddr btcutil.Address, coinSelectLocker CoinSelectionLocker,
|
||||
utxoSource UtxoSource, outpointLocker OutpointLocker,
|
||||
feeEstimator lnwallet.FeeEstimator,
|
||||
feeEstimator chainfee.Estimator,
|
||||
signer input.Signer) (*WalletSweepPackage, error) {
|
||||
|
||||
// TODO(roasbeef): turn off ATPL as well when available?
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
)
|
||||
|
||||
// TestDetermineFeePerKw tests that given a fee preference, the
|
||||
@ -17,8 +18,8 @@ import (
|
||||
func TestDetermineFeePerKw(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defaultFee := lnwallet.SatPerKWeight(999)
|
||||
relayFee := lnwallet.SatPerKWeight(300)
|
||||
defaultFee := chainfee.SatPerKWeight(999)
|
||||
relayFee := chainfee.SatPerKWeight(300)
|
||||
|
||||
feeEstimator := newMockFeeEstimator(defaultFee, relayFee)
|
||||
|
||||
@ -35,7 +36,7 @@ func TestDetermineFeePerKw(t *testing.T) {
|
||||
|
||||
// fee is the value the DetermineFeePerKw should return given
|
||||
// the FeePreference above
|
||||
fee lnwallet.SatPerKWeight
|
||||
fee chainfee.SatPerKWeight
|
||||
|
||||
// fail determines if this test case should fail or not.
|
||||
fail bool
|
||||
@ -43,9 +44,9 @@ func TestDetermineFeePerKw(t *testing.T) {
|
||||
// A fee rate below the fee rate floor should output the floor.
|
||||
{
|
||||
feePref: FeePreference{
|
||||
FeeRate: lnwallet.SatPerKWeight(99),
|
||||
FeeRate: chainfee.SatPerKWeight(99),
|
||||
},
|
||||
fee: lnwallet.FeePerKwFloor,
|
||||
fee: chainfee.FeePerKwFloor,
|
||||
},
|
||||
|
||||
// A fee rate above the floor, should pass through and return
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/shachain"
|
||||
@ -214,7 +215,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
estimator := lnwallet.NewStaticFeeEstimator(12500, 0)
|
||||
estimator := chainfee.NewStaticEstimator(12500, 0)
|
||||
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/tlv"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtwire"
|
||||
@ -19,7 +19,7 @@ type CreateSessionTLV struct {
|
||||
MaxUpdates uint16
|
||||
RewardBase uint32
|
||||
RewardRate uint32
|
||||
SweepFeeRate lnwallet.SatPerKWeight
|
||||
SweepFeeRate chainfee.SatPerKWeight
|
||||
|
||||
tlvStream *tlv.Stream
|
||||
}
|
||||
@ -48,24 +48,24 @@ func DBlobType(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
|
||||
// ESatPerKW is an encoder for lnwallet.SatPerKWeight.
|
||||
func ESatPerKW(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
if v, ok := val.(*lnwallet.SatPerKWeight); ok {
|
||||
if v, ok := val.(*chainfee.SatPerKWeight); ok {
|
||||
return tlv.EUint64(w, uint64(*v), buf)
|
||||
}
|
||||
return tlv.NewTypeForEncodingErr(val, "lnwallet.SatPerKWeight")
|
||||
return tlv.NewTypeForEncodingErr(val, "chainfee.SatPerKWeight")
|
||||
}
|
||||
|
||||
// DSatPerKW is an decoder for lnwallet.SatPerKWeight.
|
||||
func DSatPerKW(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
if v, ok := val.(*lnwallet.SatPerKWeight); ok {
|
||||
if v, ok := val.(*chainfee.SatPerKWeight); ok {
|
||||
var sat uint64
|
||||
err := tlv.DUint64(r, &sat, buf, l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = lnwallet.SatPerKWeight(sat)
|
||||
*v = chainfee.SatPerKWeight(sat)
|
||||
return nil
|
||||
}
|
||||
return tlv.NewTypeForDecodingErr(val, "lnwallet.SatPerKWeight", l, 8)
|
||||
return tlv.NewTypeForDecodingErr(val, "chainfee.SatPerKWeight", l, 8)
|
||||
}
|
||||
|
||||
// NewCreateSessionTLV initializes a new CreateSessionTLV message.
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
||||
@ -86,7 +87,7 @@ func genTaskTest(
|
||||
toLocalAmt int64,
|
||||
toRemoteAmt int64,
|
||||
blobType blob.Type,
|
||||
sweepFeeRate lnwallet.SatPerKWeight,
|
||||
sweepFeeRate chainfee.SatPerKWeight,
|
||||
rewardScript []byte,
|
||||
expSweepAmt int64,
|
||||
expRewardAmt int64,
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
|
||||
)
|
||||
@ -58,7 +58,7 @@ func ReadElement(r io.Reader, element interface{}) error {
|
||||
}
|
||||
|
||||
e.BlobType = blob.Type(blobType)
|
||||
e.SweepFeeRate = lnwallet.SatPerKWeight(sweepFeeRate)
|
||||
e.SweepFeeRate = chainfee.SatPerKWeight(sweepFeeRate)
|
||||
|
||||
// Type is still unknown to wtdb extensions, fail.
|
||||
default:
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
)
|
||||
|
||||
@ -27,11 +28,11 @@ const (
|
||||
|
||||
// DefaultSweepFeeRate specifies the fee rate used to construct justice
|
||||
// transactions. The value is expressed in satoshis per kilo-weight.
|
||||
DefaultSweepFeeRate = lnwallet.SatPerKWeight(2500)
|
||||
DefaultSweepFeeRate = chainfee.SatPerKWeight(2500)
|
||||
|
||||
// MinSweepFeeRate is the minimum sweep fee rate a client may use in its
|
||||
// policy, the current value is 4 sat/vbyte.
|
||||
MinSweepFeeRate = lnwallet.SatPerKWeight(1000)
|
||||
MinSweepFeeRate = chainfee.SatPerKWeight(1000)
|
||||
)
|
||||
|
||||
var (
|
||||
@ -97,7 +98,7 @@ type TxPolicy struct {
|
||||
// constructing the justice transaction. All sweep transactions created
|
||||
// for this session must use this value during construction, and the
|
||||
// signatures must implicitly commit to the resulting output values.
|
||||
SweepFeeRate lnwallet.SatPerKWeight
|
||||
SweepFeeRate chainfee.SatPerKWeight
|
||||
}
|
||||
|
||||
// Policy defines the negotiated parameters for a session between a client and
|
||||
|
@ -3,7 +3,7 @@ package wtwire
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
)
|
||||
|
||||
@ -34,7 +34,7 @@ type CreateSession struct {
|
||||
// constructing the justice transaction. All sweep transactions created
|
||||
// for this session must use this value during construction, and the
|
||||
// signatures must implicitly commit to the resulting output values.
|
||||
SweepFeeRate lnwallet.SatPerKWeight
|
||||
SweepFeeRate chainfee.SatPerKWeight
|
||||
}
|
||||
|
||||
// A compile time check to ensure CreateSession implements the wtwire.Message
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/watchtower/blob"
|
||||
)
|
||||
@ -74,7 +74,7 @@ func WriteElement(w io.Writer, element interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
case lnwallet.SatPerKWeight:
|
||||
case chainfee.SatPerKWeight:
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(e))
|
||||
if _, err := w.Write(b[:]); err != nil {
|
||||
@ -194,12 +194,12 @@ func ReadElement(r io.Reader, element interface{}) error {
|
||||
}
|
||||
*e = bytes
|
||||
|
||||
case *lnwallet.SatPerKWeight:
|
||||
case *chainfee.SatPerKWeight:
|
||||
var b [8]byte
|
||||
if _, err := io.ReadFull(r, b[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
*e = lnwallet.SatPerKWeight(binary.BigEndian.Uint64(b[:]))
|
||||
*e = chainfee.SatPerKWeight(binary.BigEndian.Uint64(b[:]))
|
||||
|
||||
case *ErrorCode:
|
||||
var b [2]byte
|
||||
|
Loading…
Reference in New Issue
Block a user