URI: 
       tcleanup tests that use regtest: - separate setup from execution - install bitcoind and electrumx in travis - use the same framework for lnwatcher and forwarding - make tests runnable locally - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit a6983441365d0150eb364d8d289e30ee5ebe6434
   DIR parent 023d4026b95078ee33e7f242c8d1f95189709598
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Mon, 11 Mar 2019 21:00:29 +0100
       
       cleanup tests that use regtest:
        - separate setup from execution
        - install bitcoind and electrumx in travis
        - use the same framework for lnwatcher and forwarding
        - make tests runnable locally
       
       Diffstat:
         M .travis.yml                         |       7 +++++++
         A electrum/tests/regtest/regtest.sh   |     130 +++++++++++++++++++++++++++++++
         A electrum/tests/regtest/start_bitco… |      23 +++++++++++++++++++++++
         A electrum/tests/regtest/start_elect… |       7 +++++++
         D electrum/tests/test_forwarding/tes… |      72 -------------------------------
         D electrum/tests/test_lnwatcher.py    |      42 -------------------------------
         D electrum/tests/test_lnwatcher/brea… |      22 ----------------------
         D electrum/tests/test_lnwatcher/rede… |      46 -------------------------------
         D electrum/tests/test_lnwatcher/setu… |      31 -------------------------------
         D electrum/tests/test_lnwatcher/star… |      67 -------------------------------
         A electrum/tests/test_regtest.py      |      34 +++++++++++++++++++++++++++++++
       
       11 files changed, 201 insertions(+), 280 deletions(-)
       ---
   DIR diff --git a/.travis.yml b/.travis.yml
       t@@ -12,13 +12,20 @@ addons:
            packages:
              - libsecp256k1-0
        before_install:
       +  - sudo add-apt-repository -y ppa:bitcoin/bitcoin
       +  - sudo apt-get -qq update
       +  - sudo apt-get install -yq bitcoind
          - git tag
        install:
          - pip install -r contrib/requirements/requirements-travis.txt
       +  - pip install electrumx
        cache:
          - pip: true
          - directories:
            - /tmp/electrum-build
       +before_script:
       +    - electrum/tests/regtest/start_bitcoind.sh
       +    - electrum/tests/regtest/start_electrumx.sh
        script:
            - tox
        after_success:
   DIR diff --git a/electrum/tests/regtest/regtest.sh b/electrum/tests/regtest/regtest.sh
       t@@ -0,0 +1,130 @@
       +#!/usr/bin/env bash
       +export HOME=~
       +set -eu
       +
       +# alice -> bob -> carol
       +
       +alice="./run_electrum --regtest -D /tmp/alice"
       +bob="./run_electrum --regtest -D /tmp/bob"
       +carol="./run_electrum --regtest -D /tmp/carol"
       +
       +if [[ $# -eq 0 ]]; then
       +    echo "syntax: init|start|open|status|pay|close|stop"
       +    exit 1
       +fi
       +
       +if [[ $1 == "init" ]]; then
       +    rm -rf /tmp/alice/ /tmp/bob/ /tmp/carol/
       +    $alice create > /dev/null
       +    $bob create > /dev/null
       +    $carol create > /dev/null
       +    $bob setconfig lightning_listen localhost:9735
       +    bitcoin-cli -regtest sendtoaddress $($alice getunusedaddress) 1
       +    bitcoin-cli -regtest sendtoaddress $($carol getunusedaddress) 1
       +    bitcoin-cli -regtest generate 1 > /dev/null
       +fi
       +
       +# start daemons. Bob is started first because he is listening
       +if [[ $1 == "start" ]]; then
       +    $bob daemon -s 127.0.0.1:51001:t start
       +    $bob daemon load_wallet
       +    $alice daemon -s 127.0.0.1:51001:t start
       +    $alice daemon load_wallet
       +    $carol daemon -s 127.0.0.1:51001:t start
       +    $carol daemon load_wallet
       +    sleep 10 # give time to synchronize
       +fi
       +
       +if [[ $1 == "stop" ]]; then
       +    $alice daemon stop || true
       +    $bob daemon stop || true
       +    $carol daemon stop || true
       +fi
       +
       +if [[ $1 == "open" ]]; then
       +    bob_node=$($bob nodeid)
       +    channel_id1=$($alice open_channel $bob_node 0.001 --channel_push 0.001)
       +    channel_id2=$($carol open_channel $bob_node 0.001 --channel_push 0.001)
       +    echo "mining 3 blocks"
       +    bitcoin-cli -regtest generate 3
       +    sleep 10 # time for channelDB
       +fi
       +
       +if [[ $1 == "alice_pays_carol" ]]; then
       +    request=$($carol addinvoice 0.0001 "blah")
       +    $alice lnpay $request
       +    carol_balance=$($carol list_channels | jq -r '.[0].local_balance')
       +    echo "carol balance: $carol_balance"
       +    if [[ $carol_balance != 110000 ]]; then
       +        exit 1
       +    fi
       +fi
       +
       +if [[ $1 == "close" ]]; then
       +   chan1=$($alice list_channels | jq -r ".[0].channel_point")
       +   chan2=$($carol list_channels | jq -r ".[0].channel_point")
       +   $alice close_channel $chan1
       +   $carol close_channel $chan2
       +   echo "mining 1 block"
       +   bitcoin-cli -regtest generate 1
       +fi
       +
       +if [[ $1 == "breach" ]]; then
       +    bob_node=$($bob nodeid)
       +    $alice open_channel $bob_node 0.15
       +    sleep 3
       +    bitcoin-cli generate 6 > /dev/null
       +    sleep 10
       +    request=$($bob addinvoice 0.01 "blah")
       +    $alice lnpay $request
       +    bitcoin-cli sendrawtransaction $(cat /tmp/alice/regtest/initial_commitment_tx)
       +    sleep 12
       +    bitcoin-cli generate 2 > /dev/null
       +    sleep 12
       +    balance=$($bob getbalance | jq '.confirmed | tonumber')
       +    echo "balance of bob after breach: $balance"
       +    if (( $(echo "$balance < 0.14" | bc -l) )); then
       +        exit 1
       +    fi
       +fi
       +
       +if [[ $1 == "redeem_htlcs" ]]; then
       +    $bob daemon stop
       +    ELECTRUM_DEBUG_LIGHTNING_DO_NOT_SETTLE=1 $bob daemon -s 127.0.0.1:51001:t start
       +    $bob daemon load_wallet
       +    sleep 1
       +    # alice opens channel
       +    bob_node=$($bob nodeid)
       +    $alice open_channel $bob_node 0.15
       +    bitcoin-cli generate 6 > /dev/null
       +    sleep 10
       +    # alice pays bob
       +    invoice=$($bob addinvoice 0.05 "test")
       +    $alice lnpay $invoice
       +    sleep 1
       +    settled=$($alice list_channels | jq '.[] | .local_htlcs | .settles | length')
       +    if [[ "$settled" != "0" ]]; then
       +        echo 'DO_NOT_SETTLE did not work'
       +        exit 1
       +    fi
       +    # bob goes away
       +    $bob daemon stop
       +    echo "alice balance before closing channel:" $($alice getbalance)
       +    balance_before=$($alice getbalance | jq '[.confirmed, .unconfirmed, .lightning] | to_entries | map(select(.value != null).value) | map(tonumber) | add ')
       +    # alice force closes the channel
       +    chan_id=$($alice list_channels | jq -r ".[0].channel_point")
       +    $alice close_channel $chan_id --force
       +    bitcoin-cli generate 1 > /dev/null
       +    sleep 5
       +    echo "alice balance after closing channel:" $($alice getbalance)
       +    bitcoin-cli generate 144 > /dev/null
       +    sleep 10
       +    bitcoin-cli generate 1 > /dev/null
       +    sleep 10
       +    echo "alice balance after 144 blocks:" $($alice getbalance)
       +    balance_after=$($alice getbalance |  jq '[.confirmed, .unconfirmed] | to_entries | map(select(.value != null).value) | map(tonumber) | add ')
       +    if (( $(echo "$balance_before - $balance_after > 0.02" | bc -l) )); then
       +        echo "htlc not redeemed."
       +        exit 1
       +    fi
       +fi
   DIR diff --git a/electrum/tests/regtest/start_bitcoind.sh b/electrum/tests/regtest/start_bitcoind.sh
       t@@ -0,0 +1,23 @@
       +#!/usr/bin/env bash
       +export HOME=~
       +set -eux pipefail
       +mkdir -p ~/.bitcoin
       +cat > ~/.bitcoin/bitcoin.conf <<EOF
       +regtest=1
       +txindex=1
       +printtoconsole=1
       +rpcuser=doggman
       +rpcpassword=donkey
       +rpcallowip=127.0.0.1
       +zmqpubrawblock=tcp://127.0.0.1:28332
       +zmqpubrawtx=tcp://127.0.0.1:28333
       +[regtest]
       +rpcbind=0.0.0.0
       +rpcport=18554
       +EOF
       +rm -rf ~/.bitcoin/regtest
       +screen -S bitcoind -X quit || true
       +screen -S bitcoind -m -d bitcoind -regtest -deprecatedrpc=generate
       +sleep 6
       +addr=$(bitcoin-cli getnewaddress)
       +bitcoin-cli generatetoaddress 150 $addr > /dev/null
   DIR diff --git a/electrum/tests/regtest/start_electrumx.sh b/electrum/tests/regtest/start_electrumx.sh
       t@@ -0,0 +1,7 @@
       +#!/usr/bin/env bash
       +export HOME=~
       +set -eux pipefail
       +cd
       +rm -rf electrumx_db
       +mkdir electrumx_db
       +COIN=BitcoinSegwit TCP_PORT=51001 RPC_PORT=8000 NET=regtest DAEMON_URL=http://doggman:donkey@127.0.0.1:18554 DB_DIRECTORY=~/electrumx_db electrumx_server > electrumx.log &
   DIR diff --git a/electrum/tests/test_forwarding/test_forwarding.sh b/electrum/tests/test_forwarding/test_forwarding.sh
       t@@ -1,72 +0,0 @@
       -#!/usr/bin/env bash
       -
       -# alice -> bob -> carol
       -
       -ELECTRUM=./run_electrum
       -
       -if [[ $# -eq 0 ]]; then
       -    echo "syntax: init|start|open|status|pay|close|stop"
       -    exit 1
       -fi
       -
       -if [[ $1 == "init" ]]; then
       -    rm -rf /tmp/alice/ /tmp/bob/ /tmp/carol/
       -    $ELECTRUM create --regtest -D /tmp/alice/
       -    $ELECTRUM create --regtest -D /tmp/bob/
       -    $ELECTRUM create --regtest -D /tmp/carol/
       -    $ELECTRUM setconfig --regtest -D /tmp/bob/ lightning_listen localhost:9735
       -    bitcoin-cli -regtest sendtoaddress `$ELECTRUM getunusedaddress --regtest -D /tmp/alice/` 1
       -    bitcoin-cli -regtest sendtoaddress `$ELECTRUM getunusedaddress --regtest -D /tmp/bob/` 1
       -    bitcoin-cli -regtest sendtoaddress `$ELECTRUM getunusedaddress --regtest -D /tmp/carol/` 1
       -    bitcoin-cli -regtest generate 1 > /dev/null
       -fi
       -
       -# start daemons. Bob is started first because he is listening
       -if [[ $1 == "start" ]]; then
       -    $ELECTRUM daemon --regtest -D /tmp/bob/ -s 127.0.0.1:51001:t start
       -    $ELECTRUM daemon --regtest -D /tmp/bob/ load_wallet
       -    $ELECTRUM daemon --regtest -D /tmp/alice/ -s 127.0.0.1:51001:t start
       -    $ELECTRUM daemon --regtest -D /tmp/alice/ load_wallet
       -    $ELECTRUM daemon --regtest -D /tmp/carol/ -s 127.0.0.1:51001:t start
       -    $ELECTRUM daemon --regtest -D /tmp/carol/ load_wallet
       -    echo "daemons started"
       -fi
       -
       -if [[ $1 == "open" ]]; then
       -    bob_node=$($ELECTRUM --regtest -D /tmp/bob/ nodeid)
       -    channel_id1=$($ELECTRUM --regtest -D /tmp/alice/ open_channel $bob_node 0.001 --channel_push 0.001)
       -    echo "Channel ID" $channel_id1
       -    channel_id2=$($ELECTRUM --regtest -D /tmp/carol/ open_channel $bob_node 0.001 --channel_push 0.001)
       -    echo "Channel ID" $channel_id2
       -    echo "mining 3 blocks"
       -    bitcoin-cli -regtest generate 3
       -fi
       -
       -if [[ $1 == "status" ]]; then
       -    sleep 3
       -    $ELECTRUM --regtest -D /tmp/bob list_channels
       -fi
       -
       -if [[ $1 == "pay" ]]; then
       -    sleep 3
       -    request=$($ELECTRUM --regtest -D /tmp/carol/ addinvoice 0.0001 "blah")
       -    echo $request
       -    $ELECTRUM --regtest -D /tmp/alice/ lnpay $request
       -fi
       -
       -if [[ $1 == "close" ]]; then
       -   chan1=$($ELECTRUM --regtest -D /tmp/alice/ list_channels | jq -r ".[0].channel_point")
       -   chan2=$($ELECTRUM --regtest -D /tmp/carol/ list_channels | jq -r ".[0].channel_point")
       -   echo "Channel ID" $chan1
       -   echo "Channel ID" $chan2
       -   $ELECTRUM --regtest -D /tmp/alice/ close_channel $chan1
       -   $ELECTRUM --regtest -D /tmp/carol/ close_channel $chan2
       -   echo "mining 1 block"
       -   bitcoin-cli -regtest generate 1
       -fi
       -
       -if [[ $1 == "stop" ]]; then
       -    $ELECTRUM daemon --regtest -D /tmp/bob/ -s 127.0.0.1:51001:t stop
       -    $ELECTRUM daemon --regtest -D /tmp/alice/ -s 127.0.0.1:51001:t stop
       -    $ELECTRUM daemon --regtest -D /tmp/carol/ -s 127.0.0.1:51001:t stop
       -fi
   DIR diff --git a/electrum/tests/test_lnwatcher.py b/electrum/tests/test_lnwatcher.py
       t@@ -1,42 +0,0 @@
       -import base64
       -import os
       -import sys
       -import unittest
       -import subprocess
       -from electrum.crypto import sha256
       -from electrum.util import bh2u
       -import itertools
       -import pathlib
       -
       -def split_seq(iterable, size):
       -    it = iter(iterable)
       -    item = list(itertools.islice(it, size))
       -    while item:
       -        yield item
       -        item = list(itertools.islice(it, size))
       -
       -not_travis_text = 'breach test takes a long time, installs things, requires certain ports to be available, assumes x86 and doesn\'t clean up after itself'
       -
       -@unittest.skipUnless(os.getlogin() == 'travis', not_travis_text)
       -class TestLNWatcher(unittest.TestCase):
       -    maxDiff = None # unlimited
       -
       -    @staticmethod
       -    def run_shell(cmd, timeout=60):
       -        process = subprocess.Popen(['electrum/tests/test_lnwatcher/' + cmd[0]] + ([] if len(cmd) == 1 else cmd[1:]), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
       -        for line in iter(process.stdout.readline, b''):
       -            sys.stdout.write(line.decode(sys.stdout.encoding))
       -        process.wait(timeout=timeout)
       -        assert process.returncode == 0
       -
       -    @classmethod
       -    def setUpClass(cls):
       -        cls.run_shell(['setup.sh'])
       -
       -    def test_redeem_stuck_htlcs(self):
       -        self.run_shell(['start_dependencies.sh', 'do_not_settle_elec2'])
       -        self.run_shell(['redeem_htlcs.sh'])
       -
       -    def test_funder_publishes_initial_commitment_and_fundee_takes_all(self):
       -        self.run_shell(['start_dependencies.sh'])
       -        self.run_shell(['breach.sh'])
   DIR diff --git a/electrum/tests/test_lnwatcher/breach.sh b/electrum/tests/test_lnwatcher/breach.sh
       t@@ -1,22 +0,0 @@
       -#!/usr/bin/env bash
       -export HOME=~
       -set -eux pipefail
       -bitcoin-cli generatetoaddress 109 mwLZSJ2hUkvFoSkyadNGgmu9977w6K8wfj > /dev/null
       -sleep 30
       -othernode=$(./run_electrum --regtest -D /tmp/elec2 nodeid)
       -./run_electrum --regtest -D /tmp/elec1 open_channel $othernode 0.15
       -sleep 3
       -bitcoin-cli generatetoaddress 6 mwLZSJ2hUkvFoSkyadNGgmu9977w6K8wfj > /dev/null
       -sleep 12
       -invoice=$(./run_electrum --regtest -D /tmp/elec2 addinvoice 0.01 invoice_description)
       -timeout 5 ./run_electrum -D /tmp/elec1 --regtest lnpay $invoice || (cat screenlog*; exit 1)
       -bitcoin-cli sendrawtransaction $(cat /tmp/elec1/regtest/initial_commitment_tx)
       -# elec2 should take all funds because breach
       -sleep 12
       -bitcoin-cli generatetoaddress 2 mwLZSJ2hUkvFoSkyadNGgmu9977w6K8wfj > /dev/null
       -sleep 12
       -balance=$(./run_electrum --regtest -D /tmp/elec2 getbalance | jq '.confirmed | tonumber')
       -if (( $(echo "$balance < 0.14" | bc -l) )); then
       -    echo "balance of elec2 insufficient: $balance"
       -    exit 1
       -fi
   DIR diff --git a/electrum/tests/test_lnwatcher/redeem_htlcs.sh b/electrum/tests/test_lnwatcher/redeem_htlcs.sh
       t@@ -1,46 +0,0 @@
       -#!/usr/bin/env bash
       -export HOME=~
       -set -eux pipefail
       -bitcoin-cli generatetoaddress 100 bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s > /dev/null
       -sleep 30
       -balance_before=$(./run_electrum --regtest -D /tmp/elec1 getbalance | jq -r .confirmed)
       -othernode=$(./run_electrum --regtest -D /tmp/elec2 nodeid)
       -./run_electrum --regtest -D /tmp/elec1 open_channel $othernode 0.15
       -sleep 12
       -bitcoin-cli generatetoaddress 6 bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s > /dev/null
       -sleep 12
       -balance_during=$(./run_electrum --regtest -D /tmp/elec1 getbalance | jq -r .confirmed)
       -if [[ "$balance_during" == "$balance_before" ]]; then
       -    echo 'balance has not changed'
       -    ./run_electrum --regtest -D /tmp/elec1 getbalance
       -    exit 1
       -fi
       -for i in $(seq 0 0); do
       -    invoice=$(./run_electrum --regtest -D /tmp/elec2 addinvoice 0.01 invoice_description$i)
       -    ./run_electrum -D /tmp/elec1 --regtest lnpay $invoice
       -done
       -screen -S elec2 -X quit
       -sleep 1
       -ps ax | grep run_electrum
       -chan_id=$(python3 run_electrum -D /tmp/elec1 --regtest list_channels | jq -r ".[0].channel_point")
       -./run_electrum -D /tmp/elec1 --regtest close_channel $chan_id --force
       -sleep 12
       -bitcoin-cli generatetoaddress 144 bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s
       -sleep 30
       -bitcoin-cli generatetoaddress 10 bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s
       -sleep 12
       -bitcoin-cli generatetoaddress 10 bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s
       -sleep 12
       -balance_after_elec2=$(./run_electrum --regtest -D /tmp/elec2 getbalance |  jq '[.confirmed, .unconfirmed] | to_entries | map(select(.value != null).value) | map(tonumber) | add ')
       -if [[ "$balance_after_elec2" != "0" ]]; then
       -    echo 'elec2 has balance, DO_NOT_SETTLE did not work'
       -    exit 1
       -fi
       -date
       -./run_electrum --regtest -D /tmp/elec1 history --show_fees
       -balance_after=$(./run_electrum --regtest -D /tmp/elec1 getbalance |  jq '[.confirmed, .unconfirmed] | to_entries | map(select(.value != null).value) | map(tonumber) | add ')
       -if (( $(echo "$balance_after - $balance_during < 0.14" | bc -l) || $(echo "$balance_after - $balance_during > 0.15" | bc -l) )); then
       -    echo "balance of elec1 not between 0.14 and 0.15, to_local and htlcs not redeemed. balance was $balance_before before, $balance_during after channel opening and $balance_after after force closing"
       -    tail -n 200 screenlog.0
       -    exit 1
       -fi
   DIR diff --git a/electrum/tests/test_lnwatcher/setup.sh b/electrum/tests/test_lnwatcher/setup.sh
       t@@ -1,31 +0,0 @@
       -#!/usr/bin/env bash
       -set -eux pipefail
       -#this is downloading so much, and all we need is bitcoin-cli
       -#if [ ! -f bitcoin-*.tar.gz ]; then
       -#    wget https://bitcoin.org/bin/bitcoin-core-0.17.0.1/bitcoin-0.17.0.1-x86_64-linux-gnu.tar.gz
       -#fi
       -#tar xf bitcoin-*.tar.gz
       -#sudo mv bitcoin-0.17.0/bin/bitcoin-cli /usr/bin/
       -sudo wget -qO /usr/bin/bitcoin-cli https://sr.ht/e6-xS.bitcoincli # this is just bitcoin-cli from the 0.17.0.1 release, rehosted
       -sudo chmod +x /usr/bin/bitcoin-cli
       -sudo apt-get -qq update
       -sudo apt-get -qq install libssl1.0.0 jq netcat lsof moreutils
       -
       -sudo curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
       -sudo python3 get-pip.py
       -python3 -m pip install plyvel pylru
       -mkdir ~/.bitcoin
       -cat > ~/.bitcoin/bitcoin.conf <<EOF
       -regtest=1
       -txindex=1
       -printtoconsole=1
       -rpcuser=doggman
       -rpcpassword=donkey
       -rpcallowip=127.0.0.1
       -zmqpubrawblock=tcp://127.0.0.1:28332
       -zmqpubrawtx=tcp://127.0.0.1:28333
       -[regtest]
       -rpcbind=0.0.0.0
       -rpcport=18554
       -EOF
       -echo setup.sh done
   DIR diff --git a/electrum/tests/test_lnwatcher/start_dependencies.sh b/electrum/tests/test_lnwatcher/start_dependencies.sh
       t@@ -1,67 +0,0 @@
       -#!/usr/bin/env bash
       -export HOME=~
       -ARG=$1
       -set -eux pipefail
       -if [ ! -f deterministic-bitcoind-ef70f9b5 ]; then
       -    wget -q https://github.com/ysangkok/electrum-lightning-test/releases/download/v1/deterministic-bitcoind-ef70f9b5
       -    chmod +x deterministic-bitcoind-ef70f9b5
       -fi
       -if [ ! -d electrumx ]; then
       -    rm -f master.zip
       -    wget -q https://github.com/kyuupichan/electrumx/archive/master.zip
       -    unzip -q master.zip
       -    mv electrumx-master electrumx
       -fi
       -screen -S bitcoind -X quit || true
       -killall -9 deterministic-bitcoind-ef70f9b5 || true
       -sleep 1
       -ls -ld /.bitcoin/regtest || true
       -rm -rf /.bitcoin/regtest
       -ps -ef | grep bitcoin # bitcoin can rename itself to bitcoin-shutoff
       -screen -S bitcoind -m -d ./deterministic-bitcoind-ef70f9b5 -regtest
       -block_hash=""
       -while [[ "$block_hash" == "" ]]; do
       -    sleep 1
       -    block_hash=$(bitcoin-cli generatetoaddress 1 mwLZSJ2hUkvFoSkyadNGgmu9977w6K8wfj | jq -r ".[0]" || true)
       -done
       -if [[ "$ARG" != "no_determinism" ]]; then
       -    if [[ "$block_hash" != "40fc46e8bd87c0448ceb490b5339be674b89364c9f557e17b74b437d85b0a99c" ]]; then
       -        echo 'not using deterministic bitcoind'
       -        exit 1
       -    fi
       -fi
       -screen -S electrumx -X quit || true
       -kill -9 $(lsof -i :51001 -Fp | grep ^p | cut -c 2-) || true
       -sleep 1
       -screen -S electrumx -m -d bash -c "cd electrumx && rm -rf electrumx-db; mkdir electrumx-db && COIN=BitcoinSegwit TCP_PORT=51001 RPC_PORT=8000 NET=regtest DAEMON_URL=http://doggman:donkey@127.0.0.1:18554 DB_DIRECTORY=\$PWD/electrumx-db ./electrumx_server"
       -sleep 5
       -block_header_1="0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f68514a449a154326a7eafa4a6c6fc09639afe2dedde351446a790ec72af01b74dbe5494dffff7f2000000000"
       -if [[ "$ARG" != "no_determinism" ]]; then
       -    electrumx_header_1=""
       -    while [[ "$electrumx_header_1" != "$block_header_1" ]]; do
       -        sleep 3
       -        electrumx_header_1=$(printf '{"id": 1, "method": "server.version", "params": ["testing", "1.4"]}\n{"id": 2, "method": "blockchain.block.header", "params": [1]}\n' | nc localhost 51001 | grep -v ElectrumX | jq -r .result)
       -    done
       -fi
       -screen -S elec1 -X quit || true
       -screen -S elec2 -X quit || true
       -kill -9 $(ps ax | grep run_electrum | grep -v grep | awk '{print $1}') || true
       -#kill -9 $(lsof -i :$(cat /tmp/elec1/regtest/daemon | python3 -c 'import ast, sys; print(ast.literal_eval(sys.stdin.read())[0][1])') -Fp | grep ^p | cut -c 2-) || true
       -#kill -9 $(lsof -i :$(cat /tmp/elec2/regtest/daemon | python3 -c 'import ast, sys; print(ast.literal_eval(sys.stdin.read())[0][1])') -Fp | grep ^p | cut -c 2-) || true
       -sleep 1
       -rm -rf /tmp/elec?
       -./run_electrum --regtest -D /tmp/elec1 restore "escape pumpkin perfect question nice all trigger course dismiss pole swallow burden"
       -./run_electrum --regtest -D /tmp/elec2 restore "sure razor enrich panda sustain shoe napkin brick song van embark wave"
       -cat > /tmp/elec2/regtest/config <<EOF
       -{"lightning_listen": "127.0.0.1:9735"}
       -EOF
       -ELECTRUM_DEBUG_LIGHTNING_DANGEROUS=1 screen -L -d -m -S elec1 sh -c './run_electrum --regtest -D /tmp/elec1 daemon -v -s localhost:51001:t 2>&1 | ts'
       -if [[ "$ARG" == "do_not_settle_elec2" ]]; then
       -    ELECTRUM_DEBUG_LIGHTNING_DO_NOT_SETTLE=1 ELECTRUM_DEBUG_LIGHTNING_DANGEROUS=1 screen -L -d -m -S elec2 sh -c './run_electrum --regtest -D /tmp/elec2 daemon -v -s localhost:51001:t 2>&1 | ts'
       -else
       -    ELECTRUM_DEBUG_LIGHTNING_DANGEROUS=1 screen -L -d -m -S elec2 sh -c './run_electrum --regtest -D /tmp/elec2 daemon -v -s localhost:51001:t 2>&1 | ts'
       -fi
       -sleep 3
       -./run_electrum --regtest -D /tmp/elec1 daemon load_wallet
       -./run_electrum --regtest -D /tmp/elec2 daemon load_wallet
       -sleep 3
   DIR diff --git a/electrum/tests/test_regtest.py b/electrum/tests/test_regtest.py
       t@@ -0,0 +1,34 @@
       +import os
       +import sys
       +import unittest
       +import subprocess
       +
       +class TestLightning(unittest.TestCase):
       +
       +    @staticmethod
       +    def run_shell(args, timeout=30):
       +        process = subprocess.Popen(['electrum/tests/regtest/regtest.sh'] + args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
       +        for line in iter(process.stdout.readline, b''):
       +            sys.stdout.write(line.decode(sys.stdout.encoding))
       +        process.wait(timeout=timeout)
       +        process.stdout.close()
       +        assert process.returncode == 0
       +
       +    def setUp(self):
       +        self.run_shell(['stop'])
       +        self.run_shell(['init'])
       +        self.run_shell(['start'])
       +
       +    def tearDown(self):
       +        self.run_shell(['stop'])
       +
       +    def test_breach(self):
       +        self.run_shell(['breach'])
       +
       +    def test_forwarding(self):
       +        self.run_shell(['open'])
       +        self.run_shell(['alice_pays_carol'])
       +        self.run_shell(['close'])
       +
       +    def test_redeem_htlcs(self):
       +        self.run_shell(['redeem_htlcs'])