From 0459ccf5422b6f910777cc573e4b44839a293704 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 4 May 2022 11:29:11 +0200 Subject: [PATCH] chainntnfs: test both zmq and rpc bitcoind modes --- chainntnfs/bitcoindnotify/bitcoind.go | 11 +++-- chainntnfs/bitcoindnotify/bitcoind_test.go | 14 +++++- chainntnfs/bitcoindnotify/driver.go | 18 +++++--- chainntnfs/test/bitcoind/bitcoind_test.go | 1 + chainntnfs/test/test_interface.go | 14 +++++- chainntnfs/test_utils.go | 51 ++++++++++++++-------- 6 files changed, 79 insertions(+), 30 deletions(-) diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index 016d46dc4..a83b26e06 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -19,9 +19,14 @@ import ( ) const ( - // notifierType uniquely identifies this concrete implementation of the - // ChainNotifier interface. - notifierType = "bitcoind" + // notifierType uniquely identifies a concrete implementation of the + // ChainNotifier interface that makes use of the bitcoind ZMQ interface. + notifierTypeZMQ = "bitcoind" + + // notifierTypeRPCPolling uniquely identifies a concrete implementation + // of the ChainNotifier interface that makes use of the bitcoind RPC + // interface. + notifierTypeRPCPolling = "bitcoind-rpc-polling" ) // TODO(roasbeef): generalize struct below: diff --git a/chainntnfs/bitcoindnotify/bitcoind_test.go b/chainntnfs/bitcoindnotify/bitcoind_test.go index 796735668..f9511ffe0 100644 --- a/chainntnfs/bitcoindnotify/bitcoind_test.go +++ b/chainntnfs/bitcoindnotify/bitcoind_test.go @@ -108,13 +108,18 @@ func syncNotifierWithMiner(t *testing.T, notifier *BitcoindNotifier, // TestHistoricalConfDetailsTxIndex ensures that we correctly retrieve // historical confirmation details using the backend node's txindex. func TestHistoricalConfDetailsTxIndex(t *testing.T) { + testHistoricalConfDetailsTxIndex(t, true) + testHistoricalConfDetailsTxIndex(t, false) +} + +func testHistoricalConfDetailsTxIndex(t *testing.T, rpcPolling bool) { miner, tearDown := chainntnfs.NewMiner( t, []string{"--txindex"}, true, 25, ) defer tearDown() bitcoindConn, cleanUp := chainntnfs.NewBitcoindBackend( - t, miner.P2PAddress(), true, + t, miner.P2PAddress(), true, rpcPolling, ) defer cleanUp() @@ -206,11 +211,16 @@ func TestHistoricalConfDetailsTxIndex(t *testing.T) { // historical confirmation details using the set of fallback methods when the // backend node's txindex is disabled. func TestHistoricalConfDetailsNoTxIndex(t *testing.T) { + testHistoricalConfDetailsNoTxIndex(t, true) + testHistoricalConfDetailsNoTxIndex(t, false) +} + +func testHistoricalConfDetailsNoTxIndex(t *testing.T, rpcpolling bool) { miner, tearDown := chainntnfs.NewMiner(t, nil, true, 25) defer tearDown() bitcoindConn, cleanUp := chainntnfs.NewBitcoindBackend( - t, miner.P2PAddress(), false, + t, miner.P2PAddress(), false, rpcpolling, ) defer cleanUp() diff --git a/chainntnfs/bitcoindnotify/driver.go b/chainntnfs/bitcoindnotify/driver.go index 634aa3545..1968f74c6 100644 --- a/chainntnfs/bitcoindnotify/driver.go +++ b/chainntnfs/bitcoindnotify/driver.go @@ -56,13 +56,21 @@ func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) { // chainntnfs.ChainNotifier interface. func init() { // Register the driver. - notifier := &chainntnfs.NotifierDriver{ - NotifierType: notifierType, + notifierZMQ := &chainntnfs.NotifierDriver{ + NotifierType: notifierTypeZMQ, New: createNewNotifier, } - - if err := chainntnfs.RegisterNotifier(notifier); err != nil { + if err := chainntnfs.RegisterNotifier(notifierZMQ); err != nil { panic(fmt.Sprintf("failed to register notifier driver '%s': %v", - notifierType, err)) + notifierTypeZMQ, err)) + } + + notifierRPC := &chainntnfs.NotifierDriver{ + NotifierType: notifierTypeRPCPolling, + New: createNewNotifier, + } + if err := chainntnfs.RegisterNotifier(notifierRPC); err != nil { + panic(fmt.Sprintf("failed to register notifier driver '%s': %v", + notifierTypeRPCPolling, err)) } } diff --git a/chainntnfs/test/bitcoind/bitcoind_test.go b/chainntnfs/test/bitcoind/bitcoind_test.go index 32335e7bb..38779f8c7 100644 --- a/chainntnfs/test/bitcoind/bitcoind_test.go +++ b/chainntnfs/test/bitcoind/bitcoind_test.go @@ -13,4 +13,5 @@ import ( // powered chain notifier. func TestInterfaces(t *testing.T) { chainntnfstest.TestInterfaces(t, "bitcoind") + chainntnfstest.TestInterfaces(t, "bitcoind-rpc-polling") } diff --git a/chainntnfs/test/test_interface.go b/chainntnfs/test/test_interface.go index 70f79b4bc..291d72a56 100644 --- a/chainntnfs/test/test_interface.go +++ b/chainntnfs/test/test_interface.go @@ -1966,7 +1966,19 @@ func TestInterfaces(t *testing.T, targetBackEnd string) { case "bitcoind": var bitcoindConn *chain.BitcoindConn bitcoindConn, cleanUp = chainntnfs.NewBitcoindBackend( - t, p2pAddr, true, + t, p2pAddr, true, false, + ) + newNotifier = func() (chainntnfs.TestChainNotifier, error) { + return bitcoindnotify.New( + bitcoindConn, chainntnfs.NetParams, + hintCache, hintCache, blockCache, + ), nil + } + + case "bitcoind-rpc-polling": + var bitcoindConn *chain.BitcoindConn + bitcoindConn, cleanUp = chainntnfs.NewBitcoindBackend( + t, p2pAddr, true, true, ) newNotifier = func() (chainntnfs.TestChainNotifier, error) { return bitcoindnotify.New( diff --git a/chainntnfs/test_utils.go b/chainntnfs/test_utils.go index fb5212aa5..65eaeb072 100644 --- a/chainntnfs/test_utils.go +++ b/chainntnfs/test_utils.go @@ -26,6 +26,7 @@ import ( "github.com/btcsuite/btcwallet/walletdb" "github.com/lightninglabs/neutrino" "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/lntest/wait" ) var ( @@ -193,10 +194,12 @@ func NewMiner(t *testing.T, extraArgs []string, createChain bool, // NewBitcoindBackend spawns a new bitcoind node that connects to a miner at the // specified address. The txindex boolean can be set to determine whether the -// backend node should maintain a transaction index. A connection to the newly -// spawned bitcoind node is returned. -func NewBitcoindBackend(t *testing.T, minerAddr string, - txindex bool) (*chain.BitcoindConn, func()) { +// backend node should maintain a transaction index. The rpcpolling boolean +// can be set to determine whether bitcoind's RPC polling interface should be +// used for block and tx notifications or if its ZMQ interface should be used. +// A connection to the newly spawned bitcoind node is returned. +func NewBitcoindBackend(t *testing.T, minerAddr string, txindex, + rpcpolling bool) (*chain.BitcoindConn, func()) { t.Helper() @@ -231,31 +234,41 @@ func NewBitcoindBackend(t *testing.T, minerAddr string, } // Wait for the bitcoind instance to start up. - time.Sleep(time.Second) - host := fmt.Sprintf("127.0.0.1:%d", rpcPort) - conn, err := chain.NewBitcoindConn(&chain.BitcoindConfig{ + cfg := &chain.BitcoindConfig{ ChainParams: NetParams, Host: host, User: "weks", Pass: "weks", - ZMQConfig: &chain.ZMQConfig{ - ZMQBlockHost: zmqBlockHost, - ZMQTxHost: zmqTxHost, - ZMQReadDeadline: 5 * time.Second, - }, // Fields only required for pruned nodes, not needed for these // tests. Dialer: nil, PrunedModeMaxPeers: 0, - }) - if err != nil { - bitcoind.Process.Kill() - bitcoind.Wait() - os.RemoveAll(tempBitcoindDir) - t.Fatalf("unable to establish connection to bitcoind: %v", err) } - if err := conn.Start(); err != nil { + + if rpcpolling { + cfg.ZMQConfig = &chain.ZMQConfig{ + ZMQBlockHost: zmqBlockHost, + ZMQTxHost: zmqTxHost, + ZMQReadDeadline: 5 * time.Second, + } + } else { + cfg.PollingConfig = &chain.PollingConfig{ + BlockPollingInterval: time.Millisecond * 20, + TxPollingInterval: time.Millisecond * 20, + } + } + + var conn *chain.BitcoindConn + err = wait.NoError(func() error { + conn, err = chain.NewBitcoindConn(cfg) + if err != nil { + return err + } + + return conn.Start() + }, 10*time.Second) + if err != nil { bitcoind.Process.Kill() bitcoind.Wait() os.RemoveAll(tempBitcoindDir)