mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-26 22:17:51 +01:00
router: test that this change catches up router to the latest blocks
This commit is contained in:
@@ -18,9 +18,11 @@ import (
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/clock"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
lnmock "github.com/lightningnetwork/lnd/lntest/mock"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/record"
|
||||
@@ -44,6 +46,8 @@ type testCtx struct {
|
||||
chain *mockChain
|
||||
|
||||
chainView *mockChainView
|
||||
|
||||
notifier *lnmock.ChainNotifier
|
||||
}
|
||||
|
||||
func (c *testCtx) getChannelIDFromAlias(t *testing.T, a, b string) uint64 {
|
||||
@@ -136,11 +140,18 @@ func createTestCtxFromGraphInstanceAssumeValid(t *testing.T,
|
||||
MissionControl: mc,
|
||||
}
|
||||
|
||||
notifier := &lnmock.ChainNotifier{
|
||||
EpochChan: make(chan *chainntnfs.BlockEpoch),
|
||||
SpendChan: make(chan *chainntnfs.SpendDetail),
|
||||
ConfChan: make(chan *chainntnfs.TxConfirmation),
|
||||
}
|
||||
|
||||
router, err := New(Config{
|
||||
Graph: graphInstance.graph,
|
||||
Chain: chain,
|
||||
ChainView: chainView,
|
||||
Payer: &mockPaymentAttemptDispatcherOld{},
|
||||
Notifier: notifier,
|
||||
Control: makeMockControlTower(),
|
||||
MissionControl: mc,
|
||||
SessionSource: sessionSource,
|
||||
@@ -171,6 +182,7 @@ func createTestCtxFromGraphInstanceAssumeValid(t *testing.T,
|
||||
channelIDs: graphInstance.channelIDs,
|
||||
chain: chain,
|
||||
chainView: chainView,
|
||||
notifier: notifier,
|
||||
}
|
||||
|
||||
cleanUp := func() {
|
||||
@@ -1624,7 +1636,7 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
|
||||
ctx.chain.addBlock(block, height, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(height))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), height,
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
|
||||
// Give time to process new blocks
|
||||
@@ -1656,7 +1668,7 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
|
||||
ctx.chain.addBlock(block, height, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(height))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), height,
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
// Give time to process new blocks
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
@@ -1833,7 +1845,7 @@ func TestDisconnectedBlocks(t *testing.T) {
|
||||
ctx.chain.addBlock(block, height, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(height))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), height,
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
|
||||
// Give time to process new blocks
|
||||
@@ -1867,7 +1879,7 @@ func TestDisconnectedBlocks(t *testing.T) {
|
||||
ctx.chain.addBlock(block, height, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(height))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), height,
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
// Give time to process new blocks
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
@@ -1949,12 +1961,18 @@ func TestDisconnectedBlocks(t *testing.T) {
|
||||
// Create a 15 block fork. We first let the chainView notify the router
|
||||
// about stale blocks, before sending the now connected blocks. We do
|
||||
// this because we expect this order from the chainview.
|
||||
ctx.chainView.notifyStaleBlockAck = make(chan struct{}, 1)
|
||||
for i := len(minorityChain) - 1; i >= 0; i-- {
|
||||
block := minorityChain[i]
|
||||
height := uint32(forkHeight) + uint32(i) + 1
|
||||
ctx.chainView.notifyStaleBlock(block.BlockHash(), height,
|
||||
block.Transactions)
|
||||
block.Transactions, t)
|
||||
<-ctx.chainView.notifyStaleBlockAck
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
ctx.chainView.notifyBlockAck = make(chan struct{}, 1)
|
||||
for i := uint32(1); i <= 15; i++ {
|
||||
block := &wire.MsgBlock{
|
||||
Transactions: []*wire.MsgTx{},
|
||||
@@ -1963,10 +1981,10 @@ func TestDisconnectedBlocks(t *testing.T) {
|
||||
ctx.chain.addBlock(block, height, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(height))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), height,
|
||||
block.Transactions)
|
||||
block.Transactions, t)
|
||||
<-ctx.chainView.notifyBlockAck
|
||||
}
|
||||
|
||||
// Give time to process new blocks
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
|
||||
// chanID2 should not be in the database anymore, since it is not
|
||||
@@ -2022,7 +2040,7 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
|
||||
ctx.chain.addBlock(block102, uint32(nextHeight), rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(nextHeight))
|
||||
ctx.chainView.notifyBlock(block102.BlockHash(), uint32(nextHeight),
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
|
||||
// We'll now create the edges and nodes within the database required
|
||||
// for the ChannelRouter to properly recognize the channel we added
|
||||
@@ -2075,7 +2093,7 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
|
||||
ctx.chain.addBlock(block, uint32(nextHeight), rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(nextHeight))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), uint32(nextHeight),
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
|
||||
// At this point, our starting height should be 107.
|
||||
@@ -2117,7 +2135,7 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
|
||||
ctx.chain.addBlock(block, uint32(nextHeight), rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(nextHeight))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), uint32(nextHeight),
|
||||
[]*wire.MsgTx{})
|
||||
[]*wire.MsgTx{}, t)
|
||||
}
|
||||
|
||||
// At this point, our starting height should be 112.
|
||||
@@ -4249,3 +4267,72 @@ func TestSendMPPaymentFailedWithShardsInFlight(t *testing.T) {
|
||||
session.AssertExpectations(t)
|
||||
missionControl.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestBlockDifferenceFix tests if when the router is behind on blocks, the
|
||||
// router catches up to the best block head.
|
||||
func TestBlockDifferenceFix(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
initialBlockHeight := uint32(0)
|
||||
// Starting height here is set to 0, which is behind where we want to be.
|
||||
ctx, cleanup := createTestCtxSingleNode(t, initialBlockHeight)
|
||||
defer cleanup()
|
||||
|
||||
// Add initial block to our mini blockchain.
|
||||
block := &wire.MsgBlock{
|
||||
Transactions: []*wire.MsgTx{},
|
||||
}
|
||||
ctx.chain.addBlock(block, initialBlockHeight, rand.Uint32())
|
||||
|
||||
// Let's generate a new block of height 5, 5 above where our node is at.
|
||||
newBlock := &wire.MsgBlock{
|
||||
Transactions: []*wire.MsgTx{},
|
||||
}
|
||||
newBlockHeight := uint32(5)
|
||||
|
||||
blockDifference := newBlockHeight - initialBlockHeight
|
||||
|
||||
ctx.chainView.notifyBlockAck = make(chan struct{}, 1)
|
||||
|
||||
ctx.chain.addBlock(newBlock, newBlockHeight, rand.Uint32())
|
||||
ctx.chain.setBestBlock(int32(newBlockHeight))
|
||||
ctx.chainView.notifyBlock(block.BlockHash(), newBlockHeight,
|
||||
[]*wire.MsgTx{}, t)
|
||||
|
||||
<-ctx.chainView.notifyBlockAck
|
||||
|
||||
// At this point, the chain notifier should have noticed that we're
|
||||
// behind on blocks, and will send the n missing blocks that we
|
||||
// need to the client's epochs channel. Let's replicate this
|
||||
// functionality.
|
||||
for i := 0; i < int(blockDifference); i++ {
|
||||
currBlockHeight := int32(i + 1)
|
||||
|
||||
nonce := rand.Uint32()
|
||||
|
||||
newBlock := &wire.MsgBlock{
|
||||
Transactions: []*wire.MsgTx{},
|
||||
Header: wire.BlockHeader{Nonce: nonce},
|
||||
}
|
||||
ctx.chain.addBlock(newBlock, uint32(currBlockHeight), nonce)
|
||||
currHash := newBlock.Header.BlockHash()
|
||||
|
||||
newEpoch := &chainntnfs.BlockEpoch{
|
||||
Height: currBlockHeight,
|
||||
Hash: &currHash,
|
||||
}
|
||||
|
||||
ctx.notifier.EpochChan <- newEpoch
|
||||
|
||||
ctx.chainView.notifyBlock(currHash,
|
||||
uint32(currBlockHeight), block.Transactions, t)
|
||||
|
||||
<-ctx.chainView.notifyBlockAck
|
||||
}
|
||||
|
||||
// Then router height should be updated to the latest block.
|
||||
if atomic.LoadUint32(&ctx.router.bestHeight) != newBlockHeight {
|
||||
t.Fatalf("height should have been updated to %v, instead got "+
|
||||
"%v", newBlockHeight, ctx.router.bestHeight)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user