Skip to content

Commit

Permalink
add two new regtest config options
Browse files Browse the repository at this point in the history
* added RegressionTestAnyHost. This allows sync peers from non-local
host. This is useful when using docker for regtest setups.

* added RegressionTestNoReset. This allows user to keep the previous
regtest blockchain db instead of deleting after each restart.

* updated sample-bchd.conf with the 2 new options

* added ./bchrpc/regtest/tools with instructions on how to perform
observation using regtest network and docker
  • Loading branch information
jcramer committed Apr 3, 2021
1 parent 9bebad6 commit 5d8f0bc
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 8 deletions.
5 changes: 5 additions & 0 deletions bchd.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ func removeRegressionDB(dbPath string) error {
return nil
}

// Don't reset the db if specified by config
if cfg.RegressionTestNoReset {
return nil
}

// Remove the old regression test database if it already exists.
fi, err := os.Stat(dbPath)
if err == nil {
Expand Down
1 change: 1 addition & 0 deletions bchrpc/regtest/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ module.exports = {
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-namespace": "error",
Expand Down
2 changes: 1 addition & 1 deletion bchrpc/regtest/bchd-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
if [ "$1" == "bchd1" ];
then
openssl req -x509 -newkey rsa:4096 -keyout /data/rpc.bchd1.key -out /data/rpc.bchd1.cert -days 365 -subj "/CN=bchd1" -nodes
bchd --slpcachemaxsize=1 --connect=bchd2 --grpclisten=0.0.0.0 --rpccert=/data/rpc.bchd1.cert --rpckey=/data/rpc.bchd1.key -C /data/bchd.conf
bchd --slpcachemaxsize=1 --addpeer=bchd2 --grpclisten=0.0.0.0 --rpccert=/data/rpc.bchd1.cert --rpckey=/data/rpc.bchd1.key -C /data/bchd.conf
fi

if [ "$1" == "bchd2" ];
Expand Down
1 change: 1 addition & 0 deletions bchrpc/regtest/bchd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

; Use the regression test network.
regtest=1
regtestanyhost=1

; Use the simulation test network
; simnet=1
Expand Down
15 changes: 15 additions & 0 deletions bchrpc/regtest/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,18 @@ services:
- "bchd1"
- "bchd2"
command: tail -F anything
bchd3: # a third bchd container for the purpose of manual observation separate from automated tests (see tools directory)
image: "bchd_regtest"
build:
dockerfile: "./bchrpc/regtest/Dockerfile.bchd"
context: "../.."
volumes:
- ./:/data # stores bchd.sh here
entrypoint: ["tail", "-F", "anything"] # this allows us to start and stop a node via docker-compose exec
depends_on:
- "bchd1"
- "bchd2"
expose:
- "18444" # bitcoin regtest network
ports:
- "18337:18334" # RPC service
7 changes: 4 additions & 3 deletions bchrpc/regtest/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ echo "INFO: Running mocha tests in docker"
docker-compose exec nodejs ./_test.sh
exit_code=$?

echo "INFO: Cleaning up."
docker-compose down
rm -f ./rpc.bchd1.*

if [ $exit_code -eq 0 ]; then
echo "INFO: All regtest network tests pass (code: $exit_code)"
else
echo "ERROR: One or more regtest network tests failed (code: $exit_code)"
fi

echo "INFO: Cleaning up."
docker-compose down
rm -f ./rpc.bchd1.*

exit $exit_code
24 changes: 24 additions & 0 deletions bchrpc/regtest/tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Regtest tools

Methods and commands that allow additional observation while debugging node behavior can be placed here. These tools are intended to be run on an ad-hoc basis separate from the tests located in the test folder.

## Interaction with bchd3
The docker-compose regtest network with 2 connected nodes, which can be started using `$ docker-compose up -d` from the regtest directory. A third node, `bchd3` is intended to be interacted with directly using `$ docker-compose exec bchd3 bash`, you can start and stop the node as needed for observational purposes during a debug session.

### Example commands for bchd3 interaction

* Start node 3 with no indexes: `bchd --regtest --rpcuser=bitcoin --rpcpass=password --notls --addpeer=bchd1 --regtestanyhost`
* Start node 3 with all indexes: `bchd --regtest --rpcuser=bitcoin --rpcpass=password --notls --addpeer=bchd1 --regtestanyhost --regtestnoreset --txindex --slpindex --addrindex`
* Get node 3 peer info: `bchctl -u=bitcoin -P=password --rpcserver=localhost:18334 --notls getpeerinfo`

**Note:** The flag `--regtestanyhost` allows node 3 to connect to the other peers on the docker network. Without this the node won't sync to non-localhost peers in the docker-compose network. The flag `--regtestnoreset` prevents deletion of regtest blockchain data from previous runs. By default, regtest data dir is reset at node startup.

## ./tools/Generator.ts

This script keeps `bchd2` node actively generating one block per second for 1000 blocks.

Example usage:

1. Make sure the regtest network is running via `$ docker-compose up -d` (must cd into the regtest directory)
2. Start the generator script via `$ npx ts-node ./tools/generator.ts`. This will run until all 1000 blocks are generated.
3. Shell into the `bchd3` container and start, stop, or inspect the node as required for observation.
14 changes: 14 additions & 0 deletions bchrpc/regtest/tools/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createRpcClient, sleep } from '../lib/utils';

// setup RPC clients (used primarily for generating blocks only)
const bchd2Rpc = createRpcClient();

// use a floating promise to generate 1 block each second
(async () => {
let counter = 0;
while (counter < 1000) {
counter++;
await bchd2Rpc.generate(1);
await sleep(1000);
}
})();
6 changes: 3 additions & 3 deletions bindata.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ type config struct {
TorIsolation bool `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
TestNet3 bool `long:"testnet" description:"Use the test network"`
RegressionTest bool `long:"regtest" description:"Use the regression test network"`
RegressionTestAnyHost bool `long:"regtestanyhost" description:"In regression test mode, allow connections from any host, not just localhost"`
RegressionTestNoReset bool `long:"regtestnoreset" description:"In regression test mode, don't reset the network db on node restart"`
SimNet bool `long:"simnet" description:"Use the simulation test network"`
AddCheckpoints []string `long:"addcheckpoint" description:"Add a custom checkpoint. Format: '<height>:<hash>'"`
DisableCheckpoints bool `long:"nocheckpoints" description:"Disable built-in checkpoints. Don't do this unless you know what you're doing."`
Expand Down
2 changes: 2 additions & 0 deletions netsync/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ type Config struct {
MinSyncPeerNetworkSpeed uint64

FastSyncMode bool

RegTestSyncAnyHost bool
}
8 changes: 7 additions & 1 deletion netsync/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ type SyncManager struct {
// signal that it has finished the UTXO set download before proceeding
// to make the standard getblocks request.
fastSyncMode bool

// regTestSyncAnyHost allows any host when regression test network is
// being used. For example, when running regression test network in
// docker containers the host is not a localhost.
regTestSyncAnyHost bool
}

// resetHeaderState sets the headers-first mode state to values appropriate for
Expand Down Expand Up @@ -450,7 +455,7 @@ func (sm *SyncManager) isSyncCandidate(peer *peerpkg.Peer) bool {
// Typically a peer is not a candidate for sync if it's not a full node,
// however regression test is special in that the regression tool is
// not a full node and still needs to be considered a sync candidate.
if sm.chainParams == &chaincfg.RegressionNetParams {
if sm.chainParams == &chaincfg.RegressionNetParams && !sm.regTestSyncAnyHost {
// The peer is not a candidate if it's not coming from localhost
// or the hostname can't be determined for some reason.
host, _, err := net.SplitHostPort(peer.Addr())
Expand Down Expand Up @@ -1820,6 +1825,7 @@ func New(config *Config) (*SyncManager, error) {
feeEstimator: config.FeeEstimator,
minSyncPeerNetworkSpeed: config.MinSyncPeerNetworkSpeed,
fastSyncMode: config.FastSyncMode,
regTestSyncAnyHost: config.RegTestSyncAnyHost,
}

best := sm.chain.BestSnapshot()
Expand Down
10 changes: 10 additions & 0 deletions sample-bchd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@
; Use the regression test network.
; regtest=1

; Allow connecting to peers from any host when using regression test mode. By
; default, regtest nodes will only connect to other nodes hosted on either
; localhost or 127.0.0.1. This option is useful when using more than one
; docker containers to run regression tests.
; regtestanyhost=1

; Don't reset the blockchain database in regression test mode. By default,
; the blockchain db will be reset at startup.
; regtestnoreset=1

; Use the simulation test network
; simnet=1

Expand Down
1 change: 1 addition & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3312,6 +3312,7 @@ func newServer(listenAddrs, agentBlacklist, agentWhitelist []string, db database
FeeEstimator: s.feeEstimator,
MinSyncPeerNetworkSpeed: cfg.MinSyncPeerNetworkSpeed,
FastSyncMode: cfg.FastSync,
RegTestSyncAnyHost: cfg.RegressionTestAnyHost,
})
if err != nil {
return nil, err
Expand Down

0 comments on commit 5d8f0bc

Please sign in to comment.