mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
405d4e5f73
This change adds a new subsystem that is responsible for providing an up to date view of some global chainstate parameters.
113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
package chainntnfs_test
|
|
|
|
import (
|
|
"math/rand"
|
|
"reflect"
|
|
"testing"
|
|
"testing/quick"
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
|
"github.com/lightningnetwork/lnd/lntest/mock"
|
|
"github.com/lightningnetwork/lnd/lntest/wait"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type blockEpoch chainntnfs.BlockEpoch
|
|
|
|
func (blockEpoch) Generate(r *rand.Rand, size int) reflect.Value {
|
|
var chainHash, prevBlockHash, merkleRootHash chainhash.Hash
|
|
r.Read(chainHash[:])
|
|
r.Read(prevBlockHash[:])
|
|
r.Read(merkleRootHash[:])
|
|
|
|
return reflect.ValueOf(blockEpoch(chainntnfs.BlockEpoch{
|
|
Hash: &chainHash,
|
|
Height: r.Int31n(1000000),
|
|
BlockHeader: &wire.BlockHeader{
|
|
Version: 2,
|
|
PrevBlock: prevBlockHash,
|
|
MerkleRoot: merkleRootHash,
|
|
Timestamp: time.Now(),
|
|
Bits: r.Uint32(),
|
|
Nonce: r.Uint32(),
|
|
},
|
|
}))
|
|
}
|
|
|
|
// TestBestBlockTracker ensures that the most recent event pushed on the
|
|
// underlying EpochChan is remembered by the BestBlockView functions as well
|
|
// as testing the idempotence of the BestBlockView interface.
|
|
func TestBestBlockTracker(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
notifier := &mock.ChainNotifier{
|
|
SpendChan: nil,
|
|
EpochChan: make(chan *chainntnfs.BlockEpoch),
|
|
ConfChan: nil,
|
|
}
|
|
|
|
chainNotifierI := chainntnfs.ChainNotifier(notifier)
|
|
|
|
tracker := chainntnfs.NewBestBlockTracker(chainNotifierI)
|
|
require.Nil(t, tracker.Start(),
|
|
"BestBlockTacker could not be started")
|
|
|
|
// we have to limit test cases because the poll interval of
|
|
// wait.Predicate isn't tight enough to support the usual 100
|
|
cfg := quick.Config{MaxCount: 50}
|
|
correctness := func(epochRand blockEpoch) bool {
|
|
epoch := chainntnfs.BlockEpoch(epochRand)
|
|
notifier.EpochChan <- &epoch
|
|
|
|
// wait for new block to propagate
|
|
err := wait.Predicate(
|
|
func() bool {
|
|
_, err := tracker.BestHeight()
|
|
return err == nil
|
|
},
|
|
1*time.Second,
|
|
)
|
|
require.Nil(t, err,
|
|
"BestBlockTracker: block propagation timeout")
|
|
|
|
height, _ := tracker.BestHeight()
|
|
header, _ := tracker.BestBlockHeader()
|
|
|
|
return height == uint32(epoch.Height) &&
|
|
header == epoch.BlockHeader
|
|
}
|
|
idempotence := func(epochRand blockEpoch) bool {
|
|
epoch := chainntnfs.BlockEpoch(epochRand)
|
|
notifier.EpochChan <- &epoch
|
|
|
|
// wait for new block to propagate
|
|
err := wait.Predicate(
|
|
func() bool {
|
|
_, err := tracker.BestHeight()
|
|
return err == nil
|
|
},
|
|
1*time.Second,
|
|
)
|
|
require.Nil(t, err,
|
|
"ChainStateTracker: block propagation timeout")
|
|
|
|
height0, _ := tracker.BestHeight()
|
|
height1, _ := tracker.BestHeight()
|
|
header0, _ := tracker.BestBlockHeader()
|
|
header1, _ := tracker.BestBlockHeader()
|
|
|
|
return height0 == height1 && header0 == header1
|
|
}
|
|
err := quick.Check(correctness, &cfg)
|
|
require.Nil(t, err,
|
|
"ChainStateTracker does not give up to date info: %v", err)
|
|
|
|
require.Nil(t, quick.Check(idempotence, &cfg),
|
|
"ChainStateTracker is not idempotent")
|
|
|
|
require.Nil(t, tracker.Stop(), "ChainStateTracker could not be stopped")
|
|
}
|