lnwallet+routing: use chainntnfs.NewBitcoindBackend

Since we fixed a number of issues in chainntnfs.NewBitcoindBackend that
makes it compatible with bitcoind v26.0, we now want to use that
function in all our unit tests.
This commit is contained in:
Oliver Gugger 2024-03-15 12:54:37 +01:00
parent d40312c36b
commit aa811c784a
No known key found for this signature in database
GPG key ID: 8E4256593F177720
2 changed files with 35 additions and 373 deletions

View file

@ -6,12 +6,10 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"net" "net"
"os/exec"
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"strings" "strings"
"sync/atomic"
"testing" "testing"
"time" "time"
@ -41,7 +39,6 @@ import (
"github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/labels" "github.com/lightningnetwork/lnd/labels"
"github.com/lightningnetwork/lnd/lntest/unittest" "github.com/lightningnetwork/lnd/lntest/unittest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwallet/chainfee"
@ -97,35 +94,6 @@ var (
defaultMaxLocalCsvDelay uint16 = 10000 defaultMaxLocalCsvDelay uint16 = 10000
) )
var (
// lastPort is the last port determined to be free for use by a new
// bitcoind server. It should be used atomically.
lastPort uint32 = 1024
)
// getFreePort returns the first port that is available for listening by a new
// embedded etcd server. It panics if no port is found and the maximum available
// TCP port is reached.
func getFreePort() int {
port := atomic.AddUint32(&lastPort, 1)
for port < 65535 {
// If there are no errors while attempting to listen on this
// port, close the socket and return it as available.
addr := fmt.Sprintf("127.0.0.1:%d", port)
l, err := net.Listen("tcp4", addr)
if err == nil {
err := l.Close()
if err == nil {
return int(port)
}
}
port = atomic.AddUint32(&lastPort, 1)
}
// No ports available? Must be a mistake.
panic("no ports available for listening")
}
// assertProperBalance asserts than the total value of the unspent outputs // assertProperBalance asserts than the total value of the unspent outputs
// within the wallet are *exactly* amount. If unable to retrieve the current // within the wallet are *exactly* amount. If unable to retrieve the current
// balance, or the assertion fails, the test will halt with a fatal error. // balance, or the assertion fails, the test will halt with a fatal error.
@ -3182,15 +3150,19 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
var aliceClient, bobClient chain.Interface var aliceClient, bobClient chain.Interface
switch backEnd { switch backEnd {
case "btcd": case "btcd":
aliceClient, err = chain.NewRPCClient(netParams, aliceClient, err = chain.NewRPCClient(
rpcConfig.Host, rpcConfig.User, rpcConfig.Pass, netParams, rpcConfig.Host, rpcConfig.User,
rpcConfig.Certificates, false, 20) rpcConfig.Pass, rpcConfig.Certificates, false,
20,
)
if err != nil { if err != nil {
t.Fatalf("unable to make chain rpc: %v", err) t.Fatalf("unable to make chain rpc: %v", err)
} }
bobClient, err = chain.NewRPCClient(netParams, bobClient, err = chain.NewRPCClient(
rpcConfig.Host, rpcConfig.User, rpcConfig.Pass, netParams, rpcConfig.Host, rpcConfig.User,
rpcConfig.Certificates, false, 20) rpcConfig.Pass, rpcConfig.Certificates, false,
20,
)
if err != nil { if err != nil {
t.Fatalf("unable to make chain rpc: %v", err) t.Fatalf("unable to make chain rpc: %v", err)
} }
@ -3262,78 +3234,10 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
case "bitcoind": case "bitcoind":
// Start a bitcoind instance. // Start a bitcoind instance.
tempBitcoindDir := t.TempDir() chainConn := unittest.NewBitcoindBackend(
t, unittest.NetParams, miningNode.P2PAddress(),
rpcPort := getFreePort() true, false,
zmqBlockPort := getFreePort()
zmqTxPort := getFreePort()
zmqBlockHost := fmt.Sprintf("tcp://127.0.0.1:%d",
zmqBlockPort)
zmqTxHost := fmt.Sprintf("tcp://127.0.0.1:%d",
zmqTxPort)
bitcoind := exec.Command(
"bitcoind",
"-datadir="+tempBitcoindDir,
"-regtest",
"-connect="+miningNode.P2PAddress(),
"-txindex",
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
"-disablewallet",
"-zmqpubrawblock="+zmqBlockHost,
"-zmqpubrawtx="+zmqTxHost,
) )
err = bitcoind.Start()
if err != nil {
t.Fatalf("couldn't start bitcoind: %v", err)
}
// Sanity check to ensure that the process did in fact
// start.
if bitcoind.Process == nil {
t.Fatalf("bitcoind cmd Process is not set " +
"after Start")
}
defer func() {
_ = bitcoind.Process.Kill()
_ = bitcoind.Wait()
}()
// Wait for the bitcoind instance to start up.
host := fmt.Sprintf("127.0.0.1:%d", rpcPort)
var chainConn *chain.BitcoindConn
err = wait.NoError(func() error {
chainConn, err = chain.NewBitcoindConn(&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 {
return err
}
return chainConn.Start()
}, 10*time.Second)
if err != nil {
t.Fatalf("unable to establish connection to "+
"bitcoind: %v", err)
}
defer chainConn.Stop()
// Create a btcwallet bitcoind client for both Alice and // Create a btcwallet bitcoind client for both Alice and
// Bob. // Bob.
@ -3342,65 +3246,10 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
case "bitcoind-rpc-polling": case "bitcoind-rpc-polling":
// Start a bitcoind instance. // Start a bitcoind instance.
tempBitcoindDir := t.TempDir() chainConn := unittest.NewBitcoindBackend(
rpcPort := getFreePort() t, unittest.NetParams, miningNode.P2PAddress(),
bitcoind := exec.Command( true, true,
"bitcoind",
"-datadir="+tempBitcoindDir,
"-regtest",
"-connect="+miningNode.P2PAddress(),
"-txindex",
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
"-disablewallet",
) )
err = bitcoind.Start()
if err != nil {
t.Fatalf("couldn't start bitcoind: %v", err)
}
defer func() {
_ = bitcoind.Process.Kill()
_ = bitcoind.Wait()
}()
// Sanity check to ensure that the process did in fact
// start.
if bitcoind.Process == nil {
t.Fatalf("bitcoind cmd Process is not set " +
"after Start")
}
// Wait for the bitcoind instance to start up.
host := fmt.Sprintf("127.0.0.1:%d", rpcPort)
var chainConn *chain.BitcoindConn
err = wait.NoError(func() error {
chainConn, err = chain.NewBitcoindConn(&chain.BitcoindConfig{
ChainParams: netParams,
Host: host,
User: "weks",
Pass: "weks",
PollingConfig: &chain.PollingConfig{
BlockPollingInterval: time.Millisecond * 20,
TxPollingInterval: time.Millisecond * 20,
},
// Fields only required for pruned nodes, not
// needed for these tests.
Dialer: nil,
PrunedModeMaxPeers: 0,
})
if err != nil {
return err
}
return chainConn.Start()
}, 10*time.Second)
if err != nil {
t.Fatalf("unable to establish connection to "+
"bitcoind: %v", err)
}
defer chainConn.Stop()
// Create a btcwallet bitcoind client for both Alice and // Create a btcwallet bitcoind client for both Alice and
// Bob. // Bob.

View file

@ -3,11 +3,8 @@ package chainview
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"net"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sync/atomic"
"testing" "testing"
"time" "time"
@ -20,7 +17,6 @@ import (
"github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/chain"
"github.com/btcsuite/btcwallet/walletdb" "github.com/btcsuite/btcwallet/walletdb"
_ "github.com/btcsuite/btcwallet/walletdb/bdb" // Required to register the boltdb walletdb implementation. _ "github.com/btcsuite/btcwallet/walletdb/bdb" // Required to register the boltdb walletdb implementation.
"github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino"
@ -50,35 +46,6 @@ var (
testScript, _ = txscript.PayToAddrScript(testAddr) testScript, _ = txscript.PayToAddrScript(testAddr)
) )
var (
// lastPort is the last port determined to be free for use by a new
// bitcoind server. It should be used atomically.
lastPort uint32 = 1024
)
// getFreePort returns the first port that is available for listening by a new
// embedded etcd server. It panics if no port is found and the maximum available
// TCP port is reached.
func getFreePort() int {
port := atomic.AddUint32(&lastPort, 1)
for port < 65535 {
// If there are no errors while attempting to listen on this
// port, close the socket and return it as available.
addr := fmt.Sprintf("127.0.0.1:%d", port)
l, err := net.Listen("tcp4", addr)
if err == nil {
err := l.Close()
if err == nil {
return int(port)
}
}
port = atomic.AddUint32(&lastPort, 1)
}
// No ports available? Must be a mistake.
panic("no ports available for listening")
}
func waitForMempoolTx(r *rpctest.Harness, txid *chainhash.Hash) error { func waitForMempoolTx(r *rpctest.Harness, txid *chainhash.Hash) error {
var found bool var found bool
var tx *btcutil.Tx var tx *btcutil.Tx
@ -221,8 +188,10 @@ func testFilterBlockNotifications(node *rpctest.Harness,
// filtered transaction as the filter hasn't been update. // filtered transaction as the filter hasn't been update.
select { select {
case filteredBlock := <-blockChan: case filteredBlock := <-blockChan:
assertFilteredBlock(t, filteredBlock, currentHeight, assertFilteredBlock(
newBlockHashes[0], []*chainhash.Hash{}) t, filteredBlock, currentHeight,
newBlockHashes[0], []*chainhash.Hash{},
)
case <-time.After(time.Second * 20): case <-time.After(time.Second * 20):
t.Fatalf("filtered block notification didn't arrive") t.Fatalf("filtered block notification didn't arrive")
} }
@ -697,95 +666,14 @@ var interfaceImpls = []struct {
{ {
name: "bitcoind_zmq", name: "bitcoind_zmq",
chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig, chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig,
p2pAddr string, bestHeight int32) (FilteredChainView, error) { p2pAddr string, bestHeight int32) (FilteredChainView,
error) {
// Start a bitcoind instance. // Start a bitcoind instance.
tempBitcoindDir := t.TempDir() chainConn := unittest.NewBitcoindBackend(
zmqBlockHost := "ipc:///" + tempBitcoindDir + "/blocks.socket" t, unittest.NetParams, p2pAddr, true,
zmqTxHost := "ipc:///" + tempBitcoindDir + "/tx.socket" false,
rpcPort := getFreePort()
bitcoind := exec.Command(
"bitcoind",
"-datadir="+tempBitcoindDir,
"-regtest",
"-connect="+p2pAddr,
"-txindex",
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
"-disablewallet",
"-zmqpubrawblock="+zmqBlockHost,
"-zmqpubrawtx="+zmqTxHost,
) )
err := bitcoind.Start()
if err != nil {
return nil, err
}
// Sanity check to ensure that the process did in fact
// start.
if bitcoind.Process == nil {
return nil, fmt.Errorf("bitcoind cmd " +
"Process is not set after Start")
}
t.Cleanup(func() {
_ = bitcoind.Process.Kill()
_ = bitcoind.Wait()
})
host := fmt.Sprintf("127.0.0.1:%d", rpcPort)
cfg := &chain.BitcoindConfig{
ChainParams: &chaincfg.RegressionNetParams,
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,
}
var chainConn *chain.BitcoindConn
err = wait.NoError(func() error {
chainConn, err = chain.NewBitcoindConn(cfg)
if err != nil {
return err
}
err = chainConn.Start()
if err != nil {
return err
}
client := chainConn.NewBitcoindClient()
_, currentHeight, err := client.GetBestBlock()
if err != nil {
return err
}
if currentHeight < bestHeight {
return fmt.Errorf("not synced yet")
}
return nil
}, 10*time.Second)
if err != nil {
return nil, fmt.Errorf("unable to "+
"establish connection to bitcoind: %v",
err)
}
t.Cleanup(func() {
chainConn.Stop()
})
blockCache := blockcache.NewBlockCache(10000) blockCache := blockcache.NewBlockCache(10000)
chainView := NewBitcoindFilteredChainView( chainView := NewBitcoindFilteredChainView(
@ -798,91 +686,14 @@ var interfaceImpls = []struct {
{ {
name: "bitcoind_polling", name: "bitcoind_polling",
chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig, chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig,
p2pAddr string, bestHeight int32) (FilteredChainView, error) { p2pAddr string, bestHeight int32) (FilteredChainView,
error) {
// Start a bitcoind instance.
tempBitcoindDir := t.TempDir()
rpcPort := getFreePort()
bitcoind := exec.Command(
"bitcoind",
"-datadir="+tempBitcoindDir,
"-regtest",
"-connect="+p2pAddr,
"-txindex",
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
"-disablewallet",
)
err := bitcoind.Start()
if err != nil {
return nil, err
}
// Sanity check to ensure that the process did in fact
// start.
if bitcoind.Process == nil {
return nil, fmt.Errorf("bitcoind cmd " +
"Process is not set after Start")
}
t.Cleanup(func() {
_ = bitcoind.Process.Kill()
_ = bitcoind.Wait()
})
host := fmt.Sprintf("127.0.0.1:%d", rpcPort)
cfg := &chain.BitcoindConfig{
ChainParams: &chaincfg.RegressionNetParams,
Host: host,
User: "weks",
Pass: "weks",
PollingConfig: &chain.PollingConfig{
BlockPollingInterval: time.Millisecond * 100,
TxPollingInterval: time.Millisecond * 100,
},
// Fields only required for pruned nodes, not
// needed for these tests.
Dialer: nil,
PrunedModeMaxPeers: 0,
}
// Wait for the bitcoind instance to start up. // Wait for the bitcoind instance to start up.
var chainConn *chain.BitcoindConn chainConn := unittest.NewBitcoindBackend(
err = wait.NoError(func() error { t, unittest.NetParams, p2pAddr, true,
chainConn, err = chain.NewBitcoindConn(cfg) true,
if err != nil { )
return err
}
err = chainConn.Start()
if err != nil {
return err
}
client := chainConn.NewBitcoindClient()
_, currentHeight, err := client.GetBestBlock()
if err != nil {
return err
}
if currentHeight < bestHeight {
return fmt.Errorf("not synced yet")
}
return nil
}, 10*time.Second)
if err != nil {
return nil, fmt.Errorf("unable to "+
"establish connection to bitcoind: %v",
err)
}
t.Cleanup(func() {
chainConn.Stop()
})
blockCache := blockcache.NewBlockCache(10000) blockCache := blockcache.NewBlockCache(10000)
chainView := NewBitcoindFilteredChainView( chainView := NewBitcoindFilteredChainView(
@ -895,7 +706,8 @@ var interfaceImpls = []struct {
{ {
name: "p2p_neutrino", name: "p2p_neutrino",
chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig, chainViewInit: func(t *testing.T, _ rpcclient.ConnConfig,
p2pAddr string, bestHeight int32) (FilteredChainView, error) { p2pAddr string, bestHeight int32) (FilteredChainView,
error) {
spvDir := t.TempDir() spvDir := t.TempDir()
@ -964,7 +776,8 @@ var interfaceImpls = []struct {
{ {
name: "btcd_websockets", name: "btcd_websockets",
chainViewInit: func(_ *testing.T, config rpcclient.ConnConfig, chainViewInit: func(_ *testing.T, config rpcclient.ConnConfig,
p2pAddr string, bestHeight int32) (FilteredChainView, error) { p2pAddr string, bestHeight int32) (FilteredChainView,
error) {
blockCache := blockcache.NewBlockCache(10000) blockCache := blockcache.NewBlockCache(10000)
chainView, err := NewBtcdFilteredChainView( chainView, err := NewBtcdFilteredChainView(