lntest: extract common bitcoind code into own file

To prepare for running multiple tests on bitcoind with different options
each time, we extract the common code into its own file.
This commit is contained in:
Oliver Gugger 2020-10-09 13:35:00 +02:00
parent 902d7dd812
commit 43c2031fa8
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
2 changed files with 193 additions and 171 deletions

@ -3,187 +3,20 @@
package lntest
import (
"errors"
"fmt"
"io/ioutil"
"math/rand"
"os"
"os/exec"
"path/filepath"
"time"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/rpcclient"
)
// logDir is the name of the temporary log directory.
const logDir = "./.backendlogs"
// BitcoindBackendConfig is an implementation of the BackendConfig interface
// backed by a Bitcoind node.
type BitcoindBackendConfig struct {
rpcHost string
rpcUser string
rpcPass string
zmqBlockPath string
zmqTxPath string
p2pPort int
rpcClient *rpcclient.Client
// minerAddr is the p2p address of the miner to connect to.
minerAddr string
}
// A compile time assertion to ensure BitcoindBackendConfig meets the
// BackendConfig interface.
var _ BackendConfig = (*BitcoindBackendConfig)(nil)
// GenArgs returns the arguments needed to be passed to LND at startup for
// using this node as a chain backend.
func (b BitcoindBackendConfig) GenArgs() []string {
var args []string
args = append(args, "--bitcoin.node=bitcoind")
args = append(args, fmt.Sprintf("--bitcoind.rpchost=%v", b.rpcHost))
args = append(args, fmt.Sprintf("--bitcoind.rpcuser=%v", b.rpcUser))
args = append(args, fmt.Sprintf("--bitcoind.rpcpass=%v", b.rpcPass))
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawblock=%v",
b.zmqBlockPath))
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawtx=%v",
b.zmqTxPath))
return args
}
// ConnectMiner is called to establish a connection to the test miner.
func (b BitcoindBackendConfig) ConnectMiner() error {
return b.rpcClient.AddNode(b.minerAddr, rpcclient.ANAdd)
}
// DisconnectMiner is called to disconnect the miner.
func (b BitcoindBackendConfig) DisconnectMiner() error {
return b.rpcClient.AddNode(b.minerAddr, rpcclient.ANRemove)
}
// Name returns the name of the backend type.
func (b BitcoindBackendConfig) Name() string {
return "bitcoind"
}
// NewBackend starts a bitcoind node and returns a BitoindBackendConfig for
// that node.
// NewBackend starts a bitcoind node with the txindex enabled and returns a
// BitcoindBackendConfig for that node.
func NewBackend(miner string, netParams *chaincfg.Params) (
*BitcoindBackendConfig, func() error, error) {
if netParams != &chaincfg.RegressionNetParams {
return nil, nil, fmt.Errorf("only regtest supported")
}
if err := os.MkdirAll(logDir, 0700); err != nil {
return nil, nil, err
}
logFile, err := filepath.Abs(logDir + "/bitcoind.log")
if err != nil {
return nil, nil, err
}
tempBitcoindDir, err := ioutil.TempDir("", "bitcoind")
if err != nil {
return nil, nil,
fmt.Errorf("unable to create temp directory: %v", err)
}
zmqBlockPath := "ipc:///" + tempBitcoindDir + "/blocks.socket"
zmqTxPath := "ipc:///" + tempBitcoindDir + "/txs.socket"
rpcPort := rand.Int()%(65536-1024) + 1024
p2pPort := rand.Int()%(65536-1024) + 1024
bitcoind := exec.Command(
"bitcoind",
"-datadir="+tempBitcoindDir,
extraArgs := []string{
"-debug",
"-regtest",
"-txindex",
"-whitelist=127.0.0.1", // whitelist localhost to speed up relay
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
fmt.Sprintf("-port=%d", p2pPort),
"-disablewallet",
"-zmqpubrawblock="+zmqBlockPath,
"-zmqpubrawtx="+zmqTxPath,
"-debuglogfile="+logFile,
)
err = bitcoind.Start()
if err != nil {
os.RemoveAll(tempBitcoindDir)
return nil, nil, fmt.Errorf("couldn't start bitcoind: %v", err)
}
cleanUp := func() error {
bitcoind.Process.Kill()
bitcoind.Wait()
var errStr string
// After shutting down the chain backend, we'll make a copy of
// the log file before deleting the temporary log dir.
err := CopyFile("./output_bitcoind_chainbackend.log", logFile)
if err != nil {
errStr += fmt.Sprintf("unable to copy file: %v\n", err)
}
if err = os.RemoveAll(logDir); err != nil {
errStr += fmt.Sprintf(
"cannot remove dir %s: %v\n", logDir, err,
)
}
if err := os.RemoveAll(tempBitcoindDir); err != nil {
errStr += fmt.Sprintf(
"cannot remove dir %s: %v\n",
tempBitcoindDir, err,
)
}
if errStr != "" {
return errors.New(errStr)
}
return nil
}
// Allow process to start.
time.Sleep(1 * time.Second)
rpcHost := fmt.Sprintf("127.0.0.1:%d", rpcPort)
rpcUser := "weks"
rpcPass := "weks"
rpcCfg := rpcclient.ConnConfig{
Host: rpcHost,
User: rpcUser,
Pass: rpcPass,
DisableConnectOnNew: true,
DisableAutoReconnect: false,
DisableTLS: true,
HTTPPostMode: true,
}
client, err := rpcclient.New(&rpcCfg, nil)
if err != nil {
cleanUp()
return nil, nil, fmt.Errorf("unable to create rpc client: %v",
err)
}
bd := BitcoindBackendConfig{
rpcHost: rpcHost,
rpcUser: rpcUser,
rpcPass: rpcPass,
zmqBlockPath: zmqBlockPath,
zmqTxPath: zmqTxPath,
p2pPort: p2pPort,
rpcClient: client,
minerAddr: miner,
}
return &bd, cleanUp, nil
return newBackend(miner, netParams, extraArgs)
}

189
lntest/bitcoind_common.go Normal file

@ -0,0 +1,189 @@
// +build bitcoind
package lntest
import (
"errors"
"fmt"
"io/ioutil"
"math/rand"
"os"
"os/exec"
"path/filepath"
"time"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/rpcclient"
)
// logDir is the name of the temporary log directory.
const logDir = "./.backendlogs"
// BitcoindBackendConfig is an implementation of the BackendConfig interface
// backed by a Bitcoind node.
type BitcoindBackendConfig struct {
rpcHost string
rpcUser string
rpcPass string
zmqBlockPath string
zmqTxPath string
p2pPort int
rpcClient *rpcclient.Client
// minerAddr is the p2p address of the miner to connect to.
minerAddr string
}
// A compile time assertion to ensure BitcoindBackendConfig meets the
// BackendConfig interface.
var _ BackendConfig = (*BitcoindBackendConfig)(nil)
// GenArgs returns the arguments needed to be passed to LND at startup for
// using this node as a chain backend.
func (b BitcoindBackendConfig) GenArgs() []string {
var args []string
args = append(args, "--bitcoin.node=bitcoind")
args = append(args, fmt.Sprintf("--bitcoind.rpchost=%v", b.rpcHost))
args = append(args, fmt.Sprintf("--bitcoind.rpcuser=%v", b.rpcUser))
args = append(args, fmt.Sprintf("--bitcoind.rpcpass=%v", b.rpcPass))
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawblock=%v",
b.zmqBlockPath))
args = append(args, fmt.Sprintf("--bitcoind.zmqpubrawtx=%v",
b.zmqTxPath))
return args
}
// ConnectMiner is called to establish a connection to the test miner.
func (b BitcoindBackendConfig) ConnectMiner() error {
return b.rpcClient.AddNode(b.minerAddr, rpcclient.ANAdd)
}
// DisconnectMiner is called to disconnect the miner.
func (b BitcoindBackendConfig) DisconnectMiner() error {
return b.rpcClient.AddNode(b.minerAddr, rpcclient.ANRemove)
}
// Name returns the name of the backend type.
func (b BitcoindBackendConfig) Name() string {
return "bitcoind"
}
// newBackend starts a bitcoind node with the given extra parameters and returns
// a BitcoindBackendConfig for that node.
func newBackend(miner string, netParams *chaincfg.Params, _ []string) (
*BitcoindBackendConfig, func() error, error) {
if netParams != &chaincfg.RegressionNetParams {
return nil, nil, fmt.Errorf("only regtest supported")
}
if err := os.MkdirAll(logDir, 0700); err != nil {
return nil, nil, err
}
logFile, err := filepath.Abs(logDir + "/bitcoind.log")
if err != nil {
return nil, nil, err
}
tempBitcoindDir, err := ioutil.TempDir("", "bitcoind")
if err != nil {
return nil, nil,
fmt.Errorf("unable to create temp directory: %v", err)
}
zmqBlockPath := "ipc:///" + tempBitcoindDir + "/blocks.socket"
zmqTxPath := "ipc:///" + tempBitcoindDir + "/txs.socket"
rpcPort := rand.Int()%(65536-1024) + 1024
p2pPort := rand.Int()%(65536-1024) + 1024
bitcoind := exec.Command(
"bitcoind",
"-datadir="+tempBitcoindDir,
"-debug",
"-regtest",
"-txindex",
"-whitelist=127.0.0.1", // whitelist localhost to speed up relay
"-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6f"+
"d$507c670e800a95284294edb5773b05544b"+
"220110063096c221be9933c82d38e1",
fmt.Sprintf("-rpcport=%d", rpcPort),
fmt.Sprintf("-port=%d", p2pPort),
"-disablewallet",
"-zmqpubrawblock="+zmqBlockPath,
"-zmqpubrawtx="+zmqTxPath,
"-debuglogfile="+logFile,
)
err = bitcoind.Start()
if err != nil {
os.RemoveAll(tempBitcoindDir)
return nil, nil, fmt.Errorf("couldn't start bitcoind: %v", err)
}
cleanUp := func() error {
bitcoind.Process.Kill()
bitcoind.Wait()
var errStr string
// After shutting down the chain backend, we'll make a copy of
// the log file before deleting the temporary log dir.
err := CopyFile("./output_bitcoind_chainbackend.log", logFile)
if err != nil {
errStr += fmt.Sprintf("unable to copy file: %v\n", err)
}
if err = os.RemoveAll(logDir); err != nil {
errStr += fmt.Sprintf(
"cannot remove dir %s: %v\n", logDir, err,
)
}
if err := os.RemoveAll(tempBitcoindDir); err != nil {
errStr += fmt.Sprintf(
"cannot remove dir %s: %v\n",
tempBitcoindDir, err,
)
}
if errStr != "" {
return errors.New(errStr)
}
return nil
}
// Allow process to start.
time.Sleep(1 * time.Second)
rpcHost := fmt.Sprintf("127.0.0.1:%d", rpcPort)
rpcUser := "weks"
rpcPass := "weks"
rpcCfg := rpcclient.ConnConfig{
Host: rpcHost,
User: rpcUser,
Pass: rpcPass,
DisableConnectOnNew: true,
DisableAutoReconnect: false,
DisableTLS: true,
HTTPPostMode: true,
}
client, err := rpcclient.New(&rpcCfg, nil)
if err != nil {
cleanUp()
return nil, nil, fmt.Errorf("unable to create rpc client: %v",
err)
}
bd := BitcoindBackendConfig{
rpcHost: rpcHost,
rpcUser: rpcUser,
rpcPass: rpcPass,
zmqBlockPath: zmqBlockPath,
zmqTxPath: zmqTxPath,
p2pPort: p2pPort,
rpcClient: client,
minerAddr: miner,
}
return &bd, cleanUp, nil
}