-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[itests] Bitcoind integration test #1583
Changes from all commits
35f3544
45d41dc
a57b3de
857a2c3
168fc4e
c3480c6
d7f0372
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
// +build bitcoind | ||
|
||
package lntest | ||
|
||
import ( | ||
"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. | ||
func NewBackend(miner string, netParams *chaincfg.Params) ( | ||
*BitcoindBackendConfig, func(), 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") | ||
wpaulino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we run without this? Would ensure that the fallback path (no txindex, scan manually) is tested instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could run it with both options, though this would significantly increase the running time of the current integration tests. On the other hand, we properly test both variants in the unit tests of the notifier. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could randomize it lol |
||
"-whitelist=127.0.0.1", // whitelist localhost to speed up relay | ||
wpaulino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"-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() { | ||
bitcoind.Process.Kill() | ||
bitcoind.Wait() | ||
|
||
// 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 { | ||
fmt.Printf("unable to copy file: %v\n", err) | ||
} | ||
if err = os.RemoveAll(logDir); err != nil { | ||
fmt.Printf("Cannot remove dir %s: %v\n", logDir, err) | ||
} | ||
|
||
os.RemoveAll(tempBitcoindDir) | ||
} | ||
|
||
// 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) | ||
} | ||
|
||
// We start by adding the miner to the bitcoind addnode list. We do | ||
// this instead of connecting using command line flags, because it will | ||
// allow us to disconnect the miner using the AddNode command later. | ||
if err := client.AddNode(miner, rpcclient.ANAdd); err != nil { | ||
cleanUp() | ||
return nil, nil, fmt.Errorf("unable to add node: %v", err) | ||
} | ||
|
||
bd := BitcoindBackendConfig{ | ||
rpcHost: rpcHost, | ||
rpcUser: rpcUser, | ||
rpcPass: rpcPass, | ||
zmqBlockPath: zmqBlockPath, | ||
zmqTxPath: zmqTxPath, | ||
p2pPort: p2pPort, | ||
rpcClient: client, | ||
minerAddr: miner, | ||
} | ||
|
||
return &bd, cleanUp, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, this is defined elsewhere already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is re-defined since it is behind a different build flag.