multi: update to latest fee estimation interface
This commit is contained in:
parent
a63677a381
commit
9d2eeb6304
@ -1351,7 +1351,7 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
|
|||||||
ba := newBreachArbiter(&BreachConfig{
|
ba := newBreachArbiter(&BreachConfig{
|
||||||
CloseLink: func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {},
|
CloseLink: func(_ *wire.OutPoint, _ htlcswitch.ChannelCloseType) {},
|
||||||
DB: db,
|
DB: db,
|
||||||
Estimator: &lnwallet.StaticFeeEstimator{FeeRate: 50},
|
Estimator: &lnwallet.StaticFeeEstimator{FeePerKW: 12500},
|
||||||
GenSweepScript: func() ([]byte, error) { return nil, nil },
|
GenSweepScript: func() ([]byte, error) { return nil, nil },
|
||||||
ContractBreaches: contractBreaches,
|
ContractBreaches: contractBreaches,
|
||||||
Signer: signer,
|
Signer: signer,
|
||||||
@ -1491,12 +1491,11 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa
|
|||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{FeeRate: 50}
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 12500}
|
||||||
feePerVSize, err := estimator.EstimateFeePerVSize(1)
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
|
|
||||||
// TODO(roasbeef): need to factor in commit fee?
|
// TODO(roasbeef): need to factor in commit fee?
|
||||||
aliceCommit := channeldb.ChannelCommitment{
|
aliceCommit := channeldb.ChannelCommitment{
|
||||||
|
@ -37,15 +37,21 @@ const (
|
|||||||
defaultBitcoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
|
defaultBitcoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
|
||||||
defaultBitcoinFeeRate = lnwire.MilliSatoshi(1)
|
defaultBitcoinFeeRate = lnwire.MilliSatoshi(1)
|
||||||
defaultBitcoinTimeLockDelta = 144
|
defaultBitcoinTimeLockDelta = 144
|
||||||
defaultBitcoinStaticFeeRate = lnwallet.SatPerVByte(50)
|
|
||||||
|
|
||||||
defaultLitecoinMinHTLCMSat = lnwire.MilliSatoshi(1000)
|
defaultLitecoinMinHTLCMSat = lnwire.MilliSatoshi(1000)
|
||||||
defaultLitecoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
|
defaultLitecoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
|
||||||
defaultLitecoinFeeRate = lnwire.MilliSatoshi(1)
|
defaultLitecoinFeeRate = lnwire.MilliSatoshi(1)
|
||||||
defaultLitecoinTimeLockDelta = 576
|
defaultLitecoinTimeLockDelta = 576
|
||||||
defaultLitecoinStaticFeeRate = lnwallet.SatPerVByte(200)
|
|
||||||
defaultLitecoinDustLimit = btcutil.Amount(54600)
|
defaultLitecoinDustLimit = btcutil.Amount(54600)
|
||||||
|
|
||||||
|
// defaultBitcoinStaticFeePerKW is the fee rate of 50 sat/vbyte
|
||||||
|
// expressed in sat/kw.
|
||||||
|
defaultBitcoinStaticFeePerKW = lnwallet.SatPerKWeight(12500)
|
||||||
|
|
||||||
|
// defaultLitecoinStaticFeePerKW is the fee rate of 200 sat/vbyte
|
||||||
|
// expressed in sat/kw.
|
||||||
|
defaultLitecoinStaticFeePerKW = lnwallet.SatPerKWeight(50000)
|
||||||
|
|
||||||
// btcToLtcConversionRate is a fixed ratio used in order to scale up
|
// btcToLtcConversionRate is a fixed ratio used in order to scale up
|
||||||
// payments when running on the Litecoin chain.
|
// payments when running on the Litecoin chain.
|
||||||
btcToLtcConversionRate = 60
|
btcToLtcConversionRate = 60
|
||||||
@ -141,7 +147,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
|
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
|
||||||
}
|
}
|
||||||
cc.feeEstimator = lnwallet.StaticFeeEstimator{
|
cc.feeEstimator = lnwallet.StaticFeeEstimator{
|
||||||
FeeRate: defaultBitcoinStaticFeeRate,
|
FeePerKW: defaultBitcoinStaticFeePerKW,
|
||||||
}
|
}
|
||||||
case litecoinChain:
|
case litecoinChain:
|
||||||
cc.routingPolicy = htlcswitch.ForwardingPolicy{
|
cc.routingPolicy = htlcswitch.ForwardingPolicy{
|
||||||
@ -151,7 +157,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
|
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
|
||||||
}
|
}
|
||||||
cc.feeEstimator = lnwallet.StaticFeeEstimator{
|
cc.feeEstimator = lnwallet.StaticFeeEstimator{
|
||||||
FeeRate: defaultLitecoinStaticFeeRate,
|
FeePerKW: defaultLitecoinStaticFeePerKW,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, nil, fmt.Errorf("Default routing policy for "+
|
return nil, nil, fmt.Errorf("Default routing policy for "+
|
||||||
@ -337,9 +343,9 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
// if we're using bitcoind as a backend, then we can
|
// if we're using bitcoind as a backend, then we can
|
||||||
// use live fee estimates, rather than a statically
|
// use live fee estimates, rather than a statically
|
||||||
// coded value.
|
// coded value.
|
||||||
fallBackFeeRate := lnwallet.SatPerVByte(25)
|
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||||
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
||||||
*rpcConfig, fallBackFeeRate,
|
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -354,9 +360,9 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
// if we're using litecoind as a backend, then we can
|
// if we're using litecoind as a backend, then we can
|
||||||
// use live fee estimates, rather than a statically
|
// use live fee estimates, rather than a statically
|
||||||
// coded value.
|
// coded value.
|
||||||
fallBackFeeRate := lnwallet.SatPerVByte(25)
|
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||||
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
||||||
*rpcConfig, fallBackFeeRate,
|
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -457,9 +463,9 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
// if we're using btcd as a backend, then we can use
|
// if we're using btcd as a backend, then we can use
|
||||||
// live fee estimates, rather than a statically coded
|
// live fee estimates, rather than a statically coded
|
||||||
// value.
|
// value.
|
||||||
fallBackFeeRate := lnwallet.SatPerVByte(25)
|
fallBackFeeRate := lnwallet.SatPerKVByte(25 * 1000)
|
||||||
cc.feeEstimator, err = lnwallet.NewBtcdFeeEstimator(
|
cc.feeEstimator, err = lnwallet.NewBtcdFeeEstimator(
|
||||||
*rpcConfig, fallBackFeeRate,
|
*rpcConfig, fallBackFeeRate.FeePerKWeight(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -8,10 +8,6 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/salsa20"
|
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
"github.com/btcsuite/btcd/btcec"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
@ -28,6 +24,8 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/routing"
|
"github.com/lightningnetwork/lnd/routing"
|
||||||
|
"golang.org/x/crypto/salsa20"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -68,11 +66,6 @@ const (
|
|||||||
// currently accepted on the Litecoin chain within the Lightning
|
// currently accepted on the Litecoin chain within the Lightning
|
||||||
// Protocol.
|
// Protocol.
|
||||||
maxLtcFundingAmount = maxBtcFundingAmount * btcToLtcConversionRate
|
maxLtcFundingAmount = maxBtcFundingAmount * btcToLtcConversionRate
|
||||||
|
|
||||||
// minCommitFeePerKw is the smallest fee rate that we should propose
|
|
||||||
// for a new fee update. We'll use this as a fee floor when proposing
|
|
||||||
// and accepting updates.
|
|
||||||
minCommitFeePerKw = 253
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -1028,8 +1021,8 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
reservation, err := f.cfg.Wallet.InitChannelReservation(
|
reservation, err := f.cfg.Wallet.InitChannelReservation(
|
||||||
amt, 0, msg.PushAmount,
|
amt, 0, msg.PushAmount,
|
||||||
lnwallet.SatPerKWeight(msg.FeePerKiloWeight), 0,
|
lnwallet.SatPerKWeight(msg.FeePerKiloWeight), 0,
|
||||||
fmsg.peer.IdentityKey(), fmsg.peer.Address(),
|
fmsg.peer.IdentityKey(), fmsg.peer.Address(), &chainHash,
|
||||||
&chainHash, msg.ChannelFlags,
|
msg.ChannelFlags,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("Unable to initialize reservation: %v", err)
|
fndgLog.Errorf("Unable to initialize reservation: %v", err)
|
||||||
@ -2543,23 +2536,12 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
// commitment transaction confirmed by the next few blocks (conf target
|
// commitment transaction confirmed by the next few blocks (conf target
|
||||||
// of 3). We target the near blocks here to ensure that we'll be able
|
// of 3). We target the near blocks here to ensure that we'll be able
|
||||||
// to execute a timely unilateral channel closure if needed.
|
// to execute a timely unilateral channel closure if needed.
|
||||||
feePerVSize, err := f.cfg.FeeEstimator.EstimateFeePerVSize(3)
|
commitFeePerKw, err := f.cfg.FeeEstimator.EstimateFeePerKW(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg.err <- err
|
msg.err <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the converted fee-per-kw is below the current widely used policy
|
|
||||||
// floor, then we'll use the floor instead.
|
|
||||||
commitFeePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
if commitFeePerKw < minCommitFeePerKw {
|
|
||||||
fndgLog.Infof("Proposed fee rate of %v sat/kw is below min "+
|
|
||||||
"of %v sat/kw, using fee floor", int64(commitFeePerKw),
|
|
||||||
int64(minCommitFeePerKw))
|
|
||||||
|
|
||||||
commitFeePerKw = minCommitFeePerKw
|
|
||||||
}
|
|
||||||
|
|
||||||
// We set the channel flags to indicate whether we want this channel to
|
// We set the channel flags to indicate whether we want this channel to
|
||||||
// be announced to the network.
|
// be announced to the network.
|
||||||
var channelFlags lnwire.FundingFlag
|
var channelFlags lnwire.FundingFlag
|
||||||
@ -2573,7 +2555,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
// request will fail, and be aborted.
|
// request will fail, and be aborted.
|
||||||
reservation, err := f.cfg.Wallet.InitChannelReservation(
|
reservation, err := f.cfg.Wallet.InitChannelReservation(
|
||||||
capacity, localAmt, msg.pushAmt, commitFeePerKw,
|
capacity, localAmt, msg.pushAmt, commitFeePerKw,
|
||||||
msg.fundingFeePerVSize, peerKey, msg.peer.Address(),
|
msg.fundingFeePerKw, peerKey, msg.peer.Address(),
|
||||||
&msg.chainHash, channelFlags,
|
&msg.chainHash, channelFlags,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -235,7 +235,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
|||||||
addr *lnwire.NetAddress, tempTestDir string) (*testNode, error) {
|
addr *lnwire.NetAddress, tempTestDir string) (*testNode, error) {
|
||||||
|
|
||||||
netParams := activeNetParams.Params
|
netParams := activeNetParams.Params
|
||||||
estimator := lnwallet.StaticFeeEstimator{FeeRate: 250}
|
estimator := lnwallet.StaticFeeEstimator{FeePerKW: 62500}
|
||||||
|
|
||||||
chainNotifier := &mockNotifier{
|
chainNotifier := &mockNotifier{
|
||||||
oneConfChannel: make(chan *chainntnfs.TxConfirmation, 1),
|
oneConfChannel: make(chan *chainntnfs.TxConfirmation, 1),
|
||||||
|
@ -35,11 +35,6 @@ const (
|
|||||||
// TODO(roasbeef): must be < default delta
|
// TODO(roasbeef): must be < default delta
|
||||||
expiryGraceDelta = 2
|
expiryGraceDelta = 2
|
||||||
|
|
||||||
// minCommitFeePerKw is the smallest fee rate that we should propose
|
|
||||||
// for a new fee update. We'll use this as a fee floor when proposing
|
|
||||||
// and accepting updates.
|
|
||||||
minCommitFeePerKw = 253
|
|
||||||
|
|
||||||
// DefaultMinLinkFeeUpdateTimeout represents the minimum interval in
|
// DefaultMinLinkFeeUpdateTimeout represents the minimum interval in
|
||||||
// which a link should propose to update its commitment fee rate.
|
// which a link should propose to update its commitment fee rate.
|
||||||
DefaultMinLinkFeeUpdateTimeout = 10 * time.Minute
|
DefaultMinLinkFeeUpdateTimeout = 10 * time.Minute
|
||||||
@ -495,26 +490,13 @@ func (l *channelLink) EligibleToForward() bool {
|
|||||||
// this is the native rate used when computing the fee for commitment
|
// this is the native rate used when computing the fee for commitment
|
||||||
// transactions, and the second-level HTLC transactions.
|
// transactions, and the second-level HTLC transactions.
|
||||||
func (l *channelLink) sampleNetworkFee() (lnwallet.SatPerKWeight, error) {
|
func (l *channelLink) sampleNetworkFee() (lnwallet.SatPerKWeight, error) {
|
||||||
// We'll first query for the sat/vbyte recommended to be confirmed
|
// We'll first query for the sat/kw recommended to be confirmed within 3
|
||||||
// within 3 blocks.
|
// blocks.
|
||||||
feePerVSize, err := l.cfg.FeeEstimator.EstimateFeePerVSize(3)
|
feePerKw, err := l.cfg.FeeEstimator.EstimateFeePerKW(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once we have this fee rate, we'll convert to sat-per-kw.
|
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
|
|
||||||
// If the returned feePerKw is less than the current widely used
|
|
||||||
// policy, then we'll use that instead as a floor.
|
|
||||||
if feePerKw < minCommitFeePerKw {
|
|
||||||
log.Debugf("Proposed fee rate of %v sat/kw is below min "+
|
|
||||||
"of %v sat/kw, using fee floor", int64(feePerKw),
|
|
||||||
int64(minCommitFeePerKw))
|
|
||||||
|
|
||||||
feePerKw = minCommitFeePerKw
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("ChannelLink(%v): sampled fee rate for 3 block conf: %v "+
|
log.Debugf("ChannelLink(%v): sampled fee rate for 3 block conf: %v "+
|
||||||
"sat/kw", l, int64(feePerKw))
|
"sat/kw", l, int64(feePerKw))
|
||||||
|
|
||||||
|
@ -1726,14 +1726,11 @@ func TestChannelLinkBandwidthConsistency(t *testing.T) {
|
|||||||
coreLink.cfg.HodlMask = hodl.MaskFromFlags(hodl.ExitSettle)
|
coreLink.cfg.HodlMask = hodl.MaskFromFlags(hodl.ExitSettle)
|
||||||
coreLink.cfg.DebugHTLC = true
|
coreLink.cfg.DebugHTLC = true
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
htlcFee := lnwire.NewMSatFromSatoshis(
|
htlcFee := lnwire.NewMSatFromSatoshis(
|
||||||
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
||||||
)
|
)
|
||||||
@ -2140,14 +2137,11 @@ func TestChannelLinkBandwidthConsistencyOverflow(t *testing.T) {
|
|||||||
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
||||||
)
|
)
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
|
|
||||||
var htlcID uint64
|
var htlcID uint64
|
||||||
addLinkHTLC := func(id uint64, amt lnwire.MilliSatoshi) [32]byte {
|
addLinkHTLC := func(id uint64, amt lnwire.MilliSatoshi) [32]byte {
|
||||||
@ -2390,17 +2384,15 @@ func TestChannelLinkTrimCircuitsPending(t *testing.T) {
|
|||||||
|
|
||||||
// Compute the static fees that will be used to determine the
|
// Compute the static fees that will be used to determine the
|
||||||
// correctness of Alice's bandwidth when forwarding HTLCs.
|
// correctness of Alice's bandwidth when forwarding HTLCs.
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCommitFee := alice.channel.StateSnapshot().CommitFee
|
defaultCommitFee := alice.channel.StateSnapshot().CommitFee
|
||||||
htlcFee := lnwire.NewMSatFromSatoshis(
|
htlcFee := lnwire.NewMSatFromSatoshis(
|
||||||
feeRate.FeePerKWeight().FeeForWeight(lnwallet.HtlcWeight),
|
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
||||||
)
|
)
|
||||||
|
|
||||||
// The starting bandwidth of the channel should be exactly the amount
|
// The starting bandwidth of the channel should be exactly the amount
|
||||||
@ -2666,17 +2658,15 @@ func TestChannelLinkTrimCircuitsNoCommit(t *testing.T) {
|
|||||||
|
|
||||||
// Compute the static fees that will be used to determine the
|
// Compute the static fees that will be used to determine the
|
||||||
// correctness of Alice's bandwidth when forwarding HTLCs.
|
// correctness of Alice's bandwidth when forwarding HTLCs.
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCommitFee := alice.channel.StateSnapshot().CommitFee
|
defaultCommitFee := alice.channel.StateSnapshot().CommitFee
|
||||||
htlcFee := lnwire.NewMSatFromSatoshis(
|
htlcFee := lnwire.NewMSatFromSatoshis(
|
||||||
feeRate.FeePerKWeight().FeeForWeight(lnwallet.HtlcWeight),
|
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
||||||
)
|
)
|
||||||
|
|
||||||
// The starting bandwidth of the channel should be exactly the amount
|
// The starting bandwidth of the channel should be exactly the amount
|
||||||
@ -2926,14 +2916,11 @@ func TestChannelLinkBandwidthChanReserve(t *testing.T) {
|
|||||||
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
||||||
)
|
)
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
htlcFee := lnwire.NewMSatFromSatoshis(
|
htlcFee := lnwire.NewMSatFromSatoshis(
|
||||||
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
feePerKw.FeeForWeight(lnwallet.HtlcWeight),
|
||||||
)
|
)
|
||||||
@ -3460,15 +3447,9 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
|||||||
|
|
||||||
startingFeeRate := channels.aliceToBob.CommitFeeRate()
|
startingFeeRate := channels.aliceToBob.CommitFeeRate()
|
||||||
|
|
||||||
// Convert starting fee rate to sat/vbyte. This is usually a
|
|
||||||
// lossy conversion, but since the startingFeeRate is
|
|
||||||
// 6000 sat/kw in this case, we won't lose precision.
|
|
||||||
startingFeeRateSatPerVByte := lnwallet.SatPerVByte(
|
|
||||||
startingFeeRate * 4 / 1000)
|
|
||||||
|
|
||||||
// Next, we'll send the first fee rate response to Alice.
|
// Next, we'll send the first fee rate response to Alice.
|
||||||
select {
|
select {
|
||||||
case n.feeEstimator.byteFeeIn <- startingFeeRateSatPerVByte:
|
case n.feeEstimator.byteFeeIn <- startingFeeRate:
|
||||||
case <-time.After(time.Second * 5):
|
case <-time.After(time.Second * 5):
|
||||||
t.Fatalf("alice didn't query for the new network fee")
|
t.Fatalf("alice didn't query for the new network fee")
|
||||||
}
|
}
|
||||||
@ -3497,7 +3478,7 @@ func TestChannelLinkUpdateCommitFee(t *testing.T) {
|
|||||||
// fee update.
|
// fee update.
|
||||||
newFeeRate := startingFeeRate * 3
|
newFeeRate := startingFeeRate * 3
|
||||||
select {
|
select {
|
||||||
case n.feeEstimator.byteFeeIn <- startingFeeRateSatPerVByte * 3:
|
case n.feeEstimator.byteFeeIn <- newFeeRate:
|
||||||
case <-time.After(time.Second * 5):
|
case <-time.After(time.Second * 5):
|
||||||
t.Fatalf("alice didn't query for the new network fee")
|
t.Fatalf("alice didn't query for the new network fee")
|
||||||
}
|
}
|
||||||
|
@ -58,12 +58,14 @@ func (m *mockPreimageCache) SubscribeUpdates() *contractcourt.WitnessSubscriptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mockFeeEstimator struct {
|
type mockFeeEstimator struct {
|
||||||
byteFeeIn chan lnwallet.SatPerVByte
|
byteFeeIn chan lnwallet.SatPerKWeight
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockFeeEstimator) EstimateFeePerVSize(numBlocks uint32) (lnwallet.SatPerVByte, error) {
|
func (m *mockFeeEstimator) EstimateFeePerKW(
|
||||||
|
numBlocks uint32) (lnwallet.SatPerKWeight, error) {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case feeRate := <-m.byteFeeIn:
|
case feeRate := <-m.byteFeeIn:
|
||||||
return feeRate, nil
|
return feeRate, nil
|
||||||
|
@ -271,14 +271,11 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte,
|
|||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 6000}
|
||||||
FeeRate: 24,
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
}
|
|
||||||
feePerVSize, err := estimator.EstimateFeePerVSize(1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
commitFee := feePerKw.FeeForWeight(724)
|
commitFee := feePerKw.FeeForWeight(724)
|
||||||
|
|
||||||
const broadcastHeight = 1
|
const broadcastHeight = 1
|
||||||
@ -873,7 +870,7 @@ func newThreeHopNetwork(t testing.TB, aliceChannel, firstBobChannel,
|
|||||||
carolDecoder := newMockIteratorDecoder()
|
carolDecoder := newMockIteratorDecoder()
|
||||||
|
|
||||||
feeEstimator := &mockFeeEstimator{
|
feeEstimator := &mockFeeEstimator{
|
||||||
byteFeeIn: make(chan lnwallet.SatPerVByte),
|
byteFeeIn: make(chan lnwallet.SatPerKWeight),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,8 @@ func (n *NetworkHarness) SetUp(lndArgs []string) error {
|
|||||||
PkScript: addrScript,
|
PkScript: addrScript,
|
||||||
Value: btcutil.SatoshiPerBitcoin,
|
Value: btcutil.SatoshiPerBitcoin,
|
||||||
}
|
}
|
||||||
if _, err := n.Miner.SendOutputs([]*wire.TxOut{output}, 30); err != nil {
|
_, err = n.Miner.SendOutputs([]*wire.TxOut{output}, 7500)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1159,7 +1160,8 @@ func (n *NetworkHarness) sendCoins(ctx context.Context, amt btcutil.Amount,
|
|||||||
PkScript: addrScript,
|
PkScript: addrScript,
|
||||||
Value: int64(amt),
|
Value: int64(amt),
|
||||||
}
|
}
|
||||||
if _, err := n.Miner.SendOutputs([]*wire.TxOut{output}, 30); err != nil {
|
_, err = n.Miner.SendOutputs([]*wire.TxOut{output}, 7500)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,11 +272,11 @@ func (b *BtcWallet) GetPrivKey(a btcutil.Address) (*btcec.PrivateKey, error) {
|
|||||||
//
|
//
|
||||||
// This is a part of the WalletController interface.
|
// This is a part of the WalletController interface.
|
||||||
func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
||||||
feeRate lnwallet.SatPerVByte) (*chainhash.Hash, error) {
|
feeRate lnwallet.SatPerKWeight) (*chainhash.Hash, error) {
|
||||||
|
|
||||||
// The fee rate is passed in using units of sat/vbyte, so we'll scale
|
// Convert our fee rate from sat/kw to sat/kb since it's required by
|
||||||
// this up to sat/KB as the SendOutputs method requires this unit.
|
// SendOutputs.
|
||||||
feeSatPerKB := btcutil.Amount(feeRate * 1000)
|
feeSatPerKB := btcutil.Amount(feeRate.FeePerKVByte())
|
||||||
|
|
||||||
return b.wallet.SendOutputs(outputs, defaultAccount, 1, feeSatPerKB)
|
return b.wallet.SendOutputs(outputs, defaultAccount, 1, feeSatPerKB)
|
||||||
}
|
}
|
||||||
|
@ -1131,12 +1131,11 @@ func TestHTLCSigNumber(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate two values that will be below and above Bob's dust limit.
|
// Calculate two values that will be below and above Bob's dust limit.
|
||||||
estimator := &StaticFeeEstimator{24}
|
estimator := &StaticFeeEstimator{FeePerKW: 6000}
|
||||||
feePerVSize, err := estimator.EstimateFeePerVSize(1)
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to get fee: %v", err)
|
t.Fatalf("unable to get fee: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
|
|
||||||
belowDust := btcutil.Amount(500) + htlcTimeoutFee(feePerKw)
|
belowDust := btcutil.Amount(500) + htlcTimeoutFee(feePerKw)
|
||||||
aboveDust := btcutil.Amount(1400) + htlcSuccessFee(feePerKw)
|
aboveDust := btcutil.Amount(1400) + htlcSuccessFee(feePerKw)
|
||||||
|
@ -154,13 +154,13 @@ type WalletController interface {
|
|||||||
// error should be returned.
|
// error should be returned.
|
||||||
GetPrivKey(a btcutil.Address) (*btcec.PrivateKey, error)
|
GetPrivKey(a btcutil.Address) (*btcec.PrivateKey, error)
|
||||||
|
|
||||||
// SendOutputs funds, signs, and broadcasts a Bitcoin transaction
|
// SendOutputs funds, signs, and broadcasts a Bitcoin transaction paying
|
||||||
// paying out to the specified outputs. In the case the wallet has
|
// out to the specified outputs. In the case the wallet has insufficient
|
||||||
// insufficient funds, or the outputs are non-standard, an error should
|
// funds, or the outputs are non-standard, an error should be returned.
|
||||||
// be returned. This method also takes the target fee expressed in
|
// This method also takes the target fee expressed in sat/kw that should
|
||||||
// sat/vbyte that should be used when crafting the transaction.
|
// be used when crafting the transaction.
|
||||||
SendOutputs(outputs []*wire.TxOut,
|
SendOutputs(outputs []*wire.TxOut,
|
||||||
feeRate SatPerVByte) (*chainhash.Hash, error)
|
feeRate SatPerKWeight) (*chainhash.Hash, error)
|
||||||
|
|
||||||
// ListUnspentWitness returns all unspent outputs which are version 0
|
// ListUnspentWitness returns all unspent outputs which are version 0
|
||||||
// witness programs. The 'confirms' parameter indicates the minimum
|
// witness programs. The 'confirms' parameter indicates the minimum
|
||||||
|
@ -186,7 +186,7 @@ func loadTestCredits(miner *rpctest.Harness, w *lnwallet.LightningWallet,
|
|||||||
Value: int64(satoshiPerOutput),
|
Value: int64(satoshiPerOutput),
|
||||||
PkScript: script,
|
PkScript: script,
|
||||||
}
|
}
|
||||||
if _, err := miner.SendOutputs([]*wire.TxOut{output}, 10); err != nil {
|
if _, err := miner.SendOutputs([]*wire.TxOut{output}, 2500); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ func createTestWallet(tempTestDir string, miningNode *rpctest.Harness,
|
|||||||
WalletController: wc,
|
WalletController: wc,
|
||||||
Signer: signer,
|
Signer: signer,
|
||||||
ChainIO: bio,
|
ChainIO: bio,
|
||||||
FeeEstimator: lnwallet.StaticFeeEstimator{FeeRate: 10},
|
FeeEstimator: lnwallet.StaticFeeEstimator{FeePerKW: 2500},
|
||||||
DefaultConstraints: channeldb.ChannelConstraints{
|
DefaultConstraints: channeldb.ChannelConstraints{
|
||||||
DustLimit: 500,
|
DustLimit: 500,
|
||||||
MaxPendingAmount: lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) * 100,
|
MaxPendingAmount: lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin) * 100,
|
||||||
@ -290,14 +290,14 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
|
|||||||
|
|
||||||
// Alice initiates a channel funded with 5 BTC for each side, so 10 BTC
|
// Alice initiates a channel funded with 5 BTC for each side, so 10 BTC
|
||||||
// total. She also generates 2 BTC in change.
|
// total. She also generates 2 BTC in change.
|
||||||
feeRate, err := alice.Cfg.FeeEstimator.EstimateFeePerVSize(1)
|
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
aliceChanReservation, err := alice.InitChannelReservation(
|
aliceChanReservation, err := alice.InitChannelReservation(
|
||||||
fundingAmount*2, fundingAmount, 0, feePerKw, feeRate,
|
fundingAmount*2, fundingAmount, 0, feePerKw, feePerKw, bobPub,
|
||||||
bobPub, bobAddr, chainHash, lnwire.FFAnnounceChannel)
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize funding reservation: %v", err)
|
t.Fatalf("unable to initialize funding reservation: %v", err)
|
||||||
}
|
}
|
||||||
@ -325,9 +325,10 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
|
|||||||
// Bob does the same, generating his own contribution. He then also
|
// Bob does the same, generating his own contribution. He then also
|
||||||
// receives' Alice's contribution, and consumes that so we can continue
|
// receives' Alice's contribution, and consumes that so we can continue
|
||||||
// the funding process.
|
// the funding process.
|
||||||
bobChanReservation, err := bob.InitChannelReservation(fundingAmount*2,
|
bobChanReservation, err := bob.InitChannelReservation(
|
||||||
fundingAmount, 0, feePerKw, feeRate, alicePub, aliceAddr,
|
fundingAmount*2, fundingAmount, 0, feePerKw, feePerKw, alicePub,
|
||||||
chainHash, lnwire.FFAnnounceChannel)
|
aliceAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bob unable to init channel reservation: %v", err)
|
t.Fatalf("bob unable to init channel reservation: %v", err)
|
||||||
}
|
}
|
||||||
@ -471,14 +472,13 @@ func testFundingTransactionLockedOutputs(miner *rpctest.Harness,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create amt: %v", err)
|
t.Fatalf("unable to create amt: %v", err)
|
||||||
}
|
}
|
||||||
feeRate, err := alice.Cfg.FeeEstimator.EstimateFeePerVSize(1)
|
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
_, err = alice.InitChannelReservation(
|
||||||
_, err = alice.InitChannelReservation(fundingAmount,
|
fundingAmount, fundingAmount, 0, feePerKw, feePerKw, bobPub,
|
||||||
fundingAmount, 0, feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
lnwire.FFAnnounceChannel,
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize funding reservation 1: %v", err)
|
t.Fatalf("unable to initialize funding reservation 1: %v", err)
|
||||||
@ -491,9 +491,10 @@ func testFundingTransactionLockedOutputs(miner *rpctest.Harness,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create amt: %v", err)
|
t.Fatalf("unable to create amt: %v", err)
|
||||||
}
|
}
|
||||||
failedReservation, err := alice.InitChannelReservation(amt, amt, 0,
|
failedReservation, err := alice.InitChannelReservation(
|
||||||
feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
amt, amt, 0, feePerKw, feePerKw, bobPub, bobAddr, chainHash,
|
||||||
lnwire.FFAnnounceChannel)
|
lnwire.FFAnnounceChannel,
|
||||||
|
)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("not error returned, should fail on coin selection")
|
t.Fatalf("not error returned, should fail on coin selection")
|
||||||
}
|
}
|
||||||
@ -508,28 +509,28 @@ func testFundingTransactionLockedOutputs(miner *rpctest.Harness,
|
|||||||
func testFundingCancellationNotEnoughFunds(miner *rpctest.Harness,
|
func testFundingCancellationNotEnoughFunds(miner *rpctest.Harness,
|
||||||
alice, _ *lnwallet.LightningWallet, t *testing.T) {
|
alice, _ *lnwallet.LightningWallet, t *testing.T) {
|
||||||
|
|
||||||
feeRate, err := alice.Cfg.FeeEstimator.EstimateFeePerVSize(1)
|
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
|
|
||||||
// Create a reservation for 44 BTC.
|
// Create a reservation for 44 BTC.
|
||||||
fundingAmount, err := btcutil.NewAmount(44)
|
fundingAmount, err := btcutil.NewAmount(44)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create amt: %v", err)
|
t.Fatalf("unable to create amt: %v", err)
|
||||||
}
|
}
|
||||||
chanReservation, err := alice.InitChannelReservation(fundingAmount,
|
chanReservation, err := alice.InitChannelReservation(
|
||||||
fundingAmount, 0, feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
fundingAmount, fundingAmount, 0, feePerKw, feePerKw, bobPub,
|
||||||
lnwire.FFAnnounceChannel)
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize funding reservation: %v", err)
|
t.Fatalf("unable to initialize funding reservation: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to create another channel with 44 BTC, this should fail.
|
// Attempt to create another channel with 44 BTC, this should fail.
|
||||||
_, err = alice.InitChannelReservation(fundingAmount,
|
_, err = alice.InitChannelReservation(
|
||||||
fundingAmount, 0, feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
fundingAmount, fundingAmount, 0, feePerKw, feePerKw, bobPub,
|
||||||
lnwire.FFAnnounceChannel,
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
)
|
)
|
||||||
if _, ok := err.(*lnwallet.ErrInsufficientFunds); !ok {
|
if _, ok := err.(*lnwallet.ErrInsufficientFunds); !ok {
|
||||||
t.Fatalf("coin selection succeeded should have insufficient funds: %v",
|
t.Fatalf("coin selection succeeded should have insufficient funds: %v",
|
||||||
@ -560,7 +561,7 @@ func testFundingCancellationNotEnoughFunds(miner *rpctest.Harness,
|
|||||||
|
|
||||||
// Request to fund a new channel should now succeed.
|
// Request to fund a new channel should now succeed.
|
||||||
_, err = alice.InitChannelReservation(fundingAmount, fundingAmount,
|
_, err = alice.InitChannelReservation(fundingAmount, fundingAmount,
|
||||||
0, feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
0, feePerKw, feePerKw, bobPub, bobAddr, chainHash,
|
||||||
lnwire.FFAnnounceChannel)
|
lnwire.FFAnnounceChannel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to initialize funding reservation: %v", err)
|
t.Fatalf("unable to initialize funding reservation: %v", err)
|
||||||
@ -570,15 +571,15 @@ func testFundingCancellationNotEnoughFunds(miner *rpctest.Harness,
|
|||||||
func testCancelNonExistentReservation(miner *rpctest.Harness,
|
func testCancelNonExistentReservation(miner *rpctest.Harness,
|
||||||
alice, _ *lnwallet.LightningWallet, t *testing.T) {
|
alice, _ *lnwallet.LightningWallet, t *testing.T) {
|
||||||
|
|
||||||
feeRate, err := alice.Cfg.FeeEstimator.EstimateFeePerVSize(1)
|
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create our own reservation, give it some ID.
|
// Create our own reservation, give it some ID.
|
||||||
res, err := lnwallet.NewChannelReservation(
|
res, err := lnwallet.NewChannelReservation(
|
||||||
10000, 10000, feeRate.FeePerKWeight(), alice,
|
10000, 10000, feePerKw, alice, 22, 10, &testHdSeed,
|
||||||
22, 10, &testHdSeed, lnwire.FFAnnounceChannel,
|
lnwire.FFAnnounceChannel,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create res: %v", err)
|
t.Fatalf("unable to create res: %v", err)
|
||||||
@ -597,14 +598,17 @@ func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness,
|
|||||||
// We'll attempt to create a new reservation with an extremely high fee
|
// We'll attempt to create a new reservation with an extremely high fee
|
||||||
// rate. This should push our balance into the negative and result in a
|
// rate. This should push our balance into the negative and result in a
|
||||||
// failure to create the reservation.
|
// failure to create the reservation.
|
||||||
fundingAmount, err := btcutil.NewAmount(4)
|
const numBTC = 4
|
||||||
|
fundingAmount, err := btcutil.NewAmount(numBTC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create amt: %v", err)
|
t.Fatalf("unable to create amt: %v", err)
|
||||||
}
|
}
|
||||||
feePerVSize := lnwallet.SatPerVByte(btcutil.SatoshiPerBitcoin * 4 / 100)
|
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
feePerKw := lnwallet.SatPerKWeight(
|
||||||
|
numBTC * numBTC * btcutil.SatoshiPerBitcoin,
|
||||||
|
)
|
||||||
_, err = alice.InitChannelReservation(
|
_, err = alice.InitChannelReservation(
|
||||||
fundingAmount, fundingAmount, 0, feePerKw, feePerVSize, bobPub,
|
fundingAmount, fundingAmount, 0, feePerKw, feePerKw, bobPub,
|
||||||
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
)
|
)
|
||||||
switch {
|
switch {
|
||||||
@ -672,14 +676,14 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
|||||||
t.Fatalf("unable to create amt: %v", err)
|
t.Fatalf("unable to create amt: %v", err)
|
||||||
}
|
}
|
||||||
pushAmt := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin)
|
pushAmt := lnwire.NewMSatFromSatoshis(btcutil.SatoshiPerBitcoin)
|
||||||
feeRate, err := alice.Cfg.FeeEstimator.EstimateFeePerVSize(1)
|
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
aliceChanReservation, err := alice.InitChannelReservation(
|
||||||
aliceChanReservation, err := alice.InitChannelReservation(fundingAmt,
|
fundingAmt, fundingAmt, pushAmt, feePerKw, feePerKw, bobPub,
|
||||||
fundingAmt, pushAmt, feePerKw, feeRate, bobPub, bobAddr, chainHash,
|
bobAddr, chainHash, lnwire.FFAnnounceChannel,
|
||||||
lnwire.FFAnnounceChannel)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to init channel reservation: %v", err)
|
t.Fatalf("unable to init channel reservation: %v", err)
|
||||||
}
|
}
|
||||||
@ -707,9 +711,10 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
|||||||
|
|
||||||
// Next, Bob receives the initial request, generates a corresponding
|
// Next, Bob receives the initial request, generates a corresponding
|
||||||
// reservation initiation, then consume Alice's contribution.
|
// reservation initiation, then consume Alice's contribution.
|
||||||
bobChanReservation, err := bob.InitChannelReservation(fundingAmt, 0,
|
bobChanReservation, err := bob.InitChannelReservation(
|
||||||
pushAmt, feePerKw, feeRate, alicePub, aliceAddr, chainHash,
|
fundingAmt, 0, pushAmt, feePerKw, feePerKw, alicePub, aliceAddr,
|
||||||
lnwire.FFAnnounceChannel)
|
chainHash, lnwire.FFAnnounceChannel,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create bob reservation: %v", err)
|
t.Fatalf("unable to create bob reservation: %v", err)
|
||||||
}
|
}
|
||||||
@ -891,7 +896,7 @@ func testListTransactionDetails(miner *rpctest.Harness,
|
|||||||
Value: outputAmt,
|
Value: outputAmt,
|
||||||
PkScript: script,
|
PkScript: script,
|
||||||
}
|
}
|
||||||
txid, err := miner.SendOutputs([]*wire.TxOut{output}, 10)
|
txid, err := miner.SendOutputs([]*wire.TxOut{output}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to send coinbase: %v", err)
|
t.Fatalf("unable to send coinbase: %v", err)
|
||||||
}
|
}
|
||||||
@ -994,7 +999,7 @@ func testListTransactionDetails(miner *rpctest.Harness,
|
|||||||
t.Fatalf("unable to make output script: %v", err)
|
t.Fatalf("unable to make output script: %v", err)
|
||||||
}
|
}
|
||||||
burnOutput := wire.NewTxOut(outputAmt, outputScript)
|
burnOutput := wire.NewTxOut(outputAmt, outputScript)
|
||||||
burnTXID, err := alice.SendOutputs([]*wire.TxOut{burnOutput}, 10)
|
burnTXID, err := alice.SendOutputs([]*wire.TxOut{burnOutput}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create burn tx: %v", err)
|
t.Fatalf("unable to create burn tx: %v", err)
|
||||||
}
|
}
|
||||||
@ -1108,7 +1113,7 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
|
|||||||
Value: outputAmt,
|
Value: outputAmt,
|
||||||
PkScript: script,
|
PkScript: script,
|
||||||
}
|
}
|
||||||
txid, err := miner.SendOutputs([]*wire.TxOut{output}, 10)
|
txid, err := miner.SendOutputs([]*wire.TxOut{output}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to send coinbase: %v", err)
|
t.Fatalf("unable to send coinbase: %v", err)
|
||||||
}
|
}
|
||||||
@ -1308,7 +1313,7 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||||||
Value: btcutil.SatoshiPerBitcoin,
|
Value: btcutil.SatoshiPerBitcoin,
|
||||||
PkScript: keyScript,
|
PkScript: keyScript,
|
||||||
}
|
}
|
||||||
txid, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 10)
|
txid, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create output: %v", err)
|
t.Fatalf("unable to create output: %v", err)
|
||||||
}
|
}
|
||||||
@ -1553,7 +1558,7 @@ func testSignOutputUsingTweaks(r *rpctest.Harness,
|
|||||||
Value: btcutil.SatoshiPerBitcoin,
|
Value: btcutil.SatoshiPerBitcoin,
|
||||||
PkScript: keyScript,
|
PkScript: keyScript,
|
||||||
}
|
}
|
||||||
txid, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 10)
|
txid, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create output: %v", err)
|
t.Fatalf("unable to create output: %v", err)
|
||||||
}
|
}
|
||||||
@ -1679,7 +1684,7 @@ func testReorgWalletBalance(r *rpctest.Harness, w *lnwallet.LightningWallet,
|
|||||||
Value: 1e8,
|
Value: 1e8,
|
||||||
PkScript: script,
|
PkScript: script,
|
||||||
}
|
}
|
||||||
txid, err := w.SendOutputs([]*wire.TxOut{output}, 10)
|
txid, err := w.SendOutputs([]*wire.TxOut{output}, 2500)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to send outputs: %v", err)
|
t.Fatalf("unable to send outputs: %v", err)
|
||||||
}
|
}
|
||||||
@ -2073,7 +2078,7 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "neutrino":
|
case "neutrino":
|
||||||
feeEstimator = lnwallet.StaticFeeEstimator{FeeRate: 250}
|
feeEstimator = lnwallet.StaticFeeEstimator{FeePerKW: 62500}
|
||||||
|
|
||||||
// Set some package-level variable to speed up
|
// Set some package-level variable to speed up
|
||||||
// operation for tests.
|
// operation for tests.
|
||||||
|
@ -229,12 +229,11 @@ func CreateTestChannels() (*LightningChannel, *LightningChannel, func(), error)
|
|||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := &StaticFeeEstimator{24}
|
estimator := &StaticFeeEstimator{FeePerKW: 6000}
|
||||||
feePerVSize, err := estimator.EstimateFeePerVSize(1)
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
commitFee := calcStaticFee(0)
|
commitFee := calcStaticFee(0)
|
||||||
|
|
||||||
aliceCommit := channeldb.ChannelCommitment{
|
aliceCommit := channeldb.ChannelCommitment{
|
||||||
|
2
mock.go
2
mock.go
@ -224,7 +224,7 @@ func (*mockWalletController) GetPrivKey(a btcutil.Address) (*btcec.PrivateKey, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
|
func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
|
||||||
_ lnwallet.SatPerVByte) (*chainhash.Hash, error) {
|
_ lnwallet.SatPerKWeight) (*chainhash.Hash, error) {
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
9
peer.go
9
peer.go
@ -1658,18 +1658,13 @@ func (p *peer) fetchActiveChanCloser(chanID lnwire.ChannelID) (*channelCloser, e
|
|||||||
// In order to begin fee negotiations, we'll first compute our
|
// In order to begin fee negotiations, we'll first compute our
|
||||||
// target ideal fee-per-kw. We'll set this to a lax value, as
|
// target ideal fee-per-kw. We'll set this to a lax value, as
|
||||||
// we weren't the ones that initiated the channel closure.
|
// we weren't the ones that initiated the channel closure.
|
||||||
feePerVSize, err := p.server.cc.feeEstimator.EstimateFeePerVSize(6)
|
feePerKw, err := p.server.cc.feeEstimator.EstimateFeePerKW(6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
peerLog.Errorf("unable to query fee estimator: %v", err)
|
peerLog.Errorf("unable to query fee estimator: %v", err)
|
||||||
|
|
||||||
return nil, fmt.Errorf("unable to estimate fee")
|
return nil, fmt.Errorf("unable to estimate fee")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll then convert the sat per weight to sat per k/w as this
|
|
||||||
// is the native unit used within the protocol when dealing
|
|
||||||
// with fees.
|
|
||||||
targetFeePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
|
|
||||||
_, startingHeight, err := p.server.cc.chainIO.GetBestBlock()
|
_, startingHeight, err := p.server.cc.chainIO.GetBestBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
peerLog.Errorf("unable to obtain best block: %v", err)
|
peerLog.Errorf("unable to obtain best block: %v", err)
|
||||||
@ -1685,7 +1680,7 @@ func (p *peer) fetchActiveChanCloser(chanID lnwire.ChannelID) (*channelCloser, e
|
|||||||
quit: p.quit,
|
quit: p.quit,
|
||||||
},
|
},
|
||||||
deliveryAddr,
|
deliveryAddr,
|
||||||
targetFeePerKw,
|
feePerKw,
|
||||||
uint32(startingHeight),
|
uint32(startingHeight),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
13
peer_test.go
13
peer_test.go
@ -169,12 +169,11 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) {
|
|||||||
dummyDeliveryScript),
|
dummyDeliveryScript),
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := lnwallet.StaticFeeEstimator{FeeRate: 50}
|
estimator := lnwallet.StaticFeeEstimator{FeePerKW: 12500}
|
||||||
feeRate, err := estimator.EstimateFeePerVSize(1)
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
feePerKw := feeRate.FeePerKWeight()
|
|
||||||
fee := responderChan.CalcFee(feePerKw)
|
fee := responderChan.CalcFee(feePerKw)
|
||||||
closeSig, _, _, err := responderChan.CreateCloseProposal(fee,
|
closeSig, _, _, err := responderChan.CreateCloseProposal(fee,
|
||||||
dummyDeliveryScript, initiatorDeliveryScript)
|
dummyDeliveryScript, initiatorDeliveryScript)
|
||||||
@ -460,14 +459,12 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) {
|
|||||||
msg: respShutdown,
|
msg: respShutdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := lnwallet.StaticFeeEstimator{FeeRate: 50}
|
estimator := lnwallet.StaticFeeEstimator{FeePerKW: 12500}
|
||||||
initiatorIdealFeeRate, err := estimator.EstimateFeePerVSize(1)
|
initiatorIdealFeeRate, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query fee estimator: %v", err)
|
t.Fatalf("unable to query fee estimator: %v", err)
|
||||||
}
|
}
|
||||||
initiatorIdealFee := responderChan.CalcFee(
|
initiatorIdealFee := responderChan.CalcFee(initiatorIdealFeeRate)
|
||||||
initiatorIdealFeeRate.FeePerKWeight(),
|
|
||||||
)
|
|
||||||
increasedFee := btcutil.Amount(float64(initiatorIdealFee) * 2.5)
|
increasedFee := btcutil.Amount(float64(initiatorIdealFee) * 2.5)
|
||||||
closeSig, _, _, err := responderChan.CreateCloseProposal(
|
closeSig, _, _, err := responderChan.CreateCloseProposal(
|
||||||
increasedFee, dummyDeliveryScript, initiatorDeliveryScript,
|
increasedFee, dummyDeliveryScript, initiatorDeliveryScript,
|
||||||
|
7
pilot.go
7
pilot.go
@ -80,7 +80,7 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
|
|||||||
|
|
||||||
// With the connection established, we'll now establish our connection
|
// With the connection established, we'll now establish our connection
|
||||||
// to the target peer, waiting for the first update before we exit.
|
// to the target peer, waiting for the first update before we exit.
|
||||||
feePerVSize, err := c.server.cc.feeEstimator.EstimateFeePerVSize(3)
|
feePerKw, err := c.server.cc.feeEstimator.EstimateFeePerKW(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -88,8 +88,9 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
|
|||||||
// TODO(halseth): make configurable?
|
// TODO(halseth): make configurable?
|
||||||
minHtlc := lnwire.NewMSatFromSatoshis(1)
|
minHtlc := lnwire.NewMSatFromSatoshis(1)
|
||||||
|
|
||||||
updateStream, errChan := c.server.OpenChannel(target, amt, 0,
|
updateStream, errChan := c.server.OpenChannel(
|
||||||
minHtlc, feePerVSize, false, 0)
|
target, amt, 0, minHtlc, feePerKw, false, 0,
|
||||||
|
)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
|
@ -92,7 +92,7 @@ func getTestTXID(miner *rpctest.Harness) (*chainhash.Hash, error) {
|
|||||||
PkScript: script,
|
PkScript: script,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return miner.SendOutputs(outputs, 10)
|
return miner.SendOutputs(outputs, 2500)
|
||||||
}
|
}
|
||||||
|
|
||||||
func locateOutput(tx *wire.MsgTx, script []byte) (*wire.OutPoint, *wire.TxOut, error) {
|
func locateOutput(tx *wire.MsgTx, script []byte) (*wire.OutPoint, *wire.TxOut, error) {
|
||||||
|
28
server.go
28
server.go
@ -2537,7 +2537,7 @@ type openChanReq struct {
|
|||||||
|
|
||||||
pushAmt lnwire.MilliSatoshi
|
pushAmt lnwire.MilliSatoshi
|
||||||
|
|
||||||
fundingFeePerVSize lnwallet.SatPerVByte
|
fundingFeePerKw lnwallet.SatPerKWeight
|
||||||
|
|
||||||
private bool
|
private bool
|
||||||
|
|
||||||
@ -2685,7 +2685,7 @@ func (s *server) DisconnectPeer(pubKey *btcec.PublicKey) error {
|
|||||||
// NOTE: This function is safe for concurrent access.
|
// NOTE: This function is safe for concurrent access.
|
||||||
func (s *server) OpenChannel(nodeKey *btcec.PublicKey,
|
func (s *server) OpenChannel(nodeKey *btcec.PublicKey,
|
||||||
localAmt btcutil.Amount, pushAmt, minHtlc lnwire.MilliSatoshi,
|
localAmt btcutil.Amount, pushAmt, minHtlc lnwire.MilliSatoshi,
|
||||||
fundingFeePerVSize lnwallet.SatPerVByte, private bool,
|
fundingFeePerKw lnwallet.SatPerKWeight, private bool,
|
||||||
remoteCsvDelay uint16) (chan *lnrpc.OpenStatusUpdate, chan error) {
|
remoteCsvDelay uint16) (chan *lnrpc.OpenStatusUpdate, chan error) {
|
||||||
|
|
||||||
// The updateChan will have a buffer of 2, since we expect a
|
// The updateChan will have a buffer of 2, since we expect a
|
||||||
@ -2723,9 +2723,9 @@ func (s *server) OpenChannel(nodeKey *btcec.PublicKey,
|
|||||||
|
|
||||||
// If the fee rate wasn't specified, then we'll use a default
|
// If the fee rate wasn't specified, then we'll use a default
|
||||||
// confirmation target.
|
// confirmation target.
|
||||||
if fundingFeePerVSize == 0 {
|
if fundingFeePerKw == 0 {
|
||||||
estimator := s.cc.feeEstimator
|
estimator := s.cc.feeEstimator
|
||||||
fundingFeePerVSize, err = estimator.EstimateFeePerVSize(6)
|
fundingFeePerKw, err = estimator.EstimateFeePerKW(6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return updateChan, errChan
|
return updateChan, errChan
|
||||||
@ -2737,16 +2737,16 @@ func (s *server) OpenChannel(nodeKey *btcec.PublicKey,
|
|||||||
// instead of blocking on this request which is exported as a
|
// instead of blocking on this request which is exported as a
|
||||||
// synchronous request to the outside world.
|
// synchronous request to the outside world.
|
||||||
req := &openChanReq{
|
req := &openChanReq{
|
||||||
targetPubkey: nodeKey,
|
targetPubkey: nodeKey,
|
||||||
chainHash: *activeNetParams.GenesisHash,
|
chainHash: *activeNetParams.GenesisHash,
|
||||||
localFundingAmt: localAmt,
|
localFundingAmt: localAmt,
|
||||||
fundingFeePerVSize: fundingFeePerVSize,
|
fundingFeePerKw: fundingFeePerKw,
|
||||||
pushAmt: pushAmt,
|
pushAmt: pushAmt,
|
||||||
private: private,
|
private: private,
|
||||||
minHtlc: minHtlc,
|
minHtlc: minHtlc,
|
||||||
remoteCsvDelay: remoteCsvDelay,
|
remoteCsvDelay: remoteCsvDelay,
|
||||||
updates: updateChan,
|
updates: updateChan,
|
||||||
err: errChan,
|
err: errChan,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): pass in chan that's closed if/when funding succeeds
|
// TODO(roasbeef): pass in chan that's closed if/when funding succeeds
|
||||||
|
@ -201,12 +201,11 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
|
|||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimator := &lnwallet.StaticFeeEstimator{FeeRate: 50}
|
estimator := &lnwallet.StaticFeeEstimator{FeePerKW: 12500}
|
||||||
feePerVSize, err := estimator.EstimateFeePerVSize(1)
|
feePerKw, err := estimator.EstimateFeePerKW(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
feePerKw := feePerVSize.FeePerKWeight()
|
|
||||||
|
|
||||||
// TODO(roasbeef): need to factor in commit fee?
|
// TODO(roasbeef): need to factor in commit fee?
|
||||||
aliceCommit := channeldb.ChannelCommitment{
|
aliceCommit := channeldb.ChannelCommitment{
|
||||||
|
Loading…
Reference in New Issue
Block a user