Skip to content

Commit

Permalink
chainfee: create new chainfee package extracting fees from lnwallet
Browse files Browse the repository at this point in the history
In this commit, we create a new chainfee package, that houses all fee
related functionality used within the codebase. The creation of this new
package furthers our long-term goal of extracting functionality from the
bloated `lnwallet` package into new distinct packages. Additionally,
this new packages resolves a class of import cycle that could arise if a
new package that was imported by something in `lnwallet` wanted to use
the existing fee related functions in the prior `lnwallet` package.
  • Loading branch information
Roasbeef committed Oct 31, 2019
1 parent fcf81ed commit 777ed10
Show file tree
Hide file tree
Showing 47 changed files with 536 additions and 400 deletions.
3 changes: 2 additions & 1 deletion breacharbiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions breacharbiter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
27 changes: 14 additions & 13 deletions chainregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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.
Expand Down Expand Up @@ -112,7 +113,7 @@ func (c chainCode) String() string {
type chainControl struct {
chainIO lnwallet.BlockChainIO

feeEstimator lnwallet.FeeEstimator
feeEstimator chainfee.Estimator

signer input.Signer

Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion chancloser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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_
Expand Down
3 changes: 2 additions & 1 deletion contractcourt/chain_arbitrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions fundingmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions fundingmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down
13 changes: 7 additions & 6 deletions htlcswitch/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand All @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1894,7 +1895,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)
Expand Down Expand Up @@ -2394,7 +2395,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)

Expand Down
19 changes: 10 additions & 9 deletions htlcswitch/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}{

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
}

Expand Down
Loading

0 comments on commit 777ed10

Please sign in to comment.