Merge pull request #1731 from halseth/link-policy-persist
Correctly apply min_htlc to forwarding policy
This commit is contained in:
commit
a1a6845fb5
@ -1617,7 +1617,7 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
// is over.
|
// is over.
|
||||||
// TODO(roasbeef): add abstraction over updates to accommodate
|
// TODO(roasbeef): add abstraction over updates to accommodate
|
||||||
// long-polling, or SSE, etc.
|
// long-polling, or SSE, etc.
|
||||||
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
upd := &lnrpc.OpenStatusUpdate{
|
||||||
Update: &lnrpc.OpenStatusUpdate_ChanPending{
|
Update: &lnrpc.OpenStatusUpdate_ChanPending{
|
||||||
ChanPending: &lnrpc.PendingUpdate{
|
ChanPending: &lnrpc.PendingUpdate{
|
||||||
Txid: fundingPoint.Hash[:],
|
Txid: fundingPoint.Hash[:],
|
||||||
@ -1626,6 +1626,12 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case resCtx.updates <- upd:
|
||||||
|
case <-f.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// At this point we have broadcast the funding transaction and done all
|
// At this point we have broadcast the funding transaction and done all
|
||||||
// necessary processing.
|
// necessary processing.
|
||||||
f.wg.Add(1)
|
f.wg.Add(1)
|
||||||
@ -1693,7 +1699,7 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
// Give the caller a final update notifying them that
|
// Give the caller a final update notifying them that
|
||||||
// the channel is now open.
|
// the channel is now open.
|
||||||
// TODO(roasbeef): only notify after recv of funding locked?
|
// TODO(roasbeef): only notify after recv of funding locked?
|
||||||
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
upd := &lnrpc.OpenStatusUpdate{
|
||||||
Update: &lnrpc.OpenStatusUpdate_ChanOpen{
|
Update: &lnrpc.OpenStatusUpdate_ChanOpen{
|
||||||
ChanOpen: &lnrpc.ChannelOpenUpdate{
|
ChanOpen: &lnrpc.ChannelOpenUpdate{
|
||||||
ChannelPoint: &lnrpc.ChannelPoint{
|
ChannelPoint: &lnrpc.ChannelPoint{
|
||||||
@ -1706,6 +1712,12 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case resCtx.updates <- upd:
|
||||||
|
case <-f.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = f.annAfterSixConfs(completeChan, shortChanID)
|
err = f.annAfterSixConfs(completeChan, shortChanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("failed sending channel announcement: %v",
|
fndgLog.Errorf("failed sending channel announcement: %v",
|
||||||
@ -2060,16 +2072,17 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
|||||||
|
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
|
chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
|
||||||
|
|
||||||
// We'll obtain their min HTLC as we'll use this value within our
|
// We'll obtain the min HTLC value we can forward in our direction, as
|
||||||
// ChannelUpdate. We use this value isn't of ours, as the remote party
|
// we'll use this value within our ChannelUpdate. This constraint is
|
||||||
// will be the one that's carrying the HTLC towards us.
|
// originally set by the remote node, as it will be the one that will
|
||||||
remoteMinHTLC := completeChan.RemoteChanCfg.MinHTLC
|
// need to determine the smallest HTLC it deems economically relevant.
|
||||||
|
fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC
|
||||||
|
|
||||||
ann, err := f.newChanAnnouncement(
|
ann, err := f.newChanAnnouncement(
|
||||||
f.cfg.IDKey, completeChan.IdentityPub,
|
f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
||||||
completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
|
completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
|
||||||
chanID, remoteMinHTLC,
|
chanID, fwdMinHTLC,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error generating channel "+
|
return fmt.Errorf("error generating channel "+
|
||||||
@ -2196,11 +2209,12 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
|
|||||||
fndgLog.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
|
fndgLog.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
|
||||||
&fundingPoint, spew.Sdump(shortChanID))
|
&fundingPoint, spew.Sdump(shortChanID))
|
||||||
|
|
||||||
// We'll obtain their min HTLC as we'll use this value within
|
// We'll obtain the min HTLC value we can forward in our
|
||||||
// our ChannelUpdate. We use this value isn't of ours, as the
|
// direction, as we'll use this value within our ChannelUpdate.
|
||||||
// remote party will be the one that's carrying the HTLC towards
|
// This constraint is originally set by the remote node, as it
|
||||||
// us.
|
// will be the one that will need to determine the smallest
|
||||||
remoteMinHTLC := completeChan.RemoteChanCfg.MinHTLC
|
// HTLC it deems economically relevant.
|
||||||
|
fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC
|
||||||
|
|
||||||
// Create and broadcast the proofs required to make this channel
|
// Create and broadcast the proofs required to make this channel
|
||||||
// public and usable for other nodes for routing.
|
// public and usable for other nodes for routing.
|
||||||
@ -2208,7 +2222,7 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
|
|||||||
f.cfg.IDKey, completeChan.IdentityPub,
|
f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
completeChan.LocalChanCfg.MultiSigKey.PubKey,
|
||||||
completeChan.RemoteChanCfg.MultiSigKey.PubKey,
|
completeChan.RemoteChanCfg.MultiSigKey.PubKey,
|
||||||
*shortChanID, chanID, remoteMinHTLC,
|
*shortChanID, chanID, fwdMinHTLC,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("channel announcement failed: %v", err)
|
return fmt.Errorf("channel announcement failed: %v", err)
|
||||||
@ -2375,10 +2389,10 @@ type chanAnnouncement struct {
|
|||||||
// identity pub keys of both parties to the channel, and the second segment is
|
// identity pub keys of both parties to the channel, and the second segment is
|
||||||
// authenticated only by us and contains our directional routing policy for the
|
// authenticated only by us and contains our directional routing policy for the
|
||||||
// channel.
|
// channel.
|
||||||
func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.PublicKey,
|
func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
|
||||||
localFundingKey, remoteFundingKey *btcec.PublicKey,
|
localFundingKey, remoteFundingKey *btcec.PublicKey,
|
||||||
shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID,
|
shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID,
|
||||||
remoteMinHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
|
fwdMinHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
|
||||||
|
|
||||||
chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
|
chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
|
||||||
|
|
||||||
@ -2432,9 +2446,10 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu
|
|||||||
Flags: chanFlags,
|
Flags: chanFlags,
|
||||||
TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta),
|
TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta),
|
||||||
|
|
||||||
// We use the *remote* party's HtlcMinimumMsat, as they'll be
|
// We use the HtlcMinimumMsat that the remote party required us
|
||||||
// the ones carrying the HTLC routed *towards* us.
|
// to use, as our ChannelUpdate will be used to carry HTLCs
|
||||||
HtlcMinimumMsat: remoteMinHTLC,
|
// towards them.
|
||||||
|
HtlcMinimumMsat: fwdMinHTLC,
|
||||||
|
|
||||||
BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee),
|
BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee),
|
||||||
FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate),
|
FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate),
|
||||||
@ -2513,7 +2528,7 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu
|
|||||||
// finish, either successfully or with an error.
|
// finish, either successfully or with an error.
|
||||||
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
|
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
|
||||||
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
||||||
chanID lnwire.ChannelID, remoteMinHTLC lnwire.MilliSatoshi) error {
|
chanID lnwire.ChannelID, fwdMinHTLC lnwire.MilliSatoshi) error {
|
||||||
|
|
||||||
// First, we'll create the batch of announcements to be sent upon
|
// First, we'll create the batch of announcements to be sent upon
|
||||||
// initial channel creation. This includes the channel announcement
|
// initial channel creation. This includes the channel announcement
|
||||||
@ -2521,7 +2536,7 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
|
|||||||
// proof needed to fully authenticate the channel.
|
// proof needed to fully authenticate the channel.
|
||||||
ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey,
|
ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey,
|
||||||
localFundingKey, remoteFundingKey, shortChanID, chanID,
|
localFundingKey, remoteFundingKey, shortChanID, chanID,
|
||||||
remoteMinHTLC,
|
fwdMinHTLC,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("can't generate channel announcement: %v", err)
|
fndgLog.Errorf("can't generate channel announcement: %v", err)
|
||||||
|
@ -432,6 +432,12 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
|
|||||||
},
|
},
|
||||||
TempChanIDSeed: oldCfg.TempChanIDSeed,
|
TempChanIDSeed: oldCfg.TempChanIDSeed,
|
||||||
FindChannel: oldCfg.FindChannel,
|
FindChannel: oldCfg.FindChannel,
|
||||||
|
DefaultRoutingPolicy: htlcswitch.ForwardingPolicy{
|
||||||
|
MinHTLC: 5,
|
||||||
|
BaseFee: 100,
|
||||||
|
FeeRate: 1000,
|
||||||
|
TimeLockDelta: 10,
|
||||||
|
},
|
||||||
PublishTransaction: func(txn *wire.MsgTx) error {
|
PublishTransaction: func(txn *wire.MsgTx) error {
|
||||||
publishChan <- txn
|
publishChan <- txn
|
||||||
return nil
|
return nil
|
||||||
@ -810,7 +816,16 @@ func assertAddedToRouterGraph(t *testing.T, alice, bob *testNode,
|
|||||||
assertDatabaseState(t, bob, fundingOutPoint, addedToRouterGraph)
|
assertDatabaseState(t, bob, fundingOutPoint, addedToRouterGraph)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertChannelAnnouncements(t *testing.T, alice, bob *testNode) {
|
// assertChannelAnnouncements checks that alice and bob both sends the expected
|
||||||
|
// announcements (ChannelAnnouncement, ChannelUpdate) after the funding tx has
|
||||||
|
// confirmed. The last arguments can be set if we expect the nodes to advertise
|
||||||
|
// custom min_htlc values as part of their ChannelUpdate. We expect Alice to
|
||||||
|
// advertise the value required by Bob and vice versa. If they are not set the
|
||||||
|
// advertised value will be checked againts the other node's default min_htlc
|
||||||
|
// value.
|
||||||
|
func assertChannelAnnouncements(t *testing.T, alice, bob *testNode,
|
||||||
|
customMinHtlc ...lnwire.MilliSatoshi) {
|
||||||
|
|
||||||
// After the FundingLocked message is sent, Alice and Bob will each
|
// After the FundingLocked message is sent, Alice and Bob will each
|
||||||
// send the following messages to their gossiper:
|
// send the following messages to their gossiper:
|
||||||
// 1) ChannelAnnouncement
|
// 1) ChannelAnnouncement
|
||||||
@ -818,7 +833,8 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode) {
|
|||||||
// The ChannelAnnouncement is kept locally, while the ChannelUpdate
|
// The ChannelAnnouncement is kept locally, while the ChannelUpdate
|
||||||
// is sent directly to the other peer, so the edge policies are
|
// is sent directly to the other peer, so the edge policies are
|
||||||
// known to both peers.
|
// known to both peers.
|
||||||
for j, node := range []*testNode{alice, bob} {
|
nodes := []*testNode{alice, bob}
|
||||||
|
for j, node := range nodes {
|
||||||
announcements := make([]lnwire.Message, 2)
|
announcements := make([]lnwire.Message, 2)
|
||||||
for i := 0; i < len(announcements); i++ {
|
for i := 0; i < len(announcements); i++ {
|
||||||
select {
|
select {
|
||||||
@ -831,10 +847,35 @@ func assertChannelAnnouncements(t *testing.T, alice, bob *testNode) {
|
|||||||
gotChannelAnnouncement := false
|
gotChannelAnnouncement := false
|
||||||
gotChannelUpdate := false
|
gotChannelUpdate := false
|
||||||
for _, msg := range announcements {
|
for _, msg := range announcements {
|
||||||
switch msg.(type) {
|
switch m := msg.(type) {
|
||||||
case *lnwire.ChannelAnnouncement:
|
case *lnwire.ChannelAnnouncement:
|
||||||
gotChannelAnnouncement = true
|
gotChannelAnnouncement = true
|
||||||
case *lnwire.ChannelUpdate:
|
case *lnwire.ChannelUpdate:
|
||||||
|
|
||||||
|
// The channel update sent by the node should
|
||||||
|
// advertise the MinHTLC value required by the
|
||||||
|
// _other_ node.
|
||||||
|
other := (j + 1) % 2
|
||||||
|
minHtlc := nodes[other].fundingMgr.cfg.
|
||||||
|
DefaultRoutingPolicy.MinHTLC
|
||||||
|
|
||||||
|
// We might expect a custom MinHTLC value.
|
||||||
|
if len(customMinHtlc) > 0 {
|
||||||
|
if len(customMinHtlc) != 2 {
|
||||||
|
t.Fatalf("only 0 or 2 custom " +
|
||||||
|
"min htlc values " +
|
||||||
|
"currently supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
minHtlc = customMinHtlc[j]
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.HtlcMinimumMsat != minHtlc {
|
||||||
|
t.Fatalf("expected ChannelUpdate to "+
|
||||||
|
"advertise min HTLC %v, had %v",
|
||||||
|
minHtlc, m.HtlcMinimumMsat)
|
||||||
|
}
|
||||||
|
|
||||||
gotChannelUpdate = true
|
gotChannelUpdate = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2209,6 +2250,31 @@ func TestFundingManagerCustomChannelParameters(t *testing.T) {
|
|||||||
case <-time.After(time.Second * 5):
|
case <-time.After(time.Second * 5):
|
||||||
t.Fatalf("alice did not publish funding tx")
|
t.Fatalf("alice did not publish funding tx")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify that transaction was mined.
|
||||||
|
alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{}
|
||||||
|
bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{}
|
||||||
|
|
||||||
|
// After the funding transaction is mined, Alice will send
|
||||||
|
// fundingLocked to Bob.
|
||||||
|
_ = assertFundingMsgSent(
|
||||||
|
t, alice.msgChan, "FundingLocked",
|
||||||
|
).(*lnwire.FundingLocked)
|
||||||
|
|
||||||
|
// And similarly Bob will send funding locked to Alice.
|
||||||
|
_ = assertFundingMsgSent(
|
||||||
|
t, bob.msgChan, "FundingLocked",
|
||||||
|
).(*lnwire.FundingLocked)
|
||||||
|
|
||||||
|
// Make sure both fundingManagers send the expected channel
|
||||||
|
// announcements. Alice should advertise the default MinHTLC value of
|
||||||
|
// 5, while bob should advertise the value minHtlc, since Alice
|
||||||
|
// required him to use it.
|
||||||
|
assertChannelAnnouncements(t, alice, bob, 5, minHtlc)
|
||||||
|
|
||||||
|
// The funding transaction is now confirmed, wait for the
|
||||||
|
// OpenStatusUpdate_ChanOpen update
|
||||||
|
waitForOpenUpdate(t, updateChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestFundingManagerMaxPendingChannels checks that trying to open another
|
// TestFundingManagerMaxPendingChannels checks that trying to open another
|
||||||
|
810
lnd_test.go
810
lnd_test.go
@ -149,11 +149,10 @@ func mineBlocks(t *harnessTest, net *lntest.NetworkHarness, num uint32) []*wire.
|
|||||||
// channel.
|
// channel.
|
||||||
func openChannelAndAssert(ctx context.Context, t *harnessTest,
|
func openChannelAndAssert(ctx context.Context, t *harnessTest,
|
||||||
net *lntest.NetworkHarness, alice, bob *lntest.HarnessNode,
|
net *lntest.NetworkHarness, alice, bob *lntest.HarnessNode,
|
||||||
fundingAmt btcutil.Amount, pushAmt btcutil.Amount,
|
p lntest.OpenChannelParams) *lnrpc.ChannelPoint {
|
||||||
private bool) *lnrpc.ChannelPoint {
|
|
||||||
|
|
||||||
chanOpenUpdate, err := net.OpenChannel(
|
chanOpenUpdate, err := net.OpenChannel(
|
||||||
ctx, alice, bob, fundingAmt, pushAmt, private, true,
|
ctx, alice, bob, p,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to open channel: %v", err)
|
t.Fatalf("unable to open channel: %v", err)
|
||||||
@ -648,7 +647,11 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// successfully.
|
// successfully.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
@ -722,7 +725,12 @@ func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanOpenUpdate, err := net.OpenChannel(
|
chanOpenUpdate, err := net.OpenChannel(
|
||||||
ctxt, carol, net.Alice, chanAmt, pushAmt, false, false,
|
ctxt, carol, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
SpendUnconfirmed: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to open channel between carol and alice: %v",
|
t.Fatalf("unable to open channel between carol and alice: %v",
|
||||||
@ -781,49 +789,73 @@ func txStr(chanPoint *lnrpc.ChannelPoint) string {
|
|||||||
return cp.String()
|
return cp.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForChannelUpdate waits for a node to receive updates from the advertising
|
// expectedChanUpdate houses params we expect a ChannelUpdate to advertise.
|
||||||
// node for the specified channels.
|
type expectedChanUpdate struct {
|
||||||
func waitForChannelUpdate(t *harnessTest, graphUpdates chan *lnrpc.GraphTopologyUpdate,
|
advertisingNode string
|
||||||
advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
|
expectedPolicy *lnrpc.RoutingPolicy
|
||||||
chanPoints ...*lnrpc.ChannelPoint) {
|
chanPoint *lnrpc.ChannelPoint
|
||||||
|
}
|
||||||
|
|
||||||
// Create a set containing all the channel points we are awaiting
|
// waitForChannelUpdate waits for a node to receive the expected channel
|
||||||
// updates for.
|
// updates.
|
||||||
cps := make(map[string]struct{})
|
func waitForChannelUpdate(t *harnessTest,
|
||||||
for _, chanPoint := range chanPoints {
|
graphUpdates chan *lnrpc.GraphTopologyUpdate,
|
||||||
cps[txStr(chanPoint)] = struct{}{}
|
expUpdates []expectedChanUpdate) {
|
||||||
}
|
|
||||||
|
// Create an array indicating which expected channel updates we have
|
||||||
|
// received.
|
||||||
|
found := make([]bool, len(expUpdates))
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case graphUpdate := <-graphUpdates:
|
case graphUpdate := <-graphUpdates:
|
||||||
for _, update := range graphUpdate.ChannelUpdates {
|
for _, update := range graphUpdate.ChannelUpdates {
|
||||||
|
|
||||||
|
// For each expected update, check if it matches
|
||||||
|
// the update we just received.
|
||||||
|
for i, exp := range expUpdates {
|
||||||
fundingTxStr := txStr(update.ChanPoint)
|
fundingTxStr := txStr(update.ChanPoint)
|
||||||
if _, ok := cps[fundingTxStr]; !ok {
|
if fundingTxStr != txStr(exp.chanPoint) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if update.AdvertisingNode != advertisingNode {
|
if update.AdvertisingNode !=
|
||||||
|
exp.advertisingNode {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err := checkChannelPolicy(
|
err := checkChannelPolicy(
|
||||||
update.RoutingPolicy, expectedPolicy,
|
update.RoutingPolicy,
|
||||||
|
exp.expectedPolicy,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// We got a policy update that matched the
|
// We got a policy update that matched
|
||||||
// values and channel point of what we
|
// the values and channel point of what
|
||||||
// expected, delete it from the map.
|
// we expected, mark it as found.
|
||||||
delete(cps, fundingTxStr)
|
found[i] = true
|
||||||
|
|
||||||
// If we have no more channel points we are
|
// If we have no more channel updates
|
||||||
// waiting for, break out of the loop.
|
// we are waiting for, break out of the
|
||||||
if len(cps) == 0 {
|
// loop.
|
||||||
|
rem := 0
|
||||||
|
for _, f := range found {
|
||||||
|
if !f {
|
||||||
|
rem++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rem == 0 {
|
||||||
break out
|
break out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since we found a match among the
|
||||||
|
// expected updates, break out of the
|
||||||
|
// inner loop.
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case <-time.After(20 * time.Second):
|
case <-time.After(20 * time.Second):
|
||||||
t.Fatalf("did not receive channel update")
|
t.Fatalf("did not receive channel update")
|
||||||
@ -889,6 +921,10 @@ func checkChannelPolicy(policy, expectedPolicy *lnrpc.RoutingPolicy) error {
|
|||||||
expectedPolicy.TimeLockDelta,
|
expectedPolicy.TimeLockDelta,
|
||||||
policy.TimeLockDelta)
|
policy.TimeLockDelta)
|
||||||
}
|
}
|
||||||
|
if policy.MinHtlc != expectedPolicy.MinHtlc {
|
||||||
|
return fmt.Errorf("expected min htlc %v, got %v",
|
||||||
|
expectedPolicy.MinHtlc, policy.MinHtlc)
|
||||||
|
}
|
||||||
if policy.Disabled != expectedPolicy.Disabled {
|
if policy.Disabled != expectedPolicy.Disabled {
|
||||||
return errors.New("edge should be disabled but isn't")
|
return errors.New("edge should be disabled but isn't")
|
||||||
}
|
}
|
||||||
@ -902,6 +938,13 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
timeout := time.Duration(time.Second * 15)
|
timeout := time.Duration(time.Second * 15)
|
||||||
ctxb := context.Background()
|
ctxb := context.Background()
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultFeeBase = 1000
|
||||||
|
defaultFeeRate = 1
|
||||||
|
defaultTimeLockDelta = 144
|
||||||
|
defaultMinHtlc = 1000
|
||||||
|
)
|
||||||
|
|
||||||
// Launch notification clients for all nodes, such that we can
|
// Launch notification clients for all nodes, such that we can
|
||||||
// get notified when they discover new channels and updates in the
|
// get notified when they discover new channels and updates in the
|
||||||
// graph.
|
// graph.
|
||||||
@ -911,14 +954,52 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
defer close(bQuit)
|
defer close(bQuit)
|
||||||
|
|
||||||
chanAmt := maxBtcFundingAmount
|
chanAmt := maxBtcFundingAmount
|
||||||
pushAmt := btcutil.Amount(100000)
|
pushAmt := chanAmt / 2
|
||||||
|
|
||||||
// Create a channel Alice->Bob.
|
// Create a channel Alice->Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// We add all the nodes' update channels to a slice, such that we can
|
||||||
|
// make sure they all receive the expected updates.
|
||||||
|
nodeUpdates := []chan *lnrpc.GraphTopologyUpdate{aliceUpdates, bobUpdates}
|
||||||
|
nodes := []*lntest.HarnessNode{net.Alice, net.Bob}
|
||||||
|
|
||||||
|
// Alice and Bob should see each other's ChannelUpdates, advertising the
|
||||||
|
// default routing policies.
|
||||||
|
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: defaultFeeBase,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, updates := range nodeUpdates {
|
||||||
|
waitForChannelUpdate(
|
||||||
|
t, updates,
|
||||||
|
[]expectedChanUpdate{
|
||||||
|
{net.Alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||||
|
{net.Bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// They should now know about the default policies.
|
||||||
|
for _, node := range nodes {
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint)
|
err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -941,15 +1022,71 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
carolUpdates, cQuit := subscribeGraphNotifications(t, ctxb, carol)
|
carolUpdates, cQuit := subscribeGraphNotifications(t, ctxb, carol)
|
||||||
defer close(cQuit)
|
defer close(cQuit)
|
||||||
|
|
||||||
|
nodeUpdates = append(nodeUpdates, carolUpdates)
|
||||||
|
nodes = append(nodes, carol)
|
||||||
|
|
||||||
|
// Send some coins to Carol that can be used for channel funding.
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
|
err = net.SendCoins(ctxt, btcutil.SatoshiPerBitcoin, carol)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send coins to carol: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := net.ConnectNodes(ctxb, carol, net.Bob); err != nil {
|
if err := net.ConnectNodes(ctxb, carol, net.Bob); err != nil {
|
||||||
t.Fatalf("unable to connect dave to alice: %v", err)
|
t.Fatalf("unable to connect dave to alice: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open the channel Carol->Bob with a custom min_htlc value set. Since
|
||||||
|
// Carol is opening the channel, she will require Bob to not forward
|
||||||
|
// HTLCs smaller than this value, and hence he should advertise it as
|
||||||
|
// part of his ChannelUpdate.
|
||||||
|
const customMinHtlc = 5000
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint2 := openChannelAndAssert(
|
chanPoint2 := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, pushAmt, false,
|
ctxt, t, net, carol, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
MinHtlc: customMinHtlc,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expectedPolicyBob := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: defaultFeeBase,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: customMinHtlc,
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedPolicyCarol := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: defaultFeeBase,
|
||||||
|
FeeRateMilliMsat: defaultFeeRate,
|
||||||
|
TimeLockDelta: defaultTimeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, updates := range nodeUpdates {
|
||||||
|
waitForChannelUpdate(
|
||||||
|
t, updates,
|
||||||
|
[]expectedChanUpdate{
|
||||||
|
{net.Bob.PubKeyStr, expectedPolicyBob, chanPoint2},
|
||||||
|
{carol.PubKeyStr, expectedPolicyCarol, chanPoint2},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all nodes now know about the updated policies.
|
||||||
|
for _, node := range nodes {
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, net.Bob.PubKeyStr, expectedPolicyBob,
|
||||||
|
chanPoint2,
|
||||||
|
)
|
||||||
|
assertChannelPolicy(
|
||||||
|
t, node, carol.PubKeyStr, expectedPolicyCarol,
|
||||||
|
chanPoint2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint2)
|
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -966,6 +1103,126 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
t.Fatalf("carol didn't report channel: %v", err)
|
t.Fatalf("carol didn't report channel: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First we'll try to send a payment from Alice to Carol with an amount
|
||||||
|
// less than the min_htlc value required by Carol. This payment should
|
||||||
|
// fail, as the channel Bob->Carol cannot carry HTLCs this small.
|
||||||
|
payAmt := btcutil.Amount(4)
|
||||||
|
invoice := &lnrpc.Invoice{
|
||||||
|
Memo: "testing",
|
||||||
|
Value: int64(payAmt),
|
||||||
|
}
|
||||||
|
resp, err := carol.AddInvoice(ctxb, invoice)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to add invoice: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
err = completePaymentRequests(
|
||||||
|
ctxt, net.Alice, []string{resp.PaymentRequest}, true,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Alice knows about the channel policy of Carol and should therefore
|
||||||
|
// not be able to find a path during routing.
|
||||||
|
if err == nil ||
|
||||||
|
!strings.Contains(err.Error(), "unable to find a path") {
|
||||||
|
t.Fatalf("expected payment to fail, instead got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we try to send a payment over the channel with a value too low
|
||||||
|
// to be accepted. First we query for a route to route a payment of
|
||||||
|
// 5000 mSAT, as this is accepted.
|
||||||
|
payAmt = btcutil.Amount(5)
|
||||||
|
routesReq := &lnrpc.QueryRoutesRequest{
|
||||||
|
PubKey: carol.PubKeyStr,
|
||||||
|
Amt: int64(payAmt),
|
||||||
|
NumRoutes: 1,
|
||||||
|
FinalCltvDelta: 144,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
routes, err := net.Alice.QueryRoutes(ctxt, routesReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to get route: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(routes.Routes) != 1 {
|
||||||
|
t.Fatalf("expected to find 1 route, got %v", len(routes.Routes))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We change the route to carry a payment of 4000 mSAT instead of 5000
|
||||||
|
// mSAT.
|
||||||
|
payAmt = btcutil.Amount(4)
|
||||||
|
amtSat := int64(payAmt)
|
||||||
|
amtMSat := int64(lnwire.NewMSatFromSatoshis(payAmt))
|
||||||
|
routes.Routes[0].Hops[0].AmtToForward = amtSat
|
||||||
|
routes.Routes[0].Hops[0].AmtToForwardMsat = amtMSat
|
||||||
|
routes.Routes[0].Hops[1].AmtToForward = amtSat
|
||||||
|
routes.Routes[0].Hops[1].AmtToForwardMsat = amtMSat
|
||||||
|
|
||||||
|
// Send the payment with the modified value.
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
alicePayStream, err := net.Alice.SendToRoute(ctxt)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create payment stream for alice: %v", err)
|
||||||
|
}
|
||||||
|
sendReq := &lnrpc.SendToRouteRequest{
|
||||||
|
PaymentHash: resp.RHash,
|
||||||
|
Routes: routes.Routes,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = alicePayStream.Send(sendReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect this payment to fail, and that the min_htlc value is
|
||||||
|
// communicated back to us, since the attempted HTLC value was too low.
|
||||||
|
sendResp, err := alicePayStream.Recv()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expected as part of the error message.
|
||||||
|
substrs := []string{
|
||||||
|
"AmountBelowMinimum",
|
||||||
|
"HtlcMinimumMsat: (lnwire.MilliSatoshi) 5000 mSAT",
|
||||||
|
}
|
||||||
|
for _, s := range substrs {
|
||||||
|
if !strings.Contains(sendResp.PaymentError, s) {
|
||||||
|
t.Fatalf("expected error to contain \"%v\", instead "+
|
||||||
|
"got %v", sendResp.PaymentError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure sending using the original value succeeds.
|
||||||
|
payAmt = btcutil.Amount(5)
|
||||||
|
amtSat = int64(payAmt)
|
||||||
|
amtMSat = int64(lnwire.NewMSatFromSatoshis(payAmt))
|
||||||
|
routes.Routes[0].Hops[0].AmtToForward = amtSat
|
||||||
|
routes.Routes[0].Hops[0].AmtToForwardMsat = amtMSat
|
||||||
|
routes.Routes[0].Hops[1].AmtToForward = amtSat
|
||||||
|
routes.Routes[0].Hops[1].AmtToForwardMsat = amtMSat
|
||||||
|
|
||||||
|
sendReq = &lnrpc.SendToRouteRequest{
|
||||||
|
PaymentHash: resp.RHash,
|
||||||
|
Routes: routes.Routes,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = alicePayStream.Send(sendReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sendResp, err = alicePayStream.Recv()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sendResp.PaymentError != "" {
|
||||||
|
t.Fatalf("expected payment to succeed, instead got %v",
|
||||||
|
sendResp.PaymentError)
|
||||||
|
}
|
||||||
|
|
||||||
// With our little cluster set up, we'll update the fees for the
|
// With our little cluster set up, we'll update the fees for the
|
||||||
// channel Bob side of the Alice->Bob channel, and make sure all nodes
|
// channel Bob side of the Alice->Bob channel, and make sure all nodes
|
||||||
// learn about it.
|
// learn about it.
|
||||||
@ -973,10 +1230,11 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
feeRate := int64(12)
|
feeRate := int64(12)
|
||||||
timeLockDelta := uint32(66)
|
timeLockDelta := uint32(66)
|
||||||
|
|
||||||
expectedPolicy := &lnrpc.RoutingPolicy{
|
expectedPolicy = &lnrpc.RoutingPolicy{
|
||||||
FeeBaseMsat: baseFee,
|
FeeBaseMsat: baseFee,
|
||||||
FeeRateMilliMsat: testFeeBase * feeRate,
|
FeeRateMilliMsat: testFeeBase * feeRate,
|
||||||
TimeLockDelta: timeLockDelta,
|
TimeLockDelta: timeLockDelta,
|
||||||
|
MinHtlc: defaultMinHtlc,
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &lnrpc.PolicyUpdateRequest{
|
req := &lnrpc.PolicyUpdateRequest{
|
||||||
@ -993,38 +1251,35 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all nodes to have seen the policy update done by Bob.
|
// Wait for all nodes to have seen the policy update done by Bob.
|
||||||
|
for _, updates := range nodeUpdates {
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, aliceUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
t, updates,
|
||||||
)
|
[]expectedChanUpdate{
|
||||||
waitForChannelUpdate(
|
{net.Bob.PubKeyStr, expectedPolicy, chanPoint},
|
||||||
t, bobUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
},
|
||||||
)
|
|
||||||
waitForChannelUpdate(
|
|
||||||
t, carolUpdates, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Check that all nodes now know about Bob's updated policy.
|
// Check that all nodes now know about Bob's updated policy.
|
||||||
|
for _, node := range nodes {
|
||||||
assertChannelPolicy(
|
assertChannelPolicy(
|
||||||
t, net.Alice, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
t, node, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
||||||
)
|
|
||||||
assertChannelPolicy(
|
|
||||||
t, net.Bob, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
)
|
|
||||||
assertChannelPolicy(
|
|
||||||
t, carol, net.Bob.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Now that all nodes have received the new channel update, we'll try
|
// Now that all nodes have received the new channel update, we'll try
|
||||||
// to send a payment from Alice to Carol to ensure that Alice has
|
// to send a payment from Alice to Carol to ensure that Alice has
|
||||||
// internalized this fee update. This shouldn't affect the route that
|
// internalized this fee update. This shouldn't affect the route that
|
||||||
// Alice takes though: we updated the Alice -> Bob channel and she
|
// Alice takes though: we updated the Alice -> Bob channel and she
|
||||||
// doesn't pay for transit over that channel as it's direct.
|
// doesn't pay for transit over that channel as it's direct.
|
||||||
payAmt := lnwire.MilliSatoshi(2000)
|
// Note that the payment amount is >= the min_htlc value for the
|
||||||
invoice := &lnrpc.Invoice{
|
// channel Bob->Carol, so it should successfully be forwarded.
|
||||||
|
payAmt = btcutil.Amount(5)
|
||||||
|
invoice = &lnrpc.Invoice{
|
||||||
Memo: "testing",
|
Memo: "testing",
|
||||||
Value: int64(payAmt),
|
Value: int64(payAmt),
|
||||||
}
|
}
|
||||||
resp, err := carol.AddInvoice(ctxb, invoice)
|
resp, err = carol.AddInvoice(ctxb, invoice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to add invoice: %v", err)
|
t.Fatalf("unable to add invoice: %v", err)
|
||||||
}
|
}
|
||||||
@ -1043,7 +1298,11 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint3 := openChannelAndAssert(
|
chanPoint3 := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
@ -1081,33 +1340,24 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
// Wait for all nodes to have seen the policy updates for both of
|
// Wait for all nodes to have seen the policy updates for both of
|
||||||
// Alice's channels.
|
// Alice's channels.
|
||||||
|
for _, updates := range nodeUpdates {
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, aliceUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
t, updates,
|
||||||
chanPoint3,
|
[]expectedChanUpdate{
|
||||||
)
|
{net.Alice.PubKeyStr, expectedPolicy, chanPoint},
|
||||||
waitForChannelUpdate(
|
{net.Alice.PubKeyStr, expectedPolicy, chanPoint3},
|
||||||
t, bobUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
},
|
||||||
chanPoint3,
|
|
||||||
)
|
|
||||||
waitForChannelUpdate(
|
|
||||||
t, carolUpdates, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
chanPoint3,
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// And finally check that all nodes remembers the policy update they
|
// And finally check that all nodes remembers the policy update they
|
||||||
// received.
|
// received.
|
||||||
|
for _, node := range nodes {
|
||||||
assertChannelPolicy(
|
assertChannelPolicy(
|
||||||
t, net.Alice, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
t, node, net.Alice.PubKeyStr, expectedPolicy,
|
||||||
chanPoint3,
|
chanPoint, chanPoint3,
|
||||||
)
|
|
||||||
assertChannelPolicy(
|
|
||||||
t, net.Bob, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
chanPoint3,
|
|
||||||
)
|
|
||||||
assertChannelPolicy(
|
|
||||||
t, carol, net.Alice.PubKeyStr, expectedPolicy, chanPoint,
|
|
||||||
chanPoint3,
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Close the channels.
|
// Close the channels.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
@ -1607,7 +1857,10 @@ func testChannelBalance(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctx, t, net, net.Alice, net.Bob, amount, 0, false,
|
ctx, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: amount,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wait for both Alice and Bob to recognize this new channel.
|
// Wait for both Alice and Bob to recognize this new channel.
|
||||||
@ -1809,7 +2062,11 @@ func testChannelForceClosure(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wait for Alice and Carol to receive the channel edge from the
|
// Wait for Alice and Carol to receive the channel edge from the
|
||||||
@ -2525,7 +2782,10 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assertAmountSent := func(amt btcutil.Amount) {
|
assertAmountSent := func(amt btcutil.Amount) {
|
||||||
@ -2663,7 +2923,10 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanAmt := btcutil.Amount(100000)
|
chanAmt := btcutil.Amount(100000)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
assertAmountSent := func(amt btcutil.Amount) {
|
assertAmountSent := func(amt btcutil.Amount) {
|
||||||
@ -2819,7 +3082,10 @@ func testListPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
chanAmt := btcutil.Amount(100000)
|
chanAmt := btcutil.Amount(100000)
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now that the channel is open, create an invoice for Bob which
|
// Now that the channel is open, create an invoice for Bob which
|
||||||
@ -3005,6 +3271,7 @@ func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
|||||||
FeeBaseMsat: baseFee,
|
FeeBaseMsat: baseFee,
|
||||||
FeeRateMilliMsat: feeRate,
|
FeeRateMilliMsat: feeRate,
|
||||||
TimeLockDelta: timeLockDelta,
|
TimeLockDelta: timeLockDelta,
|
||||||
|
MinHtlc: 1000, // default value
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
||||||
@ -3028,8 +3295,10 @@ func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
|
|||||||
defer close(aQuit)
|
defer close(aQuit)
|
||||||
|
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, listenerUpdates, node.PubKeyStr, expectedPolicy,
|
t, listenerUpdates,
|
||||||
chanPoint,
|
[]expectedChanUpdate{
|
||||||
|
{node.PubKeyStr, expectedPolicy, chanPoint},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3043,7 +3312,10 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -3082,7 +3354,10 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, 0, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
@ -3115,7 +3390,10 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -3324,8 +3602,12 @@ func testSingleHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(ctxt, t, net, net.Alice,
|
chanPointAlice := openChannelAndAssert(
|
||||||
net.Bob, chanAmt, 0, false)
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
txidHash, err := getChanPointFundingTxid(chanPointAlice)
|
txidHash, err := getChanPointFundingTxid(chanPointAlice)
|
||||||
@ -3471,8 +3753,12 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(ctxt, t, net, net.Alice,
|
chanPointAlice := openChannelAndAssert(
|
||||||
net.Bob, chanAmt, 0, false)
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
txidHash, err := getChanPointFundingTxid(chanPointAlice)
|
txidHash, err := getChanPointFundingTxid(chanPointAlice)
|
||||||
@ -3505,8 +3791,12 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
t.Fatalf("unable to send coins to bob: %v", err)
|
t.Fatalf("unable to send coins to bob: %v", err)
|
||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointBob := openChannelAndAssert(ctxt, t, net, net.Bob,
|
chanPointBob := openChannelAndAssert(
|
||||||
carol, chanAmt, 0, false)
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
|
)
|
||||||
networkChans = append(networkChans, chanPointBob)
|
networkChans = append(networkChans, chanPointBob)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointBob)
|
txidHash, err = getChanPointFundingTxid(chanPointBob)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3659,8 +3949,12 @@ func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(ctxt, t, net, net.Alice,
|
chanPointAlice := openChannelAndAssert(
|
||||||
net.Bob, chanAmt, 0, false)
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
|
)
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointAlice)
|
err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointAlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3701,8 +3995,12 @@ func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(ctxt, t, net, carol,
|
chanPointCarol := openChannelAndAssert(
|
||||||
charlie, chanAmt, 0, false)
|
ctxt, t, net, carol, charlie,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
|
)
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
err = carol.WaitForNetworkChannelOpen(ctxt, chanPointCarol)
|
err = carol.WaitForNetworkChannelOpen(ctxt, chanPointCarol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -3790,7 +4088,10 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Open a channel with 200k satoshis between Alice and Bob.
|
// Open a channel with 200k satoshis between Alice and Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt*2, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt * 2,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -3823,7 +4124,10 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, 0, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
@ -3856,7 +4160,10 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -3907,7 +4214,11 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
t.Fatalf("unable to connect dave to alice: %v", err)
|
t.Fatalf("unable to connect dave to alice: %v", err)
|
||||||
}
|
}
|
||||||
chanOpenUpdate, err := net.OpenChannel(
|
chanOpenUpdate, err := net.OpenChannel(
|
||||||
ctxb, carol, net.Alice, chanAmt, 0, true, true,
|
ctxb, carol, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to open channel: %v", err)
|
t.Fatalf("unable to open channel: %v", err)
|
||||||
@ -4134,7 +4445,12 @@ func testInvoiceRoutingHints(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// payment.
|
// payment.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointBob := openChannelAndAssert(
|
chanPointBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, chanAmt/2, true,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: chanAmt / 2,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Then, we'll create Carol's node and open a public channel between her
|
// Then, we'll create Carol's node and open a public channel between her
|
||||||
@ -4151,7 +4467,11 @@ func testInvoiceRoutingHints(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, chanAmt/2, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: chanAmt / 2,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Then, we'll create Dave's node and open a private channel between him
|
// Then, we'll create Dave's node and open a private channel between him
|
||||||
@ -4169,7 +4489,11 @@ func testInvoiceRoutingHints(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, dave, chanAmt, 0, true,
|
ctxt, t, net, net.Alice, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Finally, we'll create Eve's node and open a private channel between
|
// Finally, we'll create Eve's node and open a private channel between
|
||||||
@ -4185,7 +4509,12 @@ func testInvoiceRoutingHints(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointEve := openChannelAndAssert(
|
chanPointEve := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, eve, chanAmt, chanAmt/2, true,
|
ctxt, t, net, net.Alice, eve,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: chanAmt / 2,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make sure all the channels have been opened.
|
// Make sure all the channels have been opened.
|
||||||
@ -4307,7 +4636,11 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
// being the funder.
|
// being the funder.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, true,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
@ -4350,7 +4683,10 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointBob := openChannelAndAssert(
|
chanPointBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
@ -4403,7 +4739,11 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, true,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
Private: true,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
@ -4514,7 +4854,10 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Next create a new invoice for Bob requesting 1k satoshis.
|
// Next create a new invoice for Bob requesting 1k satoshis.
|
||||||
@ -4752,7 +5095,10 @@ func testBasicChannelCreation(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
for i := 0; i < numChannels; i++ {
|
for i := 0; i < numChannels; i++ {
|
||||||
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
||||||
chanPoints[i] = openChannelAndAssert(
|
chanPoints[i] = openChannelAndAssert(
|
||||||
ctx, t, net, net.Alice, net.Bob, amount, 0, false,
|
ctx, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: amount,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4803,7 +5149,10 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
for i := 0; i < maxPendingChannels; i++ {
|
for i := 0; i < maxPendingChannels; i++ {
|
||||||
ctx, _ = context.WithTimeout(context.Background(), timeout)
|
ctx, _ = context.WithTimeout(context.Background(), timeout)
|
||||||
stream, err := net.OpenChannel(
|
stream, err := net.OpenChannel(
|
||||||
ctx, net.Alice, carol, amount, 0, false, true,
|
ctx, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: amount,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to open channel: %v", err)
|
t.Fatalf("unable to open channel: %v", err)
|
||||||
@ -4815,8 +5164,12 @@ func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// channel request should cause ErrorGeneric to be sent back to Alice.
|
// channel request should cause ErrorGeneric to be sent back to Alice.
|
||||||
ctx, _ = context.WithTimeout(context.Background(), timeout)
|
ctx, _ = context.WithTimeout(context.Background(), timeout)
|
||||||
_, err = net.OpenChannel(
|
_, err = net.OpenChannel(
|
||||||
ctx, net.Alice, carol, amount, 0, false, true,
|
ctx, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: amount,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("error wasn't received")
|
t.Fatalf("error wasn't received")
|
||||||
} else if grpc.Code(err) != lnwire.ErrMaxPendingChannels.ToGrpcCode() {
|
} else if grpc.Code(err) != lnwire.ErrMaxPendingChannels.ToGrpcCode() {
|
||||||
@ -4973,7 +5326,10 @@ func testFailingChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the channel open, we'll create a invoice for Carol that Alice
|
// With the channel open, we'll create a invoice for Carol that Alice
|
||||||
@ -5146,7 +5502,10 @@ func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxb := context.Background()
|
ctxb := context.Background()
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
coopChanPoint := openChannelAndAssert(
|
coopChanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create Carol's node and connect Alice to her.
|
// Create Carol's node and connect Alice to her.
|
||||||
@ -5164,7 +5523,10 @@ func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// closed.
|
// closed.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
forceCloseChanPoint := openChannelAndAssert(
|
forceCloseChanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now, create Dave's a node and also open a channel between Alice and
|
// Now, create Dave's a node and also open a channel between Alice and
|
||||||
@ -5180,7 +5542,10 @@ func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
persistentChanPoint := openChannelAndAssert(
|
persistentChanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, dave, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// isConnected is a helper closure that checks if a peer is connected to
|
// isConnected is a helper closure that checks if a peer is connected to
|
||||||
@ -5360,7 +5725,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// 0.5 BTC value.
|
// 0.5 BTC value.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, carol, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the channel open, we'll create a few invoices for Bob that
|
// With the channel open, we'll create a few invoices for Bob that
|
||||||
@ -5639,7 +6007,10 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness
|
|||||||
// 0.5 BTC value.
|
// 0.5 BTC value.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, carol, chanAmt, 0, false,
|
ctxt, t, net, dave, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the channel open, we'll create a few invoices for Carol that
|
// With the channel open, we'll create a few invoices for Carol that
|
||||||
@ -5904,7 +6275,11 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
|
|||||||
// maxBtcFundingAmount (2^24) satoshis value.
|
// maxBtcFundingAmount (2^24) satoshis value.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, carol, chanAmt, pushAmt, false,
|
ctxt, t, net, dave, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the channel open, we'll create a few invoices for Carol that
|
// With the channel open, we'll create a few invoices for Carol that
|
||||||
@ -6361,7 +6736,10 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// We'll first open up a channel between them with a 0.5 BTC value.
|
// We'll first open up a channel between them with a 0.5 BTC value.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// We a´make a note of the nodes' current on-chain balances, to make
|
// We a´make a note of the nodes' current on-chain balances, to make
|
||||||
@ -6650,7 +7028,10 @@ func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// and Bob.
|
// and Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
if err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointAlice); err != nil {
|
if err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPointAlice); err != nil {
|
||||||
@ -6695,7 +7076,10 @@ func testHtlcErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
const bobChanAmt = maxBtcFundingAmount
|
const bobChanAmt = maxBtcFundingAmount
|
||||||
chanPointBob := openChannelAndAssert(
|
chanPointBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that Alice has Carol in her routing table before proceeding.
|
// Ensure that Alice has Carol in her routing table before proceeding.
|
||||||
@ -6992,7 +7376,10 @@ func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
// Open a new channel between Alice and Bob.
|
// Open a new channel between Alice and Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// The channel opening above should have triggered a few notifications
|
// The channel opening above should have triggered a few notifications
|
||||||
@ -7117,7 +7504,10 @@ out:
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint = openChannelAndAssert(
|
chanPoint = openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reconnect Alice and Bob. This should result in the nodes syncing up
|
// Reconnect Alice and Bob. This should result in the nodes syncing up
|
||||||
@ -7213,7 +7603,10 @@ func testNodeAnnouncement(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
timeout := time.Duration(time.Second * 5)
|
timeout := time.Duration(time.Second * 5)
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, dave, 1000000, 0, false,
|
ctxt, t, net, net.Bob, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: 1000000,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// When Alice now connects with Dave, Alice will get his node
|
// When Alice now connects with Dave, Alice will get his node
|
||||||
@ -7274,7 +7667,11 @@ func testNodeSignVerify(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Create a channel between alice and bob.
|
// Create a channel between alice and bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
aliceBobCh := openChannelAndAssert(
|
aliceBobCh := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
aliceMsg := []byte("alice msg")
|
aliceMsg := []byte("alice msg")
|
||||||
@ -7370,7 +7767,10 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
channelCapacity := btcutil.Amount(paymentAmt * 2000)
|
channelCapacity := btcutil.Amount(paymentAmt * 2000)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, channelCapacity, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: channelCapacity,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
info, err := getChanInfo(net.Alice)
|
info, err := getChanInfo(net.Alice)
|
||||||
@ -7553,8 +7953,11 @@ func testBidirectionalAsyncPayments(net *lntest.NetworkHarness, t *harnessTest)
|
|||||||
// Alice should send all money from her side to Bob.
|
// Alice should send all money from her side to Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, paymentAmt*2000,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
paymentAmt*1000, false,
|
lntest.OpenChannelParams{
|
||||||
|
Amt: paymentAmt * 2000,
|
||||||
|
PushAmt: paymentAmt * 1000,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
info, err := getChanInfo(net.Alice)
|
info, err := getChanInfo(net.Alice)
|
||||||
@ -7896,7 +8299,10 @@ func createThreeHopHodlNetwork(t *harnessTest,
|
|||||||
timeout := time.Duration(time.Second * 15)
|
timeout := time.Duration(time.Second * 15)
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
aliceChanPoint := openChannelAndAssert(
|
aliceChanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
@ -7926,7 +8332,10 @@ func createThreeHopHodlNetwork(t *harnessTest,
|
|||||||
// open, our topology looks like: A -> B -> C.
|
// open, our topology looks like: A -> B -> C.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
bobChanPoint := openChannelAndAssert(
|
bobChanPoint := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
ctxt, _ = context.WithTimeout(ctxb, time.Second*15)
|
||||||
err = net.Bob.WaitForNetworkChannelOpen(ctxt, bobChanPoint)
|
err = net.Bob.WaitForNetworkChannelOpen(ctxt, bobChanPoint)
|
||||||
@ -9463,7 +9872,11 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -9502,7 +9915,11 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, pushAmt, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
@ -9536,7 +9953,11 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, pushAmt, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -9793,7 +10214,11 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -9832,7 +10257,11 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, pushAmt, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
@ -9866,7 +10295,11 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, pushAmt, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -10130,7 +10563,11 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -10169,8 +10606,13 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, pushAmt, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -10203,7 +10645,11 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, pushAmt, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -10474,7 +10920,11 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
|||||||
// being the sole funder of the channel.
|
// being the sole funder of the channel.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, pushAmt, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -10513,7 +10963,11 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointDave := openChannelAndAssert(
|
chanPointDave := openChannelAndAssert(
|
||||||
ctxt, t, net, dave, net.Alice, chanAmt, pushAmt, false,
|
ctxt, t, net, dave, net.Alice,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointDave)
|
networkChans = append(networkChans, chanPointDave)
|
||||||
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
txidHash, err = getChanPointFundingTxid(chanPointDave)
|
||||||
@ -10545,7 +10999,11 @@ func testSwitchOfflineDeliveryOutgoingOffline(
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, pushAmt, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
PushAmt: pushAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -10764,7 +11222,10 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Open a channel between Alice and Bob.
|
// Open a channel between Alice and Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAlice := openChannelAndAssert(
|
chanPointAlice := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointAlice)
|
networkChans = append(networkChans, chanPointAlice)
|
||||||
|
|
||||||
@ -10784,7 +11245,10 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointBob := openChannelAndAssert(
|
chanPointBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointBob)
|
networkChans = append(networkChans, chanPointBob)
|
||||||
|
|
||||||
@ -10804,7 +11268,10 @@ func testQueryRoutes(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarol := openChannelAndAssert(
|
chanPointCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
networkChans = append(networkChans, chanPointCarol)
|
networkChans = append(networkChans, chanPointCarol)
|
||||||
|
|
||||||
@ -10958,7 +11425,10 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// Open a channel between Alice and Bob.
|
// Open a channel between Alice and Bob.
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAliceBob := openChannelAndAssert(
|
chanPointAliceBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create Carol's node and open a channel between her and Alice with
|
// Create Carol's node and open a channel between her and Alice with
|
||||||
@ -10980,7 +11450,10 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAliceCarol := openChannelAndAssert(
|
chanPointAliceCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create Dave's node and open a channel between him and Bob with Bob
|
// Create Dave's node and open a channel between him and Bob with Bob
|
||||||
@ -10997,7 +11470,10 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointBobDave := openChannelAndAssert(
|
chanPointBobDave := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Bob, dave, chanAmt, 0, false,
|
ctxt, t, net, net.Bob, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Open a channel between Carol and Dave.
|
// Open a channel between Carol and Dave.
|
||||||
@ -11007,7 +11483,10 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointCarolDave := openChannelAndAssert(
|
chanPointCarolDave := openChannelAndAssert(
|
||||||
ctxt, t, net, carol, dave, chanAmt, 0, false,
|
ctxt, t, net, carol, dave,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now that all the channels were set up, we'll wait for all the nodes
|
// Now that all the channels were set up, we'll wait for all the nodes
|
||||||
@ -11056,6 +11535,7 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
FeeBaseMsat: baseFee,
|
FeeBaseMsat: baseFee,
|
||||||
FeeRateMilliMsat: testFeeBase * feeRate,
|
FeeRateMilliMsat: testFeeBase * feeRate,
|
||||||
TimeLockDelta: timeLockDelta,
|
TimeLockDelta: timeLockDelta,
|
||||||
|
MinHtlc: 1000, // default value
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
||||||
@ -11075,9 +11555,12 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
aliceUpdates, aQuit := subscribeGraphNotifications(t, ctxt, net.Alice)
|
aliceUpdates, aQuit := subscribeGraphNotifications(t, ctxt, net.Alice)
|
||||||
defer close(aQuit)
|
defer close(aQuit)
|
||||||
|
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, aliceUpdates, carol.PubKeyStr, expectedPolicy,
|
t, aliceUpdates,
|
||||||
chanPointCarolDave,
|
[]expectedChanUpdate{
|
||||||
|
{carol.PubKeyStr, expectedPolicy, chanPointCarolDave},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// We'll also need the channel IDs for Bob's channels in order to
|
// We'll also need the channel IDs for Bob's channels in order to
|
||||||
@ -11218,7 +11701,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
ctxb := context.Background()
|
ctxb := context.Background()
|
||||||
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAliceBob := openChannelAndAssert(
|
chanPointAliceBob := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, net.Bob,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
carol, err := net.NewNode("Carol", nil)
|
carol, err := net.NewNode("Carol", nil)
|
||||||
@ -11232,7 +11718,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointAliceCarol := openChannelAndAssert(
|
chanPointAliceCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, net.Alice, carol, chanAmt, 0, false,
|
ctxt, t, net, net.Alice, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// We create a new node Eve that has an inactive channel timeout of
|
// We create a new node Eve that has an inactive channel timeout of
|
||||||
@ -11260,7 +11749,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
chanPointEveCarol := openChannelAndAssert(
|
chanPointEveCarol := openChannelAndAssert(
|
||||||
ctxt, t, net, eve, carol, chanAmt, 0, false,
|
ctxt, t, net, eve, carol,
|
||||||
|
lntest.OpenChannelParams{
|
||||||
|
Amt: chanAmt,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Launch a node for Dave which will connect to Bob in order to receive
|
// Launch a node for Dave which will connect to Bob in order to receive
|
||||||
@ -11284,6 +11776,7 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
FeeBaseMsat: int64(defaultBitcoinBaseFeeMSat),
|
FeeBaseMsat: int64(defaultBitcoinBaseFeeMSat),
|
||||||
FeeRateMilliMsat: int64(defaultBitcoinFeeRate),
|
FeeRateMilliMsat: int64(defaultBitcoinFeeRate),
|
||||||
TimeLockDelta: defaultBitcoinTimeLockDelta,
|
TimeLockDelta: defaultBitcoinTimeLockDelta,
|
||||||
|
MinHtlc: 1000, // default value
|
||||||
Disabled: true,
|
Disabled: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11294,8 +11787,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
t.Fatalf("unable to suspend carol: %v", err)
|
t.Fatalf("unable to suspend carol: %v", err)
|
||||||
}
|
}
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, daveUpdates, eve.PubKeyStr, expectedPolicy,
|
t, daveUpdates,
|
||||||
chanPointEveCarol,
|
[]expectedChanUpdate{
|
||||||
|
{eve.PubKeyStr, expectedPolicy, chanPointEveCarol},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// We restart Carol. Since the channel now becomes active again, Eve
|
// We restart Carol. Since the channel now becomes active again, Eve
|
||||||
@ -11306,8 +11801,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
expectedPolicy.Disabled = false
|
expectedPolicy.Disabled = false
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, daveUpdates, eve.PubKeyStr, expectedPolicy,
|
t, daveUpdates,
|
||||||
chanPointEveCarol,
|
[]expectedChanUpdate{
|
||||||
|
{eve.PubKeyStr, expectedPolicy, chanPointEveCarol},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Close Alice's channels with Bob and Carol cooperatively and
|
// Close Alice's channels with Bob and Carol cooperatively and
|
||||||
@ -11328,8 +11825,11 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
// receive an update marking each as disabled.
|
// receive an update marking each as disabled.
|
||||||
expectedPolicy.Disabled = true
|
expectedPolicy.Disabled = true
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, daveUpdates, net.Alice.PubKeyStr, expectedPolicy,
|
t, daveUpdates,
|
||||||
chanPointAliceBob, chanPointAliceCarol,
|
[]expectedChanUpdate{
|
||||||
|
{net.Alice.PubKeyStr, expectedPolicy, chanPointAliceBob},
|
||||||
|
{net.Alice.PubKeyStr, expectedPolicy, chanPointAliceCarol},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Finally, close the channels by mining the closing transactions.
|
// Finally, close the channels by mining the closing transactions.
|
||||||
@ -11347,8 +11847,10 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
waitForChannelUpdate(
|
waitForChannelUpdate(
|
||||||
t, daveUpdates, eve.PubKeyStr, expectedPolicy,
|
t, daveUpdates,
|
||||||
chanPointEveCarol,
|
[]expectedChanUpdate{
|
||||||
|
{eve.PubKeyStr, expectedPolicy, chanPointEveCarol},
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err = waitForNTxsInMempool(net.Miner.Node, 1, timeout)
|
_, err = waitForNTxsInMempool(net.Miner.Node, 1, timeout)
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/btcsuite/btcutil"
|
"github.com/btcsuite/btcutil"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NetworkHarness is an integration testing harness for the lightning network.
|
// NetworkHarness is an integration testing harness for the lightning network.
|
||||||
@ -687,15 +688,35 @@ func (n *NetworkHarness) WaitForTxBroadcast(ctx context.Context, txid chainhash.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpenChannelParams houses the params to specify when opening a new channel.
|
||||||
|
type OpenChannelParams struct {
|
||||||
|
// Amt is the local amount being put into the channel.
|
||||||
|
Amt btcutil.Amount
|
||||||
|
|
||||||
|
// PushAmt is the amount that should be pushed to the remote when the
|
||||||
|
// channel is opened.
|
||||||
|
PushAmt btcutil.Amount
|
||||||
|
|
||||||
|
// Private is a boolan indicating whether the opened channel should be
|
||||||
|
// private.
|
||||||
|
Private bool
|
||||||
|
|
||||||
|
// SpendUnconfirmed is a boolean indicating whether we can utilize
|
||||||
|
// unconfirmed outputs to fund the channel.
|
||||||
|
SpendUnconfirmed bool
|
||||||
|
|
||||||
|
// MinHtlc is the htlc_minumum_msat value set when opening the channel.
|
||||||
|
MinHtlc lnwire.MilliSatoshi
|
||||||
|
}
|
||||||
|
|
||||||
// OpenChannel attempts to open a channel between srcNode and destNode with the
|
// OpenChannel attempts to open a channel between srcNode and destNode with the
|
||||||
// passed channel funding parameters. If the passed context has a timeout, then
|
// passed channel funding parameters. If the passed context has a timeout, then
|
||||||
// if the timeout is reached before the channel pending notification is
|
// if the timeout is reached before the channel pending notification is
|
||||||
// received, an error is returned. The confirmed boolean determines whether we
|
// received, an error is returned. The confirmed boolean determines whether we
|
||||||
// should fund the channel with confirmed outputs or not.
|
// should fund the channel with confirmed outputs or not.
|
||||||
func (n *NetworkHarness) OpenChannel(ctx context.Context,
|
func (n *NetworkHarness) OpenChannel(ctx context.Context,
|
||||||
srcNode, destNode *HarnessNode, amt btcutil.Amount,
|
srcNode, destNode *HarnessNode, p OpenChannelParams) (
|
||||||
pushAmt btcutil.Amount,
|
lnrpc.Lightning_OpenChannelClient, error) {
|
||||||
private, confirmed bool) (lnrpc.Lightning_OpenChannelClient, error) {
|
|
||||||
|
|
||||||
// Wait until srcNode and destNode have the latest chain synced.
|
// Wait until srcNode and destNode have the latest chain synced.
|
||||||
// Otherwise, we may run into a check within the funding manager that
|
// Otherwise, we may run into a check within the funding manager that
|
||||||
@ -708,17 +729,18 @@ func (n *NetworkHarness) OpenChannel(ctx context.Context,
|
|||||||
return nil, fmt.Errorf("Unable to sync destNode chain: %v", err)
|
return nil, fmt.Errorf("Unable to sync destNode chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
minConfs := int32(0)
|
minConfs := int32(1)
|
||||||
if confirmed {
|
if p.SpendUnconfirmed {
|
||||||
minConfs = 1
|
minConfs = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
openReq := &lnrpc.OpenChannelRequest{
|
openReq := &lnrpc.OpenChannelRequest{
|
||||||
NodePubkey: destNode.PubKey[:],
|
NodePubkey: destNode.PubKey[:],
|
||||||
LocalFundingAmount: int64(amt),
|
LocalFundingAmount: int64(p.Amt),
|
||||||
PushSat: int64(pushAmt),
|
PushSat: int64(p.PushAmt),
|
||||||
Private: private,
|
Private: p.Private,
|
||||||
MinConfs: minConfs,
|
MinConfs: minConfs,
|
||||||
|
MinHtlcMsat: int64(p.MinHtlc),
|
||||||
}
|
}
|
||||||
|
|
||||||
respStream, err := srcNode.OpenChannel(ctx, openReq)
|
respStream, err := srcNode.OpenChannel(ctx, openReq)
|
||||||
|
@ -6254,3 +6254,9 @@ func (lc *LightningChannel) RemoteCommitHeight() uint64 {
|
|||||||
|
|
||||||
return lc.channelState.RemoteCommitment.CommitHeight
|
return lc.channelState.RemoteCommitment.CommitHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FwdMinHtlc returns the minimum HTLC value required by the remote node, i.e.
|
||||||
|
// the minimum value HTLC we can forward on this channel.
|
||||||
|
func (lc *LightningChannel) FwdMinHtlc() lnwire.MilliSatoshi {
|
||||||
|
return lc.localChanCfg.MinHTLC
|
||||||
|
}
|
||||||
|
56
peer.go
56
peer.go
@ -396,10 +396,14 @@ func (p *peer) loadActiveChannels(chans []*channeldb.OpenChannel) error {
|
|||||||
TimeLockDelta: uint32(selfPolicy.TimeLockDelta),
|
TimeLockDelta: uint32(selfPolicy.TimeLockDelta),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
peerLog.Warnf("Unable to find our forwarding policy "+
|
||||||
|
"for channel %v, using default values",
|
||||||
|
chanPoint)
|
||||||
forwardingPolicy = &p.server.cc.routingPolicy
|
forwardingPolicy = &p.server.cc.routingPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
peerLog.Tracef("Using link policy of: %v", spew.Sdump(forwardingPolicy))
|
peerLog.Tracef("Using link policy of: %v",
|
||||||
|
spew.Sdump(forwardingPolicy))
|
||||||
|
|
||||||
// Register this new channel link with the HTLC Switch. This is
|
// Register this new channel link with the HTLC Switch. This is
|
||||||
// necessary to properly route multi-hop payments, and forward
|
// necessary to properly route multi-hop payments, and forward
|
||||||
@ -542,9 +546,7 @@ func (p *peer) addLink(chanPoint *wire.OutPoint,
|
|||||||
Peer: p,
|
Peer: p,
|
||||||
DecodeHopIterators: p.server.sphinx.DecodeHopIterators,
|
DecodeHopIterators: p.server.sphinx.DecodeHopIterators,
|
||||||
ExtractErrorEncrypter: p.server.sphinx.ExtractErrorEncrypter,
|
ExtractErrorEncrypter: p.server.sphinx.ExtractErrorEncrypter,
|
||||||
FetchLastChannelUpdate: fetchLastChanUpdate(
|
FetchLastChannelUpdate: p.server.fetchLastChanUpdate(),
|
||||||
p.server, p.PubKey(),
|
|
||||||
),
|
|
||||||
DebugHTLC: cfg.DebugHTLC,
|
DebugHTLC: cfg.DebugHTLC,
|
||||||
HodlMask: cfg.Hodl.Mask(),
|
HodlMask: cfg.Hodl.Mask(),
|
||||||
Registry: p.server.invoices,
|
Registry: p.server.invoices,
|
||||||
@ -1550,9 +1552,23 @@ out:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll query the localChanCfg of the new channel to
|
||||||
|
// determine the minimum HTLC value that can be
|
||||||
|
// forwarded. For fees we'll use the default values, as
|
||||||
|
// they currently are always set to the default values
|
||||||
|
// at initial channel creation.
|
||||||
|
fwdMinHtlc := newChan.FwdMinHtlc()
|
||||||
|
defaultPolicy := p.server.cc.routingPolicy
|
||||||
|
forwardingPolicy := &htlcswitch.ForwardingPolicy{
|
||||||
|
MinHTLC: fwdMinHtlc,
|
||||||
|
BaseFee: defaultPolicy.BaseFee,
|
||||||
|
FeeRate: defaultPolicy.FeeRate,
|
||||||
|
TimeLockDelta: defaultPolicy.TimeLockDelta,
|
||||||
|
}
|
||||||
|
|
||||||
// Create the link and add it to the switch.
|
// Create the link and add it to the switch.
|
||||||
err = p.addLink(
|
err = p.addLink(
|
||||||
chanPoint, newChan, &p.server.cc.routingPolicy,
|
chanPoint, newChan, forwardingPolicy,
|
||||||
chainEvents, currentHeight, false,
|
chainEvents, currentHeight, false,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2098,33 +2114,3 @@ func (p *peer) StartTime() time.Time {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): make all start/stop mutexes a CAS
|
// TODO(roasbeef): make all start/stop mutexes a CAS
|
||||||
|
|
||||||
// fetchLastChanUpdate returns a function which is able to retrieve the last
|
|
||||||
// channel update for a target channel.
|
|
||||||
func fetchLastChanUpdate(s *server,
|
|
||||||
pubKey [33]byte) func(lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) {
|
|
||||||
|
|
||||||
return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) {
|
|
||||||
info, edge1, edge2, err := s.chanRouter.GetChannelByID(cid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if edge1 == nil || edge2 == nil {
|
|
||||||
return nil, fmt.Errorf("unable to find channel by "+
|
|
||||||
"ShortChannelID(%v)", cid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're the outgoing node on the first edge, then that
|
|
||||||
// means the second edge is our policy. Otherwise, the first
|
|
||||||
// edge is our policy.
|
|
||||||
var local *channeldb.ChannelEdgePolicy
|
|
||||||
if bytes.Equal(edge1.Node.PubKeyBytes[:], pubKey[:]) {
|
|
||||||
local = edge2
|
|
||||||
} else {
|
|
||||||
local = edge1
|
|
||||||
}
|
|
||||||
|
|
||||||
return extractChannelUpdate(info, local)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
49
server.go
49
server.go
@ -336,7 +336,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
|||||||
FwdingLog: chanDB.ForwardingLog(),
|
FwdingLog: chanDB.ForwardingLog(),
|
||||||
SwitchPackager: channeldb.NewSwitchPackager(),
|
SwitchPackager: channeldb.NewSwitchPackager(),
|
||||||
ExtractErrorEncrypter: s.sphinx.ExtractErrorEncrypter,
|
ExtractErrorEncrypter: s.sphinx.ExtractErrorEncrypter,
|
||||||
FetchLastChannelUpdate: fetchLastChanUpdate(s, serializedPubKey),
|
FetchLastChannelUpdate: s.fetchLastChanUpdate(),
|
||||||
Notifier: s.cc.chainNotifier,
|
Notifier: s.cc.chainNotifier,
|
||||||
FwdEventTicker: ticker.New(
|
FwdEventTicker: ticker.New(
|
||||||
htlcswitch.DefaultFwdEventInterval),
|
htlcswitch.DefaultFwdEventInterval),
|
||||||
@ -2952,6 +2952,33 @@ func (s *server) fetchLastChanUpdateByOutPoint(op wire.OutPoint) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pubKey := s.identityPriv.PubKey().SerializeCompressed()
|
||||||
|
return extractChannelUpdate(pubKey, info, edge1, edge2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetchLastChanUpdate returns a function which is able to retrieve our latest
|
||||||
|
// channel update for a target channel.
|
||||||
|
func (s *server) fetchLastChanUpdate() func(lnwire.ShortChannelID) (
|
||||||
|
*lnwire.ChannelUpdate, error) {
|
||||||
|
|
||||||
|
ourPubKey := s.identityPriv.PubKey().SerializeCompressed()
|
||||||
|
return func(cid lnwire.ShortChannelID) (*lnwire.ChannelUpdate, error) {
|
||||||
|
info, edge1, edge2, err := s.chanRouter.GetChannelByID(cid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return extractChannelUpdate(ourPubKey[:], info, edge1, edge2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractChannelUpdate attempts to retrieve a lnwire.ChannelUpdate message
|
||||||
|
// from an edge's info and a set of routing policies.
|
||||||
|
// NOTE: the passed policies can be nil.
|
||||||
|
func extractChannelUpdate(ownerPubKey []byte,
|
||||||
|
info *channeldb.ChannelEdgeInfo,
|
||||||
|
policies ...*channeldb.ChannelEdgePolicy) (
|
||||||
|
*lnwire.ChannelUpdate, error) {
|
||||||
|
|
||||||
// Helper function to extract the owner of the given policy.
|
// Helper function to extract the owner of the given policy.
|
||||||
owner := func(edge *channeldb.ChannelEdgePolicy) []byte {
|
owner := func(edge *channeldb.ChannelEdgePolicy) []byte {
|
||||||
var pubKey *btcec.PublicKey
|
var pubKey *btcec.PublicKey
|
||||||
@ -2971,21 +2998,19 @@ func (s *server) fetchLastChanUpdateByOutPoint(op wire.OutPoint) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the channel update from the policy we own, if any.
|
// Extract the channel update from the policy we own, if any.
|
||||||
ourPubKey := s.identityPriv.PubKey().SerializeCompressed()
|
for _, edge := range policies {
|
||||||
if edge1 != nil && bytes.Equal(ourPubKey, owner(edge1)) {
|
if edge != nil && bytes.Equal(ownerPubKey, owner(edge)) {
|
||||||
return extractChannelUpdate(info, edge1)
|
return createChannelUpdate(info, edge)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if edge2 != nil && bytes.Equal(ourPubKey, owner(edge2)) {
|
return nil, fmt.Errorf("unable to extract ChannelUpdate for channel %v",
|
||||||
return extractChannelUpdate(info, edge2)
|
info.ChannelPoint)
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("unable to find channel(%v)", op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractChannelUpdate retrieves a lnwire.ChannelUpdate message from an edge's
|
// createChannelUpdate reconstructs a signed ChannelUpdate from the given edge
|
||||||
// info and routing policy.
|
// info and policy.
|
||||||
func extractChannelUpdate(info *channeldb.ChannelEdgeInfo,
|
func createChannelUpdate(info *channeldb.ChannelEdgeInfo,
|
||||||
policy *channeldb.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) {
|
policy *channeldb.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) {
|
||||||
|
|
||||||
update := &lnwire.ChannelUpdate{
|
update := &lnwire.ChannelUpdate{
|
||||||
|
Loading…
Reference in New Issue
Block a user