Merge pull request #4765 from guggero/itest-miner-fix

Update btcd to master, make itest btcd harness more robust
This commit is contained in:
Conner Fromknecht 2020-12-03 16:19:58 -08:00 committed by GitHub
commit 3e1ba20370
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 110 additions and 79 deletions

1
.gitignore vendored

@ -36,6 +36,7 @@ lntest/itest/*.log
lntest/itest/.backendlogs
lntest/itest/.minerlogs
lntest/itest/lnd-itest
lntest/itest/btcd-itest
lntest/itest/.logs-*
cmd/cmd

@ -73,7 +73,7 @@ jobs:
- name: Btcd Integration Windows
script:
- make itest-parallel-windows
- make itest-parallel windows=1
os: windows
before_install:
- choco upgrade --no-progress -y make netcat curl findutils

@ -20,7 +20,6 @@ GOACC_BIN := $(GO_BIN)/go-acc
GOFUZZ_BUILD_BIN := $(GO_BIN)/go-fuzz-build
GOFUZZ_BIN := $(GO_BIN)/go-fuzz
BTCD_DIR :=${GOPATH}/src/$(BTCD_PKG)
MOBILE_BUILD_DIR :=${GOPATH}/src/$(MOBILE_PKG)/build
IOS_BUILD_DIR := $(MOBILE_BUILD_DIR)/ios
IOS_BUILD := $(IOS_BUILD_DIR)/Lndmobile.framework
@ -32,7 +31,7 @@ COMMIT_HASH := $(shell git rev-parse HEAD)
BTCD_COMMIT := $(shell cat go.mod | \
grep $(BTCD_PKG) | \
tail -n1 | \
head -n1 | \
awk -F " " '{ print $$2 }' | \
awk -F "/" '{ print $$1 }')
@ -140,14 +139,12 @@ build:
$(GOBUILD) -tags="$(DEV_TAGS)" -o lncli-debug $(DEV_LDFLAGS) $(PKG)/cmd/lncli
build-itest:
@$(call print, "Building itest lnd and lncli.")
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lnd-itest $(ITEST_LDFLAGS) $(PKG)/cmd/lnd
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lncli-itest $(ITEST_LDFLAGS) $(PKG)/cmd/lncli
@$(call print, "Building itest btcd and lnd.")
CGO_ENABLED=0 $(GOBUILD) -tags="rpctest" -o lntest/itest/btcd-itest$(EXEC_SUFFIX) $(ITEST_LDFLAGS) $(BTCD_PKG)
CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o lntest/itest/lnd-itest$(EXEC_SUFFIX) $(ITEST_LDFLAGS) $(PKG)/cmd/lnd
build-itest-windows:
@$(call print, "Building itest lnd and lncli.")
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lnd-itest.exe $(ITEST_LDFLAGS) $(PKG)/cmd/lnd
$(GOBUILD) -tags="$(ITEST_TAGS)" -o lncli-itest.exe $(ITEST_LDFLAGS) $(PKG)/cmd/lncli
@$(call print, "Building itest binary for ${backend} backend.")
CGO_ENABLED=0 $(GOTEST) -v ./lntest/itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -c -o lntest/itest/itest.test$(EXEC_SUFFIX)
install:
@$(call print, "Installing lnd and lncli.")
@ -170,33 +167,17 @@ check: unit itest
itest-only:
@$(call print, "Running integration tests with ${backend} backend.")
$(ITEST)
rm -rf lntest/itest/*.log lntest/itest/.logs-*; date
EXEC_SUFFIX=$(EXEC_SUFFIX) scripts/itest_part.sh 0 1 $(TEST_FLAGS) $(ITEST_FLAGS)
lntest/itest/log_check_errors.sh
itest: btcd build-itest itest-only
itest-parallel: btcd
@$(call print, "Building lnd binary")
CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o lntest/itest/lnd-itest $(ITEST_LDFLAGS) $(PKG)/cmd/lnd
@$(call print, "Building itest binary for $(backend) backend")
CGO_ENABLED=0 $(GOTEST) -v ./lntest/itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -logoutput -goroutinedump -c -o lntest/itest/itest.test
itest: build-itest itest-only
itest-parallel: build-itest
@$(call print, "Running tests")
rm -rf lntest/itest/*.log lntest/itest/.logs-*
echo "$$(seq 0 $$(expr $(ITEST_PARALLELISM) - 1))" | xargs -P $(ITEST_PARALLELISM) -n 1 -I {} scripts/itest_part.sh {} $(NUM_ITEST_TRANCHES) $(TEST_FLAGS)
itest-parallel-windows: btcd
@$(call print, "Building lnd binary")
CGO_ENABLED=0 $(GOBUILD) -tags="$(ITEST_TAGS)" -o lntest/itest/lnd-itest.exe $(ITEST_LDFLAGS) $(PKG)/cmd/lnd
@$(call print, "Building itest binary for $(backend) backend")
CGO_ENABLED=0 $(GOTEST) -v ./lntest/itest -tags="$(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)" -logoutput -goroutinedump -c -o lntest/itest/itest.test.exe
@$(call print, "Running tests")
EXEC_SUFFIX=".exe" echo "$$(seq 0 $$(expr $(ITEST_PARALLELISM) - 1))" | xargs -P $(ITEST_PARALLELISM) -n 1 -I {} scripts/itest_part.sh {} $(NUM_ITEST_TRANCHES) $(TEST_FLAGS)
itest-windows: btcd build-itest-windows itest-only
rm -rf lntest/itest/*.log lntest/itest/.logs-*; date
EXEC_SUFFIX=$(EXEC_SUFFIX) echo "$$(seq 0 $$(expr $(ITEST_PARALLELISM) - 1))" | xargs -P $(ITEST_PARALLELISM) -n 1 -I {} scripts/itest_part.sh {} $(NUM_ITEST_TRANCHES) $(TEST_FLAGS)
lntest/itest/log_check_errors.sh
unit: btcd
@$(call print, "Running unit tests.")
@ -226,7 +207,7 @@ travis-cover: btcd unit-cover goveralls
flakehunter: build-itest
@$(call print, "Flake hunting ${backend} integration tests.")
while [ $$? -eq 0 ]; do $(ITEST); done
while [ $$? -eq 0 ]; do make itest-only icase='${icase}' backend='${backend}'; done
flake-unit:
@$(call print, "Flake hunting unit tests.")

@ -1067,7 +1067,9 @@ func testReorgConf(miner *rpctest.Harness,
notifier chainntnfs.TestChainNotifier, scriptDispatch bool, t *testing.T) {
// Set up a new miner that we can use to cause a reorg.
miner2, err := rpctest.New(chainntnfs.NetParams, nil, []string{"--txindex"})
miner2, err := rpctest.New(
chainntnfs.NetParams, nil, []string{"--txindex"}, "",
)
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}
@ -1247,7 +1249,9 @@ func testReorgSpend(miner *rpctest.Harness,
}
// Set up a new miner that we can use to cause a reorg.
miner2, err := rpctest.New(chainntnfs.NetParams, nil, []string{"--txindex"})
miner2, err := rpctest.New(
chainntnfs.NetParams, nil, []string{"--txindex"}, "",
)
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}
@ -1592,7 +1596,9 @@ func testCatchUpOnMissedBlocksWithReorg(miner1 *rpctest.Harness,
var wg sync.WaitGroup
// Set up a new miner that we can use to cause a reorg.
miner2, err := rpctest.New(chainntnfs.NetParams, nil, []string{"--txindex"})
miner2, err := rpctest.New(
chainntnfs.NetParams, nil, []string{"--txindex"}, "",
)
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}

@ -177,7 +177,7 @@ func NewMiner(t *testing.T, extraArgs []string, createChain bool,
trickle := fmt.Sprintf("--trickleinterval=%v", TrickleInterval)
extraArgs = append(extraArgs, trickle)
node, err := rpctest.New(NetParams, nil, extraArgs)
node, err := rpctest.New(NetParams, nil, extraArgs, "")
if err != nil {
t.Fatalf("unable to create backend node: %v", err)
}

2
go.mod

@ -5,7 +5,7 @@ require (
github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e // indirect
github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82
github.com/Yawning/aez v0.0.0-20180114000226-4dad034d9db2
github.com/btcsuite/btcd v0.20.1-beta.0.20200903105316-61634447e719
github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcutil v1.0.2
github.com/btcsuite/btcutil/psbt v1.0.3-0.20200826194809-5f93e33af2b0

4
go.sum

@ -27,8 +27,8 @@ github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcug
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.20.1-beta.0.20200513120220-b470eee47728/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.20.1-beta.0.20200903105316-61634447e719 h1:EVCN2/T2EhbccMSuV3iM6cVcVVYSzmsx4EP3fWgdFGQ=
github.com/btcsuite/btcd v0.20.1-beta.0.20200903105316-61634447e719/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401 h1:0tjUthKCaF8zwF9Qg7lfnep0xdo4n8WiFUfQPaMHX6g=
github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=

@ -88,11 +88,19 @@ func NewBackend(miner string, netParams *chaincfg.Params) (
// make sure they stay connected if it happens.
"--nobanning",
}
chainBackend, err := rpctest.New(netParams, nil, args)
chainBackend, err := rpctest.New(netParams, nil, args, GetBtcdBinary())
if err != nil {
return nil, nil, fmt.Errorf("unable to create btcd node: %v", err)
}
// We want to overwrite some of the connection settings to make the
// tests more robust. We might need to restart the backend while there
// are already blocks present, which will take a bit longer than the
// 1 second the default settings amount to. Doubling both values will
// give us retries up to 4 seconds.
chainBackend.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2
chainBackend.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2
if err := chainBackend.SetUp(false, 0); err != nil {
return nil, nil, fmt.Errorf("unable to set up btcd backend: %v", err)
}

@ -2471,8 +2471,8 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) {
tempLogDir := fmt.Sprintf("%s/.tempminerlogs", lntest.GetLogDir())
logFilename := "output-open_channel_reorg-temp_miner.log"
tempMiner, tempMinerCleanUp, err := lntest.NewMiner(
tempLogDir, logFilename,
harnessNetParams, &rpcclient.NotificationHandlers{},
tempLogDir, logFilename, harnessNetParams,
&rpcclient.NotificationHandlers{}, lntest.GetBtcdBinary(),
)
require.NoError(t.t, err, "failed to create temp miner")
defer func() {
@ -14241,7 +14241,10 @@ func TestLightningNetworkDaemon(t *testing.T) {
testCases, trancheIndex, trancheOffset := getTestCaseSplitTranche()
lntest.ApplyPortOffset(uint32(trancheIndex) * 1000)
ht := newHarnessTest(t, nil)
// Before we start any node, we need to make sure that any btcd node
// that is started through the RPC harness uses a unique port as well to
// avoid any port collisions.
rpctest.ListenAddressGenerator = lntest.GenerateBtcdListenerAddresses
// Declare the network harness here to gain access to its
// 'OnTxAccepted' call back.
@ -14258,8 +14261,8 @@ func TestLightningNetworkDaemon(t *testing.T) {
// We will also connect it to our chain backend.
minerLogDir := fmt.Sprintf("%s/.minerlogs", logDir)
miner, minerCleanUp, err := lntest.NewMiner(
minerLogDir, "output_btcd_miner.log",
harnessNetParams, &rpcclient.NotificationHandlers{},
minerLogDir, "output_btcd_miner.log", harnessNetParams,
&rpcclient.NotificationHandlers{}, lntest.GetBtcdBinary(),
)
require.NoError(t, err, "failed to create new miner")
defer func() {
@ -14270,29 +14273,27 @@ func TestLightningNetworkDaemon(t *testing.T) {
chainBackend, cleanUp, err := lntest.NewBackend(
miner.P2PAddress(), harnessNetParams,
)
if err != nil {
ht.Fatalf("unable to start backend: %v", err)
}
require.NoError(t, err, "new backend")
defer func() {
require.NoError(
t, cleanUp(), "failed to clean up chain backend",
)
require.NoError(t, cleanUp(), "cleanup")
}()
if err := miner.SetUp(true, 50); err != nil {
ht.Fatalf("unable to set up mining node: %v", err)
}
if err := miner.Node.NotifyNewTransactions(false); err != nil {
ht.Fatalf("unable to request transaction notifications: %v", err)
}
// Before we start anything, we want to overwrite some of the connection
// settings to make the tests more robust. We might need to restart the
// miner while there are already blocks present, which will take a bit
// longer than the 1 second the default settings amount to. Doubling
// both values will give us retries up to 4 seconds.
miner.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2
miner.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2
// Connect chainbackend to miner.
require.NoError(
t, chainBackend.ConnectMiner(), "failed to connect to miner",
)
// Set up miner and connect chain backend to it.
require.NoError(t, miner.SetUp(true, 50))
require.NoError(t, miner.Node.NotifyNewTransactions(false))
require.NoError(t, chainBackend.ConnectMiner(), "connect miner")
// Now we can set up our test harness (LND instance), with the chain
// backend we just created.
ht := newHarnessTest(t, nil)
binary := ht.getLndBinary()
lndHarness, err = lntest.NewNetworkHarness(
miner, chainBackend, binary, *useEtcd,

@ -12,7 +12,6 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"sync"
"sync/atomic"
"time"
@ -54,6 +53,10 @@ const (
// trickleDelay is the amount of time in milliseconds between each
// release of announcements by AuthenticatedGossiper to the network.
trickleDelay = 50
// listenerFormat is the format string that is used to generate local
// listener addresses.
listenerFormat = "127.0.0.1:%d"
)
var (
@ -78,6 +81,11 @@ var (
// goroutines of test nodes on failure.
goroutineDump = flag.Bool("goroutinedump", false,
"write goroutine dump from node n to file pprof-n.log")
// btcdExecutable is the full path to the btcd binary.
btcdExecutable = flag.String(
"btcdexec", "", "full path to btcd binary",
)
)
// nextAvailablePort returns the first port that is available for listening by
@ -93,7 +101,7 @@ func nextAvailablePort() int {
// the harness node, in practice in CI servers this seems much
// less likely than simply some other process already being
// bound at the start of the tests.
addr := fmt.Sprintf("127.0.0.1:%d", port)
addr := fmt.Sprintf(listenerFormat, port)
l, err := net.Listen("tcp4", addr)
if err == nil {
err := l.Close()
@ -123,6 +131,24 @@ func GetLogDir() string {
return "."
}
// GetBtcdBinary returns the full path to the binary of the custom built btcd
// executable or an empty string if none is set.
func GetBtcdBinary() string {
if btcdExecutable != nil {
return *btcdExecutable
}
return ""
}
// GenerateBtcdListenerAddresses is a function that returns two listener
// addresses with unique ports and should be used to overwrite rpctest's default
// generator which is prone to use colliding ports.
func GenerateBtcdListenerAddresses() (string, string) {
return fmt.Sprintf(listenerFormat, nextAvailablePort()),
fmt.Sprintf(listenerFormat, nextAvailablePort())
}
// generateListeningPorts returns four ints representing ports to listen on
// designated for the current lightning network test. This returns the next
// available ports for the p2p, rpc, rest and profiling services.
@ -188,15 +214,15 @@ type NodeConfig struct {
}
func (cfg NodeConfig) P2PAddr() string {
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.P2PPort))
return fmt.Sprintf(listenerFormat, cfg.P2PPort)
}
func (cfg NodeConfig) RPCAddr() string {
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RPCPort))
return fmt.Sprintf(listenerFormat, cfg.RPCPort)
}
func (cfg NodeConfig) RESTAddr() string {
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RESTPort))
return fmt.Sprintf(listenerFormat, cfg.RESTPort)
}
// DBDir returns the holding directory path of the graph database.
@ -394,8 +420,8 @@ func newNode(cfg NodeConfig) (*HarnessNode, error) {
// miner node's log dir. When tests finished, during clean up, its logs are
// copied to a file specified as logFilename.
func NewMiner(logDir, logFilename string, netParams *chaincfg.Params,
handler *rpcclient.NotificationHandlers) (*rpctest.Harness,
func() error, error) {
handler *rpcclient.NotificationHandlers,
btcdBinary string) (*rpctest.Harness, func() error, error) {
args := []string{
"--rejectnonstd",
@ -407,7 +433,7 @@ func NewMiner(logDir, logFilename string, netParams *chaincfg.Params,
"--trickleinterval=100ms",
}
miner, err := rpctest.New(netParams, handler, args)
miner, err := rpctest.New(netParams, handler, args, btcdBinary)
if err != nil {
return nil, nil, fmt.Errorf(
"unable to create mining node: %v", err,

@ -2187,7 +2187,7 @@ func testReorgWalletBalance(r *rpctest.Harness, w *lnwallet.LightningWallet,
// Now we cause a reorganization as follows.
// Step 1: create a new miner and start it.
r2, err := rpctest.New(r.ActiveNet, nil, []string{"--txindex"})
r2, err := rpctest.New(r.ActiveNet, nil, []string{"--txindex"}, "")
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}
@ -3093,7 +3093,9 @@ func TestLightningWallet(t *testing.T) {
// dedicated miner to generate blocks, cause re-orgs, etc. We'll set
// up this node with a chain length of 125, so we have plenty of BTC
// to play around with.
miningNode, err := rpctest.New(netParams, nil, []string{"--txindex"})
miningNode, err := rpctest.New(
netParams, nil, []string{"--txindex"}, "",
)
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}

@ -3,6 +3,7 @@ RPC_TAGS = autopilotrpc chainrpc invoicesrpc routerrpc signrpc verrpc walletrpc
LOG_TAGS =
TEST_FLAGS =
ITEST_FLAGS =
EXEC_SUFFIX =
COVER_PKG = $$(go list -deps ./... | grep '$(PKG)' | grep -v lnrpc)
NUM_ITEST_TRANCHES = 6
ITEST_PARALLELISM = $(NUM_ITEST_TRANCHES)
@ -23,6 +24,12 @@ ifneq ($(parallel),)
ITEST_PARALLELISM = $(parallel)
endif
# Windows needs to append a .exe suffix to all executable files, otherwise it
# won't run them.
ifneq ($(windows),)
EXEC_SUFFIX = .exe
endif
# If specific package is being unit tested, construct the full name of the
# subpackage.
ifneq ($(pkg),)
@ -95,5 +102,3 @@ endif
# Construct the integration test command with the added build flags.
ITEST_TAGS := $(DEV_TAGS) $(RPC_TAGS) rpctest $(backend)
ITEST := rm -f lntest/itest/*.log; date; $(GOTEST) -v ./lntest/itest -tags="$(ITEST_TAGS)" $(TEST_FLAGS) $(ITEST_FLAGS) -logoutput -goroutinedump

@ -540,7 +540,7 @@ func testFilterBlockDisconnected(node *rpctest.Harness,
// Create a node that has a shorter chain than the main chain, so we
// can trigger a reorg.
reorgNode, err := rpctest.New(netParams, nil, []string{"--txindex"})
reorgNode, err := rpctest.New(netParams, nil, []string{"--txindex"}, "")
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}
@ -902,7 +902,7 @@ func TestFilteredChainView(t *testing.T) {
// dedicated miner to generate blocks, cause re-orgs, etc. We'll set up
// this node with a chain length of 125, so we have plenty of BTC to
// play around with.
miner, err := rpctest.New(netParams, nil, []string{"--txindex"})
miner, err := rpctest.New(netParams, nil, []string{"--txindex"}, "")
if err != nil {
t.Fatalf("unable to create mining node: %v", err)
}

@ -15,9 +15,10 @@ shift
# that here if necessary.
EXEC="$WORKDIR"/itest.test"$EXEC_SUFFIX"
LND_EXEC="$WORKDIR"/lnd-itest"$EXEC_SUFFIX"
echo $EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE
BTCD_EXEC="$WORKDIR"/btcd-itest"$EXEC_SUFFIX"
echo $EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE
# Exit code 255 causes the parallel jobs to abort, so if one part fails the
# other is aborted too.
cd "$WORKDIR" || exit 255
$EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE || exit 255
$EXEC -test.v "$@" -logoutput -goroutinedump -logdir=.logs-tranche$TRANCHE -lndexec=$LND_EXEC -btcdexec=$BTCD_EXEC -splittranches=$NUM_TRANCHES -runtranche=$TRANCHE || exit 255