From b3948d352e565723748a18e0594e6d0b16e092bd Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Mon, 13 Nov 2017 17:32:27 -0800 Subject: [PATCH] funding tests: update tests for the 6 block and private channel changes --- fundingmanager_test.go | 639 ++++++++++++++++++----------------------- 1 file changed, 283 insertions(+), 356 deletions(-) diff --git a/fundingmanager_test.go b/fundingmanager_test.go index f1f41844..3da5fcbb 100644 --- a/fundingmanager_test.go +++ b/fundingmanager_test.go @@ -81,14 +81,20 @@ var ( ) type mockNotifier struct { - confChannel chan *chainntnfs.TxConfirmation - epochChan chan *chainntnfs.BlockEpoch + oneConfChannel chan *chainntnfs.TxConfirmation + sixConfChannel chan *chainntnfs.TxConfirmation + epochChan chan *chainntnfs.BlockEpoch } func (m *mockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) { + if numConfs == 6 { + return &chainntnfs.ConfirmationEvent{ + Confirmed: m.sixConfChannel, + }, nil + } return &chainntnfs.ConfirmationEvent{ - Confirmed: m.confChannel, + Confirmed: m.oneConfChannel, }, nil } func (m *mockNotifier) RegisterBlockEpochNtfn() (*chainntnfs.BlockEpochEvent, error) { @@ -164,8 +170,9 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, estimator := lnwallet.StaticFeeEstimator{FeeRate: 250} chainNotifier := &mockNotifier{ - confChannel: make(chan *chainntnfs.TxConfirmation, 1), - epochChan: make(chan *chainntnfs.BlockEpoch, 1), + oneConfChannel: make(chan *chainntnfs.TxConfirmation, 1), + sixConfChannel: make(chan *chainntnfs.TxConfirmation, 1), + epochChan: make(chan *chainntnfs.BlockEpoch, 1), } newChannelsChan := make(chan *newChannelMsg) @@ -210,7 +217,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, SignMessage: func(pubKey *btcec.PublicKey, msg []byte) (*btcec.Signature, error) { return nil, nil }, - SendLocalAnnouncement: func(msg lnwire.Message) error { + SendAnnouncement: func(msg lnwire.Message) error { select { case sentAnnouncements <- msg: case <-shutdownChan: @@ -308,7 +315,7 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) { msg []byte) (*btcec.Signature, error) { return nil, nil }, - SendLocalAnnouncement: func(msg lnwire.Message) error { + SendAnnouncement: func(msg lnwire.Message) error { select { case aliceAnnounceChan <- msg: case <-shutdownChan: @@ -398,7 +405,7 @@ func tearDownFundingManagers(t *testing.T, a, b *testNode) { // transaction is confirmed on-chain. Returns the funding out point. func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt, pushAmt btcutil.Amount, numConfs uint32, - updateChan chan *lnrpc.OpenStatusUpdate, private bool) *wire.OutPoint { + updateChan chan *lnrpc.OpenStatusUpdate, announceChan bool) *wire.OutPoint { // Create a funding request and start the workflow. errChan := make(chan error, 1) initReq := &openChanReq{ @@ -407,7 +414,7 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt, chainHash: *activeNetParams.GenesisHash, localFundingAmt: localFundingAmt, pushAmt: lnwire.NewMSatFromSatoshis(pushAmt), - private: private, + private: !announceChan, updates: updateChan, err: errChan, } @@ -625,126 +632,98 @@ func assertFundingLockedSent(t *testing.T, alice, bob *testNode, assertDatabaseState(t, bob, fundingOutPoint, fundingLockedSent) } -func assertPrivateAnnouncement(t *testing.T, node *testNode) { - // After the FundingLocked message is sent, Alice and Bob will each - // send three private announcement messages: - // 1) ChannelAnnouncement - // 2) ChannelUpdate - // 3) ChannelUpdate - // The only message of the three that will reach the peer is the second - // ChannelUpdate message. The second channel update is sent via - // SendToPeer. In the test case, the second channel update will not be - // sent because the tests don't use the gossiper. - privateAnns := make([]lnwire.Message, 2) - for i := 0; i < len(privateAnns); i++ { - select { - case privateAnns[i] = <-node.announceChan: - case <-time.After(time.Second * 5): - t.Fatalf("node did not send private announcement: %v", i) - } - } - - gotPrivateChannelAnnouncement := false - gotPrivateChannelUpdate := false - for _, msg := range privateAnns { - switch msg.(type) { - case *lnwire.ChannelAnnouncement: - gotPrivateChannelAnnouncement = true - case *lnwire.ChannelUpdate: - gotPrivateChannelUpdate = true - } - } - - if !gotPrivateChannelAnnouncement { - t.Fatalf("did not get private ChannelAnnouncement from node") - } - if !gotPrivateChannelUpdate { - t.Fatalf("did not get private ChannelUpdate from node") - } -} - func assertAddedToRouterGraph(t *testing.T, alice, bob *testNode, fundingOutPoint *wire.OutPoint) { - state, _, err := alice.fundingMgr.getChannelOpeningState(fundingOutPoint) - if err != nil { - t.Fatalf("unable to get channel state: %v", err) - } - - if state != addedToRouterGraph { - t.Fatalf("expected state to be addedToRouterGraph, was %v", state) - } - state, _, err = bob.fundingMgr.getChannelOpeningState(fundingOutPoint) - if err != nil { - t.Fatalf("unable to get channel state: %v", err) - } - - if state != addedToRouterGraph { - t.Fatalf("expected state to be addedToRouterGraph, was %v", state) - } + assertDatabaseState(t, alice, fundingOutPoint, addedToRouterGraph) + assertDatabaseState(t, bob, fundingOutPoint, addedToRouterGraph) } func assertChannelAnnouncements(t *testing.T, alice, bob *testNode) { + // After the FundingLocked message is sent, Alice and Bob will each + // send the following messages to their gossiper: + // 1) ChannelAnnouncement + // 2) ChannelUpdate + // The ChannelAnnouncement is kept locally, while the ChannelUpdate + // is sent directly to the other peer, so the edge policies are + // known to both peers. + for j, node := range []*testNode{alice, bob} { + announcements := make([]lnwire.Message, 2) + for i := 0; i < len(announcements); i++ { + select { + case announcements[i] = <-node.announceChan: + case <-time.After(time.Second * 5): + t.Fatalf("node did not send announcement: %v", i) + } + } + + gotChannelAnnouncement := false + gotChannelUpdate := false + for _, msg := range announcements { + switch msg.(type) { + case *lnwire.ChannelAnnouncement: + gotChannelAnnouncement = true + case *lnwire.ChannelUpdate: + gotChannelUpdate = true + } + } + + if !gotChannelAnnouncement { + t.Fatalf("did not get ChannelAnnouncement from node %d", + j) + } + if !gotChannelUpdate { + t.Fatalf("did not get ChannelUpdate from node %d", j) + } + + // Make sure no other message is sent. + select { + case <-node.announceChan: + t.Fatalf("received unexpected announcement") + case <-time.After(300 * time.Millisecond): + // Expected + } + } +} + +func assertAnnouncementSignatures(t *testing.T, alice, bob *testNode) { // After the FundingLocked message is sent and six confirmations have - // been reached, the channel will be announced to the greater network. + // been reached, the channel will be announced to the greater network + // by having the nodes exchange announcement signatures. // Two distinct messages will be sent: // 1) AnnouncementSignatures // 2) NodeAnnouncement // These may arrive in no particular order. - announcements := make([]lnwire.Message, 2) - for i := 0; i < len(announcements); i++ { - select { - case announcements[i] = <-alice.announceChan: - case <-time.After(time.Second * 5): - t.Fatalf("alice did not send announcement %v", i) + // Note that sending the NodeAnnouncement at this point is an + // implementation detail, and not something required by the LN spec. + for j, node := range []*testNode{alice, bob} { + announcements := make([]lnwire.Message, 2) + for i := 0; i < len(announcements); i++ { + select { + case announcements[i] = <-node.announceChan: + case <-time.After(time.Second * 5): + t.Fatalf("node did not send announcement %v", i) + } } - } - gotAnnounceSignatures := false - gotNodeAnnouncement := false - - for _, msg := range announcements { - switch msg.(type) { - case *lnwire.AnnounceSignatures: - gotAnnounceSignatures = true - case *lnwire.NodeAnnouncement: - gotNodeAnnouncement = true + gotAnnounceSignatures := false + gotNodeAnnouncement := false + for _, msg := range announcements { + switch msg.(type) { + case *lnwire.AnnounceSignatures: + gotAnnounceSignatures = true + case *lnwire.NodeAnnouncement: + gotNodeAnnouncement = true + } } - } - if !gotAnnounceSignatures { - t.Fatalf("did not get AnnounceSignatures from Alice") - } - if !gotNodeAnnouncement { - t.Fatalf("did not get NodeAnnouncement from Alice") - } - - // Do the check for Bob as well. - for i := 0; i < len(announcements); i++ { - select { - case announcements[i] = <-bob.announceChan: - case <-time.After(time.Second * 5): - t.Fatalf("bob did not send announcement %v", i) + if !gotAnnounceSignatures { + t.Fatalf("did not get AnnounceSignatures from node %d", + j) } - } - - gotAnnounceSignatures = false - gotNodeAnnouncement = false - - for _, msg := range announcements { - switch msg.(type) { - case *lnwire.AnnounceSignatures: - gotAnnounceSignatures = true - case *lnwire.NodeAnnouncement: - gotNodeAnnouncement = true + if !gotNodeAnnouncement { + t.Fatalf("did not get NodeAnnouncement from node %d", j) } } - - if !gotAnnounceSignatures { - t.Fatalf("did not get AnnounceSignatures from Bob") - } - if !gotNodeAnnouncement { - t.Fatalf("did not get NodeAnnouncement from Bob") - } } func waitForOpenUpdate(t *testing.T, updateChan chan *lnrpc.OpenStatusUpdate) { @@ -834,11 +813,11 @@ func TestFundingManagerNormalWorkflow(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -855,31 +834,17 @@ func TestFundingManagerNormalWorkflow(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) - // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Make sure both fundingManagers send the expected channel announcements. - assertChannelAnnouncements(t, alice, bob) - - // The funding process is now finished, wait for the + // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update waitForOpenUpdate(t, updateChan) - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - assertNoChannelState(t, alice, bob, fundingOutPoint) - // Exchange the fundingLocked messages. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) bob.fundingMgr.processFundingLocked(fundingLockedAlice, aliceAddr) @@ -887,6 +852,17 @@ func TestFundingManagerNormalWorkflow(t *testing.T) { // Check that they notify the breach arbiter and peer about the new // channel. assertHandleFundingLocked(t, alice, bob) + + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Make sure the fundingManagers exchange announcement signatures. + assertAnnouncementSignatures(t, alice, bob) + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } func TestFundingManagerRestartBehavior(t *testing.T) { @@ -899,7 +875,7 @@ func TestFundingManagerRestartBehavior(t *testing.T) { // transaction is broadcasted. updateChan := make(chan *lnrpc.OpenStatusUpdate) fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // After the funding transaction gets mined, both nodes will send the // fundingLocked message to the other peer. If the funding node fails @@ -917,8 +893,8 @@ func TestFundingManagerRestartBehavior(t *testing.T) { } // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -950,8 +926,8 @@ func TestFundingManagerRestartBehavior(t *testing.T) { recreateAliceFundingManager(t, alice) // Intentionally make the channel announcements fail - alice.fundingMgr.cfg.SendLocalAnnouncement = func(msg lnwire.Message) error { - return fmt.Errorf("intentional error in SendLocalAnnouncement") + alice.fundingMgr.cfg.SendAnnouncement = func(msg lnwire.Message) error { + return fmt.Errorf("intentional error in SendAnnouncement") } fundingLockedAlice := checkNodeSendingFundingLocked(t, alice) @@ -968,36 +944,6 @@ func TestFundingManagerRestartBehavior(t *testing.T) { // Expected } - // Next up, we check that Alice rebroadcasts the private announcement - // messages on restart. Bob should as expected send private announcements. - recreateAliceFundingManager(t, alice) - time.Sleep(300 * time.Millisecond) - - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) - - // Check that the state machine is updated accordingly - assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) - - // Next, we check that Alice rebroadcasts the channel announcement - // messages on restart. Bob should as expected send channel announcements. - recreateAliceFundingManager(t, alice) - time.Sleep(300 * time.Millisecond) - - // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - assertChannelAnnouncements(t, alice, bob) - - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - assertNoChannelState(t, alice, bob, fundingOutPoint) - // Exchange the fundingLocked messages. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) bob.fundingMgr.processFundingLocked(fundingLockedAlice, aliceAddr) @@ -1005,6 +951,35 @@ func TestFundingManagerRestartBehavior(t *testing.T) { // Check that they notify the breach arbiter and peer about the new // channel. assertHandleFundingLocked(t, alice, bob) + + // Next up, we check that Alice rebroadcasts the announcement + // messages on restart. Bob should as expected send announcements. + recreateAliceFundingManager(t, alice) + time.Sleep(300 * time.Millisecond) + + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) + + // Check that the state machine is updated accordingly + assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) + + // Next, we check that Alice sends the annnouncement signatures + // on restart after six confirmations. Bob should as expected send + // them as well. + recreateAliceFundingManager(t, alice) + time.Sleep(300 * time.Millisecond) + + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Make sure the fundingManagers exchange announcement signatures. + assertAnnouncementSignatures(t, alice, bob) + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } // TestFundingManagerOfflinePeer checks that the fundingManager waits for the @@ -1020,7 +995,7 @@ func TestFundingManagerOfflinePeer(t *testing.T) { // transaction is broadcasted. updateChan := make(chan *lnrpc.OpenStatusUpdate) fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // After the funding transaction gets mined, both nodes will send the // fundingLocked message to the other peer. If the funding node fails @@ -1038,8 +1013,8 @@ func TestFundingManagerOfflinePeer(t *testing.T) { } // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1108,30 +1083,15 @@ func TestFundingManagerOfflinePeer(t *testing.T) { // Make sure both fundingManagers send the expected channel // announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) + assertChannelAnnouncements(t, alice, bob) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) - // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Make sure both fundingManagers send the expected channel announcements. - assertChannelAnnouncements(t, alice, bob) - - // The funding process is now finished, wait for the + // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update waitForOpenUpdate(t, updateChan) - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - assertNoChannelState(t, alice, bob, fundingOutPoint) - // Exchange the fundingLocked messages. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) bob.fundingMgr.processFundingLocked(fundingLockedAlice, aliceAddr) @@ -1140,6 +1100,17 @@ func TestFundingManagerOfflinePeer(t *testing.T) { // channel. assertHandleFundingLocked(t, alice, bob) + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Make sure both fundingManagers send the expected announcement + // signatures. + assertAnnouncementSignatures(t, alice, bob) + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } func TestFundingManagerFundingTimeout(t *testing.T) { @@ -1153,7 +1124,7 @@ func TestFundingManagerFundingTimeout(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. - _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, false) + _ = openChannel(t, alice, bob, 500000, 0, 1, updateChan, true) // Bob will at this point be waiting for the funding transaction to be // confirmed, so the channel should be considered pending. @@ -1198,11 +1169,11 @@ func TestFundingManagerReceiveFundingLockedTwice(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1219,31 +1190,17 @@ func TestFundingManagerReceiveFundingLockedTwice(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) - // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Make sure both fundingManagers send the expected channel announcements. - assertChannelAnnouncements(t, alice, bob) - - // The funding process is now finished, wait for the + // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update waitForOpenUpdate(t, updateChan) - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - assertNoChannelState(t, alice, bob, fundingOutPoint) - // Send the fundingLocked message twice to Alice, and once to Bob. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) @@ -1284,6 +1241,16 @@ func TestFundingManagerReceiveFundingLockedTwice(t *testing.T) { // Expected } + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Make sure the fundingManagers exchange announcement signatures. + assertAnnouncementSignatures(t, alice, bob) + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } // TestFundingManagerRestartAfterChanAnn checks that the fundingManager properly @@ -1301,11 +1268,11 @@ func TestFundingManagerRestartAfterChanAnn(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1322,31 +1289,17 @@ func TestFundingManagerRestartAfterChanAnn(t *testing.T) { // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) - // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Make sure both fundingManagers send the expected channel announcements. - assertChannelAnnouncements(t, alice, bob) - - // The funding process is now finished, wait for the + // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update waitForOpenUpdate(t, updateChan) - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - assertNoChannelState(t, alice, bob, fundingOutPoint) - // At this point we restart Alice's fundingManager, before she receives // the fundingLocked message. After restart, she will receive it, and // we expect her to be able to handle it correctly. @@ -1359,12 +1312,23 @@ func TestFundingManagerRestartAfterChanAnn(t *testing.T) { // Check that they notify the breach arbiter and peer about the new // channel. assertHandleFundingLocked(t, alice, bob) + + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Make sure both fundingManagers send the expected channel announcements. + assertAnnouncementSignatures(t, alice, bob) + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } -// TestFundingManagerProcessingAfterReceivingFundingLocked checks that the -// fundingManager continues to operate as expected after it has processed +// TestFundingManagerRestartAfterReceivingFundingLocked checks that the +// fundingManager continues to operate as expected after it has received // fundingLocked and then gets restarted. -func TestFundingManagerRestartAfterProcessingFundingLocked(t *testing.T) { +func TestFundingManagerRestartAfterReceivingFundingLocked(t *testing.T) { disableFndgLogger(t) alice, bob := setupFundingManagers(t) @@ -1376,11 +1340,11 @@ func TestFundingManagerRestartAfterProcessingFundingLocked(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - false) + true) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1407,36 +1371,31 @@ func TestFundingManagerRestartAfterProcessingFundingLocked(t *testing.T) { // channel. assertHandleFundingLocked(t, alice, bob) - // Sleep since handleFundingLocked is in a goroutine. - time.Sleep(300 * time.Millisecond) - // At this point we restart Alice's fundingManager. recreateAliceFundingManager(t, alice) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) // Check that the state machine is updated accordingly assertAddedToRouterGraph(t, alice, bob, fundingOutPoint) // Notify that six confirmations has been reached on funding transaction. - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} // Make sure both fundingManagers send the expected channel announcements. - assertChannelAnnouncements(t, alice, bob) + assertAnnouncementSignatures(t, alice, bob) // The internal state-machine should now have deleted the channelStates // from the database, as the channel is announced. assertNoChannelState(t, alice, bob, fundingOutPoint) } -// TestFundingManagerPrivateChannel tests that if we open a private channel, -// the announcement_signatures nor the node_announcement messages are sent. +// TestFundingManagerPrivateChannel tests that if we open a private channel +// (a channel not supposed to be announced to the rest of the network), +// the announcementSignatures nor the nodeAnnouncement messages are sent. func TestFundingManagerPrivateChannel(t *testing.T) { disableFndgLogger(t) @@ -1449,15 +1408,11 @@ func TestFundingManagerPrivateChannel(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - true) + false) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Give fundingManager time to process the newly mined tx and write - //state to database. - time.Sleep(300 * time.Millisecond) + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1471,54 +1426,17 @@ func TestFundingManagerPrivateChannel(t *testing.T) { // And similarly Bob will send funding locked to Alice. fundingLockedBob := checkNodeSendingFundingLocked(t, bob) - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) - // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) - - // Notify that six confirmations has been reached on the funding - // transaction. This won't actually succeed since annAfterSixConfs is - // never called, so this is called in a goroutine to not pause the - // main thread. - go func() { - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - }() - - // Since this is a private channel, we shouldn't receive the public - // channel announcement messages announcement_signatures or - // node_announcement. - select { - case ann := <-alice.announceChan: - t.Fatalf("unexpectedly got channel announcement message: %v", ann) - default: - // Expected - } - - select { - case ann := <-bob.announceChan: - t.Fatalf("unexpectedly got channel announcement message: %v", ann) - default: - // Expected - } - - // The funding process is now finished, wait for the + // The funding transaction is now confirmed, wait for the // OpenStatusUpdate_ChanOpen update waitForOpenUpdate(t, updateChan) - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. - time.Sleep(300 * time.Millisecond) - assertNoChannelState(t, alice, bob, fundingOutPoint) - // Exchange the fundingLocked messages. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) bob.fundingMgr.processFundingLocked(fundingLockedAlice, aliceAddr) @@ -1526,11 +1444,35 @@ func TestFundingManagerPrivateChannel(t *testing.T) { // Check that they notify the breach arbiter and peer about the new // channel. assertHandleFundingLocked(t, alice, bob) + + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Since this is a private channel, we shouldn't receive the + // announcement signatures or node announcement messages. + select { + case ann := <-alice.announceChan: + t.Fatalf("unexpectedly got channel announcement message: %v", ann) + case <-time.After(300 * time.Millisecond): + // Expected + } + + select { + case ann := <-bob.announceChan: + t.Fatalf("unexpectedly got channel announcement message: %v", ann) + case <-time.After(300 * time.Millisecond): + // Expected + } + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) } // TestFundingManagerPrivateRestart tests that the privacy guarantees granted // by the private channel persist even on restart. This means that the -// announcement_signatures nor the node_announcement messages are sent upon +// announcement signatures nor the node announcement messages are sent upon // restart. func TestFundingManagerPrivateRestart(t *testing.T) { disableFndgLogger(t) @@ -1544,15 +1486,11 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // Run through the process of opening the channel, up until the funding // transaction is broadcasted. fundingOutPoint := openChannel(t, alice, bob, 500000, 0, 1, updateChan, - true) + false) // Notify that transaction was mined - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - - // Give fundingManager time to process the newly mined tx and write - //state to database. - time.Sleep(300 * time.Millisecond) + alice.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.oneConfChannel <- &chainntnfs.TxConfirmation{} // The funding transaction was mined, so assert that both funding // managers now have the state of this channel 'markedOpen' in their @@ -1566,63 +1504,21 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // And similarly Bob will send funding locked to Alice. fundingLockedBob := checkNodeSendingFundingLocked(t, bob) - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) - // Check that the state machine is updated accordingly assertFundingLockedSent(t, alice, bob, fundingOutPoint) - // Restart Alice's fundingManager so we can prove that the public - // channel announcements are not sent upon restart and that the private - // setting persists upon restart. - recreateAliceFundingManager(t, alice) - time.Sleep(300 * time.Millisecond) + // Make sure both fundingManagers send the expected channel + // announcements. + assertChannelAnnouncements(t, alice, bob) - // Make sure both fundingManagers send the expected private announcements. - assertPrivateAnnouncement(t, alice) - assertPrivateAnnouncement(t, bob) - - // Sleep to make sure database write is finished. - time.Sleep(300 * time.Millisecond) - - // Restart again. - recreateAliceFundingManager(t, alice) - time.Sleep(300 * time.Millisecond) - - // Notify that six confirmations has been reached on the funding - // transaction. This won't actually succeed since annAfterSixConfs is - // never called, so this is called in a goroutine to not pause the - // main thread. - go func() { - alice.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - bob.mockNotifier.confChannel <- &chainntnfs.TxConfirmation{} - }() - - // Since this is a private channel, we shouldn't receive the public - // channel announcement messages announcement_signatures or - // node_announcement. - select { - case ann := <-alice.announceChan: - t.Fatalf("unexpectedly got channel announcement message: %v", ann) - default: - // Expected - } - - select { - case ann := <-bob.announceChan: - t.Fatalf("unexpectedly got channel announcement message: %v", ann) - default: - // Expected - } - - // The internal state-machine should now have deleted the channelStates - // from the database, as the channel is announced. // Note: We don't check for the addedToRouterGraph state because in // the private channel mode, the state is quickly changed from // addedToRouterGraph to deleted from the database since the public // announcement phase is skipped. - time.Sleep(300 * time.Millisecond) - assertNoChannelState(t, alice, bob, fundingOutPoint) + + // The funding transaction is now confirmed, wait for the + // OpenStatusUpdate_ChanOpen update + waitForOpenUpdate(t, updateChan) // Exchange the fundingLocked messages. alice.fundingMgr.processFundingLocked(fundingLockedBob, bobAddr) @@ -1631,4 +1527,35 @@ func TestFundingManagerPrivateRestart(t *testing.T) { // Check that they notify the breach arbiter and peer about the new // channel. assertHandleFundingLocked(t, alice, bob) + + // Restart Alice's fundingManager so we can prove that the public + // channel announcements are not sent upon restart and that the private + // setting persists upon restart. + recreateAliceFundingManager(t, alice) + time.Sleep(300 * time.Millisecond) + + // Notify that six confirmations has been reached on funding transaction. + alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{} + + // Since this is a private channel, we shouldn't receive the public + // channel announcement messages announcement signatures or + // node announcement. + select { + case ann := <-alice.announceChan: + t.Fatalf("unexpectedly got channel announcement message: %v", ann) + case <-time.After(300 * time.Millisecond): + // Expected + } + + select { + case ann := <-bob.announceChan: + t.Fatalf("unexpectedly got channel announcement message: %v", ann) + case <-time.After(300 * time.Millisecond): + // Expected + } + + // The internal state-machine should now have deleted the channelStates + // from the database, as the channel is announced. + assertNoChannelState(t, alice, bob, fundingOutPoint) }