lnd/lntest
yyforyongyu cc6b20bf2f
lntest: mine empty blocks when cleaning up force close
Fix this test flake,
```
harness_miner.go:218:
        	Error Trace:	/home/runner/work/lnd/lnd/lntest/harness_miner.go:218
        	            				/home/runner/work/lnd/lnd/lntest/harness.go:1641
        	            				/home/runner/work/lnd/lnd/lntest/harness.go:1515
        	            				/home/runner/work/lnd/lnd/itest/lnd_wipe_fwdpkgs_test.go:121
        	            				/home/runner/work/lnd/lnd/lntest/harness.go:286
        	            				/home/runner/work/lnd/lnd/itest/lnd_test.go:136
        	Error:      	Received unexpected error:
        	            	want 1, got 0 in mempool: []
        	Test:       	TestLightningNetworkDaemon/tranche02/91-of-135/neutrino/wipe_forwarding_packages
        	Messages:   	assert tx in mempool timeout
    harness.go:339: finished test: wipe_forwarding_packages, start height=1636, end height=1653, mined blocks=17
    harness.go:345: test failed, skipped cleanup
```
2023-10-31 16:51:24 +08:00
..
channels lntest/channels: introduce subpackage to deduplicate static structs 2021-01-25 14:04:39 -05:00
mock multi: add GetBlockHeader to BlockChainIO 2023-10-27 11:05:27 -04:00
node multi: use "bitcoin" chain name constant 2023-10-06 16:34:47 -07:00
rpc multi: add GetBlockHeader to BlockChainIO 2023-10-27 11:05:27 -04:00
wait lntest: increase channel close timeout 2023-04-20 18:52:46 +08:00
bitcoind_common.go itest+lntest: migrate lntemp to lntest 2023-02-23 21:56:09 +08:00
bitcoind_notxindex.go multi: new bitcoind rpcpolling backend for itests 2022-05-11 09:02:13 +02:00
bitcoind_rpcpolling.go multi: new bitcoind rpcpolling backend for itests 2022-05-11 09:02:13 +02:00
bitcoind.go multi: new bitcoind rpcpolling backend for itests 2022-05-11 09:02:13 +02:00
btcd.go itest+lntest: add helper methods to manage temp miners 2023-06-19 14:04:24 +08:00
doc.go lntest: Add doc.go with package documentation. 2017-12-14 20:06:23 -08:00
fee_service.go lntest: add http header timeout to config 2023-10-17 11:25:06 -06:00
harness_assertion.go itest: batch channel fee params 2023-07-26 09:49:22 +02:00
harness_miner.go itest+lntest: add helper methods to manage temp miners 2023-06-19 14:04:24 +08:00
harness_node_manager.go itest: fix make lint 2023-02-23 21:56:10 +08:00
harness_setup.go lntest: fix linter stylecheck and containedctx 2023-02-24 01:35:16 +08:00
harness.go lntest: mine empty blocks when cleaning up force close 2023-10-31 16:51:24 +08:00
neutrino.go itest+lntest: migrate lntemp to lntest 2023-02-23 21:56:09 +08:00
README.md multi: replace FundingLocked related docs 2023-03-17 18:21:59 +08:00
utils.go itest: add taproot support for all variants of runMultiHopHtlcClaimTest 2023-08-22 16:34:06 -07:00

lntest

lntest is a package which holds the components used for the lnds integration tests. It is responsible for managing lnd nodes, chain backends and miners, advancing nodes states and providing assertions.

Quick Start

A simple example to run the integration test.

func TestFoo(t *testing.T) {
	// Get the binary path and setup the harness test.
	//
	// TODO: define the binary path to lnd and the name of the database
	// backend.
	harnessTest := lntemp.SetupHarness(t, binary, *dbBackendFlag)
	defer harnessTest.Stop()

	// Setup standby nodes, Alice and Bob, which will be alive and shared
	// among all the test cases.
	harnessTest.SetupStandbyNodes()

	// Run the subset of the test cases selected in this tranche.
	//
	// TODO: define your own testCases.
	for _, tc := range testCases {
		tc := tc

		t.Run(tc.Name, func(st *testing.T) {
			// Create a separate harness test for the testcase to
			// avoid overwriting the external harness test that is
			// tied to the parent test.
			ht := harnessTest.Subtest(st)

			// Run the test cases.
			ht.RunTestCase(tc)
		})
	}
}

Package Structure

This package has four major components, HarnessTest, HarnessMiner, node.HarnessNode and rpc.HarnessRPC, with the following architecture,

+----------------------------------------------------------+
|                                                          |
|                        HarnessTest                       |
|                                                          |
| +----------------+  +----------------+  +--------------+ |
| |   HarnessNode  |  |   HarnessNode  |  | HarnessMiner | |
| |                |  |                |  +--------------+ |
| | +------------+ |  | +------------+ |                   |
| | | HarnessRPC | |  | | HarnessRPC | |  +--------------+ |
| | +------------+ |  | +------------+ |  | HarnessMiner | |
| +----------------+  +----------------+  +--------------+ |
+----------------------------------------------------------+
  • HarnessRPC holds all the RPC clients and adds a layer over all the RPC methods to assert no error happened at the RPC level.

  • HarnessNode builds on top of the HarnessRPC. It is responsible for managing the lnd node, including start and stop pf the lnd process, authentication of the gRPC connection, topology subscription(NodeWatcher) and maintains an internal state(NodeState).

  • HarnessMiner builds on top of btcds rcptest.Harness and is responsilbe for managing blocks and the mempool.

  • HarnessTest builds on top of testing.T and can be viewed as the assertion machine. It provides multiple ways to initialize a node, such as with/without seed, backups, etc. It also handles interactions between nodes like connecting nodes and opening/closing channels so its easier to acquire or validate a desired test states such as nodes balance, mempool condition, etc.

Standby Nodes

Standby nodes are HarnessNodes created when initializing the integration test and stay alive across all the test cases. Creating a new node is not without a cost. With block height increasing, it takes significantly longer to initialize a new node and wait for it to be synced. Standby nodes, however, dont have this problem as they are digesting blocks all the time. Thus its encouraged to use standby nodes wherever possible.

Currently there are two standby nodes, Alice and Bob. Their internal states are recorded and taken into account when HarnessTest makes assertions. When making a new test case using Subtest, theres a cleanup function which further validates the current test case has no dangling uncleaned states, such as transactions left in mempool, open channels, etc.

Different Code Used in lntest

Since the miner in lntest uses regtest, it has a very fast block production rate, which is the greatest difference between the conditions it simulates and the real-world has. Aside from that, lnd has several places that use different code, which is triggered by the build flag integration, to speed up the tests. They are summarized as followings,

  1. funding.checkPeerChannelReadyInterval, which is used when we wait for the peer to send us ChannelReady. This value is 1 second in lnd, and 10 milliseconds in lntest.
  2. lncfg.ProtocolOptions, which is used to specify protocol flags. In lnd, anchor and script enforced lease are enabled by default, while in lntest, they are disabled by default.
  3. Reduced scrypt parameters are used in lntest. In lnd, the parameters N, R, and P are imported from snacl, while in lntest they are replaced with waddrmgr.FastScryptOptions. Both macaroon and aezeed are affected.
  4. The method, nextRevocationProducer, defined in LightningWallet is slightly different. For lnwallet, it will check a special pre-defined channel ID to test restoring channel backups created with the old revocation root derivation method.