mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-28 10:41:57 +01:00
itest: openchannel fee scenarios
This commit is contained in:
parent
2a90b2439a
commit
41822a8baf
@ -92,7 +92,7 @@ type NetworkHarness struct {
|
|||||||
// NewNetworkHarness creates a new network test harness.
|
// NewNetworkHarness creates a new network test harness.
|
||||||
// TODO(roasbeef): add option to use golang's build library to a binary of the
|
// TODO(roasbeef): add option to use golang's build library to a binary of the
|
||||||
// current repo. This will save developers from having to manually `go install`
|
// current repo. This will save developers from having to manually `go install`
|
||||||
// within the repo each time before changes
|
// within the repo each time before changes.
|
||||||
func NewNetworkHarness(m *HarnessMiner, b BackendConfig, lndBinary string,
|
func NewNetworkHarness(m *HarnessMiner, b BackendConfig, lndBinary string,
|
||||||
dbBackend DatabaseBackend) (*NetworkHarness, error) {
|
dbBackend DatabaseBackend) (*NetworkHarness, error) {
|
||||||
|
|
||||||
@ -240,6 +240,7 @@ out:
|
|||||||
|
|
||||||
if aliceResp.ConfirmedBalance == expectedBalance &&
|
if aliceResp.ConfirmedBalance == expectedBalance &&
|
||||||
bobResp.ConfirmedBalance == expectedBalance {
|
bobResp.ConfirmedBalance == expectedBalance {
|
||||||
|
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
case <-balanceTimeout:
|
case <-balanceTimeout:
|
||||||
@ -764,7 +765,7 @@ func (n *NetworkHarness) connectNodes(t *testing.T, a, b *HarnessNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DisconnectNodes disconnects node a from node b by sending RPC message
|
// DisconnectNodes disconnects node a from node b by sending RPC message
|
||||||
// from a node to b node
|
// from a node to b node.
|
||||||
func (n *NetworkHarness) DisconnectNodes(a, b *HarnessNode) error {
|
func (n *NetworkHarness) DisconnectNodes(a, b *HarnessNode) error {
|
||||||
ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout)
|
ctx, cancel := context.WithTimeout(n.runCtx, DefaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -998,6 +999,26 @@ type OpenChannelParams struct {
|
|||||||
// ScidAlias denotes whether the channel will be an option-scid-alias
|
// ScidAlias denotes whether the channel will be an option-scid-alias
|
||||||
// channel type negotiation.
|
// channel type negotiation.
|
||||||
ScidAlias bool
|
ScidAlias bool
|
||||||
|
|
||||||
|
// BaseFee is the channel base fee applied during the channel
|
||||||
|
// announcement phase.
|
||||||
|
BaseFee uint64
|
||||||
|
|
||||||
|
// FeeRate is the channel fee rate in ppm applied during the channel
|
||||||
|
// announcement phase.
|
||||||
|
FeeRate uint64
|
||||||
|
|
||||||
|
// UseBaseFee, if set, instructs the downstream logic to apply the
|
||||||
|
// user-specified channel base fee to the channel update announcement.
|
||||||
|
// If set to false it avoids applying a base fee of 0 and instead
|
||||||
|
// activates the default configured base fee.
|
||||||
|
UseBaseFee bool
|
||||||
|
|
||||||
|
// UseFeeRate, if set, instructs the downstream logic to apply the
|
||||||
|
// user-specified channel fee rate to the channel update announcement.
|
||||||
|
// If set to false it avoids applying a fee rate of 0 and instead
|
||||||
|
// activates the default configured fee rate.
|
||||||
|
UseFeeRate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenChannel attempts to open a channel between srcNode and destNode with the
|
// OpenChannel attempts to open a channel between srcNode and destNode with the
|
||||||
@ -1038,6 +1059,10 @@ func (n *NetworkHarness) OpenChannel(srcNode, destNode *HarnessNode,
|
|||||||
CommitmentType: p.CommitmentType,
|
CommitmentType: p.CommitmentType,
|
||||||
ZeroConf: p.ZeroConf,
|
ZeroConf: p.ZeroConf,
|
||||||
ScidAlias: p.ScidAlias,
|
ScidAlias: p.ScidAlias,
|
||||||
|
BaseFee: p.BaseFee,
|
||||||
|
FeeRate: p.FeeRate,
|
||||||
|
UseBaseFee: p.UseBaseFee,
|
||||||
|
UseFeeRate: p.UseFeeRate,
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to use n.runCtx here to keep the response stream alive after
|
// We need to use n.runCtx here to keep the response stream alive after
|
||||||
@ -1223,6 +1248,7 @@ func (n *NetworkHarness) CloseChannel(lnNode *HarnessNode,
|
|||||||
// not.
|
// not.
|
||||||
filterChannel := func(node *HarnessNode,
|
filterChannel := func(node *HarnessNode,
|
||||||
op wire.OutPoint) (*lnrpc.Channel, error) {
|
op wire.OutPoint) (*lnrpc.Channel, error) {
|
||||||
|
|
||||||
listResp, err := node.ListChannels(ctxt, listReq)
|
listResp, err := node.ListChannels(ctxt, listReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1330,7 +1330,7 @@ func (hn *HarnessNode) lightningNetworkWatcher() {
|
|||||||
|
|
||||||
// WaitForNetworkChannelOpen will block until a channel with the target
|
// WaitForNetworkChannelOpen will block until a channel with the target
|
||||||
// outpoint is seen as being fully advertised within the network. A channel is
|
// outpoint is seen as being fully advertised within the network. A channel is
|
||||||
// considered "fully advertised" once both of its directional edges has been
|
// considered "fully advertised" once both of its directional edges have been
|
||||||
// advertised within the test Lightning Network.
|
// advertised within the test Lightning Network.
|
||||||
func (hn *HarnessNode) WaitForNetworkChannelOpen(
|
func (hn *HarnessNode) WaitForNetworkChannelOpen(
|
||||||
chanPoint *lnrpc.ChannelPoint) error {
|
chanPoint *lnrpc.ChannelPoint) error {
|
||||||
|
@ -30,7 +30,7 @@ func assertPolicyUpdate(t *harnessTest, nodes []*lntest.HarnessNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// testUpdateChannelPolicy tests that policy updates made to a channel
|
// testUpdateChannelPolicy tests that policy updates made to a channel
|
||||||
// gets propagated to other nodes in the network.
|
// get propagated to other nodes in the network.
|
||||||
func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
ctxb := context.Background()
|
ctxb := context.Background()
|
||||||
|
|
||||||
@ -466,7 +466,8 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
t, []*lntest.HarnessNode{net.Alice, net.Bob},
|
t, []*lntest.HarnessNode{net.Alice, net.Bob},
|
||||||
net.Alice.PubKeyStr, expectedPolicy, chanPoint3,
|
net.Alice.PubKeyStr, expectedPolicy, chanPoint3,
|
||||||
)
|
)
|
||||||
// Check that all nodes remembers the policy update
|
|
||||||
|
// Check that all nodes remember the policy update
|
||||||
// they received.
|
// they received.
|
||||||
assertChannelPolicy(
|
assertChannelPolicy(
|
||||||
t, net.Alice, net.Alice.PubKeyStr,
|
t, net.Alice, net.Alice.PubKeyStr,
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/integration/rpctest"
|
"github.com/btcsuite/btcd/integration/rpctest"
|
||||||
|
"github.com/lightningnetwork/lnd/chainreg"
|
||||||
"github.com/lightningnetwork/lnd/funding"
|
"github.com/lightningnetwork/lnd/funding"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lntest"
|
"github.com/lightningnetwork/lnd/lntest"
|
||||||
@ -226,13 +227,15 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
chanGraph, err = net.Alice.DescribeGraph(ctxt, req)
|
chanGraph, err = net.Alice.DescribeGraph(ctxt, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
predErr = fmt.Errorf("unable to query for alice's routing table: %v", err)
|
predErr = fmt.Errorf("unable to query for "+
|
||||||
|
"alice's routing table: %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
numEdges = len(chanGraph.Edges)
|
numEdges = len(chanGraph.Edges)
|
||||||
if numEdges != 0 {
|
if numEdges != 0 {
|
||||||
predErr = fmt.Errorf("expected to find no edge in the graph, found %d",
|
predErr = fmt.Errorf("expected to find "+
|
||||||
|
"no edge in the graph, found %d",
|
||||||
numEdges)
|
numEdges)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -249,10 +252,161 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
closeReorgedChannelAndAssert(t, net, net.Alice, chanPoint, false)
|
closeReorgedChannelAndAssert(t, net, net.Alice, chanPoint, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// testBasicChannelCreationAndUpdates tests multiple channel opening and closing,
|
// testOpenChannelFeePolicy checks if different channel fee scenarios
|
||||||
// and ensures that if a node is subscribed to channel updates they will be
|
// are correctly handled when the optional channel fee parameters
|
||||||
// received correctly for both cooperative and force closed channels.
|
// baseFee and feeRate are provided. If the OpenChannelRequest is not
|
||||||
func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness, t *harnessTest) {
|
// provided with a value for baseFee/feeRate the expectation is that the
|
||||||
|
// default baseFee/feeRate is applied.
|
||||||
|
// 1.) no params provided to OpenChannelRequest
|
||||||
|
// ChannelUpdate --> defaultBaseFee, defaultFeeRate
|
||||||
|
// 2.) only baseFee provided to OpenChannelRequest
|
||||||
|
// ChannelUpdate --> provided baseFee, defaultFeeRate
|
||||||
|
// 3.) only feeRate provided to OpenChannelRequest
|
||||||
|
// ChannelUpdate --> defaultBaseFee, provided FeeRate
|
||||||
|
// 4.) baseFee and feeRate provided to OpenChannelRequest
|
||||||
|
// ChannelUpdate --> provided baseFee, provided feeRate.
|
||||||
|
func testOpenChannelUpdateFeePolicy(net *lntest.NetworkHarness,
|
||||||
|
t *harnessTest) {
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultBaseFee = 1000
|
||||||
|
defaultFeeRate = 1
|
||||||
|
defaultTimeLockDelta = chainreg.DefaultBitcoinTimeLockDelta
|
||||||
|
defaultMinHtlc = 1000
|
||||||
|
optionalBaseFee = 1337
|
||||||
|
optionalFeeRate = 1337
|
||||||
|
)
|
||||||
|
|
||||||
|
defaultMaxHtlc := calculateMaxHtlc(funding.MaxBtcFundingAmount)
|
||||||
|
|
||||||
|
chanAmt := funding.MaxBtcFundingAmount
|
||||||
|
pushAmt := chanAmt / 2
|
||||||
|
|
||||||
|
feeScenarios := []lntest.OpenChannelParams{
|
||||||
|
{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
UseBaseFee: false,
|
||||||
|
UseFeeRate: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
BaseFee: optionalBaseFee,
|
||||||
|
UseBaseFee: true,
|
||||||
|
UseFeeRate: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
FeeRate: optionalFeeRate,
|
||||||
|
UseBaseFee: false,
|
||||||
|
UseFeeRate: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
BaseFee: optionalBaseFee,
|
||||||
|
FeeRate: optionalFeeRate,
|
||||||
|
UseBaseFee: true,
|
||||||
|
UseFeeRate: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedPolicies := []lnrpc.RoutingPolicy{
|
||||||
|
{
|
||||||
|
FeeBaseMsat: defaultBaseFee,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
MaxHtlcMsat: defaultMaxHtlc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
FeeBaseMsat: optionalBaseFee,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
MaxHtlcMsat: defaultMaxHtlc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
FeeBaseMsat: defaultBaseFee,
|
||||||
|
FeeRateMilliMsat: optionalFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
MaxHtlcMsat: defaultMaxHtlc,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
FeeBaseMsat: optionalBaseFee,
|
||||||
|
FeeRateMilliMsat: optionalFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
MaxHtlcMsat: defaultMaxHtlc,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
bobExpectedPolicy := lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: defaultBaseFee,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
MaxHtlcMsat: defaultMaxHtlc,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, feeScenario := range feeScenarios {
|
||||||
|
// Create a channel Alice->Bob.
|
||||||
|
chanPoint := openChannelAndAssert(
|
||||||
|
t, net, net.Alice, net.Bob,
|
||||||
|
feeScenario,
|
||||||
|
)
|
||||||
|
|
||||||
|
defer closeChannelAndAssert(t, net, net.Alice, chanPoint, false)
|
||||||
|
|
||||||
|
// We add all the nodes' update channels to a slice, such that we can
|
||||||
|
// make sure they all receive the expected updates.
|
||||||
|
nodes := []*lntest.HarnessNode{net.Alice, net.Bob}
|
||||||
|
|
||||||
|
// Alice and Bob should see each other's ChannelUpdates, advertising
|
||||||
|
// the preferred routing policies.
|
||||||
|
assertPolicyUpdate(
|
||||||
|
t, nodes, net.Alice.PubKeyStr,
|
||||||
|
&expectedPolicies[i], chanPoint,
|
||||||
|
)
|
||||||
|
assertPolicyUpdate(
|
||||||
|
t, nodes, net.Bob.PubKeyStr,
|
||||||
|
&bobExpectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
|
||||||
|
// They should now know about the default policies.
|
||||||
|
for _, node := range nodes {
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, net.Alice.PubKeyStr,
|
||||||
|
&expectedPolicies[i], chanPoint,
|
||||||
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, net.Bob.PubKeyStr,
|
||||||
|
&bobExpectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(
|
||||||
|
t.t, net.Alice.WaitForNetworkChannelOpen(chanPoint),
|
||||||
|
"alice reports channel opening",
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(
|
||||||
|
t.t, net.Bob.WaitForNetworkChannelOpen(chanPoint),
|
||||||
|
"bob reports channel opening",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testBasicChannelCreationAndUpdates tests multiple channel opening and
|
||||||
|
// closing, and ensures that if a node is subscribed to channel updates
|
||||||
|
// they will be received correctly for both cooperative and force closed
|
||||||
|
// channels.
|
||||||
|
func testBasicChannelCreationAndUpdates(net *lntest.NetworkHarness,
|
||||||
|
t *harnessTest) {
|
||||||
|
|
||||||
runBasicChannelCreationAndUpdates(net, t, net.Alice, net.Bob)
|
runBasicChannelCreationAndUpdates(net, t, net.Alice, net.Bob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,4 +443,8 @@ var allTestCases = []*testCase{
|
|||||||
name: "trackpayments",
|
name: "trackpayments",
|
||||||
test: testTrackPayments,
|
test: testTrackPayments,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "open channel fee policy",
|
||||||
|
test: testOpenChannelUpdateFeePolicy,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user