electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

regtest.sh (10981B)


      1 #!/usr/bin/env bash
      2 export HOME=~
      3 set -eu
      4 
      5 # alice -> bob -> carol
      6 
      7 alice="./run_electrum --regtest -D /tmp/alice"
      8 bob="./run_electrum --regtest -D /tmp/bob"
      9 carol="./run_electrum --regtest -D /tmp/carol"
     10 
     11 bitcoin_cli="bitcoin-cli -rpcuser=doggman -rpcpassword=donkey -rpcport=18554 -regtest"
     12 
     13 function new_blocks()
     14 {
     15     $bitcoin_cli generatetoaddress $1 $($bitcoin_cli getnewaddress) > /dev/null
     16 }
     17 
     18 function wait_for_balance()
     19 {
     20     msg="wait until $1's balance reaches $2"
     21     cmd="./run_electrum --regtest -D /tmp/$1"
     22     while balance=$($cmd getbalance | jq '[.confirmed, .unconfirmed] | to_entries | map(select(.value != null).value) | map(tonumber) | add ') && (( $(echo "$balance < $2" | bc -l) )); do
     23         sleep 1
     24 	msg="$msg."
     25 	printf "$msg\r"
     26     done
     27     printf "\n"
     28 }
     29 
     30 function wait_until_channel_open()
     31 {
     32     msg="wait until $1 sees channel open"
     33     cmd="./run_electrum --regtest -D /tmp/$1"
     34     while channel_state=$($cmd list_channels | jq '.[0] | .state' | tr -d '"') && [ $channel_state != "OPEN" ]; do
     35         sleep 1
     36 	msg="$msg."
     37 	printf "$msg\r"
     38     done
     39     printf "\n"
     40 }
     41 
     42 function wait_until_channel_closed()
     43 {
     44     msg="wait until $1 sees channel closed"
     45     cmd="./run_electrum --regtest -D /tmp/$1"
     46     while [[ $($cmd list_channels | jq '.[0].state' | tr -d '"') != "CLOSED" ]]; do
     47         sleep 1
     48 	msg="$msg."
     49 	printf "$msg\r"
     50     done
     51     printf "\n"
     52 }
     53 
     54 function wait_until_spent()
     55 {
     56     msg="wait until $1:$2 is spent"
     57     while [[ $($bitcoin_cli gettxout $1 $2) ]]; do
     58         sleep 1
     59 	msg="$msg."
     60 	printf "$msg\r"
     61     done
     62     printf "\n"
     63 }
     64 
     65 if [[ $# -eq 0 ]]; then
     66     echo "syntax: init|start|open|status|pay|close|stop"
     67     exit 1
     68 fi
     69 
     70 if [[ $1 == "new_block" ]]; then
     71     new_blocks 1
     72 fi
     73 
     74 if [[ $1 == "init" ]]; then
     75     echo "initializing $2"
     76     rm -rf /tmp/$2/
     77     agent="./run_electrum --regtest -D /tmp/$2"
     78     $agent create --offline > /dev/null
     79     $agent setconfig --offline log_to_file True
     80     $agent setconfig --offline use_gossip True
     81     $agent setconfig --offline server 127.0.0.1:51001:t
     82     $agent setconfig --offline lightning_to_self_delay 144
     83     # alice is funded, bob is listening
     84     if [[ $2 == "bob" ]]; then
     85         $bob setconfig --offline lightning_listen localhost:9735
     86     else
     87         echo "funding $2"
     88         $bitcoin_cli sendtoaddress $($agent getunusedaddress -o) 1
     89     fi
     90 fi
     91 
     92 
     93 # start daemons. Bob is started first because he is listening
     94 if [[ $1 == "start" ]]; then
     95     agent="./run_electrum --regtest -D /tmp/$2"
     96     $agent daemon -d
     97     $agent load_wallet
     98     sleep 1 # give time to synchronize
     99 fi
    100 
    101 if [[ $1 == "stop" ]]; then
    102     agent="./run_electrum --regtest -D /tmp/$2"
    103     $agent stop || true
    104 fi
    105 
    106 
    107 # alice sends two payments, then broadcast ctx after first payment.
    108 # thus, bob needs to redeem both to_local and to_remote
    109 
    110 
    111 if [[ $1 == "breach" ]]; then
    112     wait_for_balance alice 1
    113     echo "alice opens channel"
    114     bob_node=$($bob nodeid)
    115     channel=$($alice open_channel $bob_node 0.15)
    116     new_blocks 3
    117     wait_until_channel_open alice
    118     request=$($bob add_lightning_request 0.01 -m "blah" | jq -r ".invoice")
    119     echo "alice pays"
    120     $alice lnpay $request
    121     sleep 2
    122     ctx=$($alice get_channel_ctx $channel --iknowwhatimdoing)
    123     request=$($bob add_lightning_request 0.01 -m "blah2" | jq -r ".invoice")
    124     echo "alice pays again"
    125     $alice lnpay $request
    126     echo "alice broadcasts old ctx"
    127     $bitcoin_cli sendrawtransaction $ctx
    128     new_blocks 1
    129     wait_until_channel_closed bob
    130     new_blocks 1
    131     wait_for_balance bob 0.14
    132     $bob getbalance
    133 fi
    134 
    135 
    136 if [[ $1 == "backup" ]]; then
    137     wait_for_balance alice 1
    138     echo "alice opens channel"
    139     bob_node=$($bob nodeid)
    140     channel=$($alice open_channel $bob_node 0.15)
    141     echo "channel point: $channel"
    142     new_blocks 3
    143     wait_until_channel_open alice
    144     backup=$($alice export_channel_backup $channel)
    145     request=$($bob add_lightning_request 0.01 -m "blah" | jq -r ".invoice")
    146     echo "alice pays"
    147     $alice lnpay $request
    148     seed=$($alice getseed)
    149     $alice stop
    150     sleep 2 # FIXME: we should not have to do that..
    151     mv /tmp/alice/regtest/wallets/default_wallet /tmp/alice/regtest/wallets/default_wallet.old
    152     $alice -o restore "$seed"
    153     $alice daemon -d
    154     $alice load_wallet
    155     $alice import_channel_backup $backup
    156     $alice request_force_close $channel
    157 fi
    158 
    159 
    160 if [[ $1 == "extract_preimage" ]]; then
    161     # instead of settling bob will broadcast
    162     $bob enable_htlc_settle false
    163     wait_for_balance alice 1
    164     echo "alice opens channel"
    165     bob_node=$($bob nodeid)
    166     $alice open_channel $bob_node 0.15
    167     new_blocks 3
    168     wait_until_channel_open alice
    169     chan_id=$($alice list_channels | jq -r ".[0].channel_point")
    170     # alice pays bob
    171     invoice=$($bob add_lightning_request 0.04 -m "test" | jq -r ".invoice")
    172     screen -S alice_payment -dm -L -Logfile /tmp/alice/screen.log $alice lnpay $invoice --timeout=600
    173     sleep 1
    174     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    175     if [[ "$unsettled" == "0" ]]; then
    176         echo 'enable_htlc_settle did not work'
    177         exit 1
    178     fi
    179     # bob force closes
    180     $bob close_channel $chan_id --force
    181     new_blocks 1
    182     wait_until_channel_closed bob
    183     sleep 5
    184     success=$(cat /tmp/alice/screen.log | jq -r ".success")
    185     if [[ "$success" != "true" ]]; then
    186         exit 1
    187     fi
    188     cat /tmp/alice/screen.log
    189 fi
    190 
    191 
    192 if [[ $1 == "redeem_htlcs" ]]; then
    193     $bob enable_htlc_settle false
    194     wait_for_balance alice 1
    195     echo "alice opens channel"
    196     bob_node=$($bob nodeid)
    197     $alice open_channel $bob_node 0.15
    198     new_blocks 3
    199     wait_until_channel_open alice
    200     # alice pays bob
    201     invoice=$($bob add_lightning_request 0.04 -m "test" | jq -r ".invoice")
    202     $alice lnpay $invoice --timeout=1 || true
    203     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    204     if [[ "$unsettled" == "0" ]]; then
    205         echo 'enable_htlc_settle did not work'
    206         exit 1
    207     fi
    208     # bob goes away
    209     $bob stop
    210     echo "alice balance before closing channel:" $($alice getbalance)
    211     balance_before=$($alice getbalance | jq '[.confirmed, .unconfirmed, .lightning] | to_entries | map(select(.value != null).value) | map(tonumber) | add ')
    212     # alice force closes the channel
    213     chan_id=$($alice list_channels | jq -r ".[0].channel_point")
    214     $alice close_channel $chan_id --force
    215     new_blocks 1
    216     sleep 3
    217     echo "alice balance after closing channel:" $($alice getbalance)
    218     new_blocks 150
    219     sleep 10
    220     new_blocks 1
    221     sleep 3
    222     echo "alice balance after CLTV" $($alice getbalance)
    223     new_blocks 150
    224     sleep 10
    225     new_blocks 1
    226     sleep 3
    227     echo "alice balance after CSV" $($alice getbalance)
    228     # fixme: add local to getbalance
    229     wait_for_balance alice $(echo "$balance_before - 0.02" | bc -l)
    230     $alice getbalance
    231 fi
    232 
    233 
    234 if [[ $1 == "breach_with_unspent_htlc" ]]; then
    235     $bob enable_htlc_settle false
    236     wait_for_balance alice 1
    237     echo "alice opens channel"
    238     bob_node=$($bob nodeid)
    239     channel=$($alice open_channel $bob_node 0.15)
    240     new_blocks 3
    241     wait_until_channel_open alice
    242     echo "alice pays bob"
    243     invoice=$($bob add_lightning_request 0.04 -m "test" | jq -r ".invoice")
    244     $alice lnpay $invoice --timeout=1 || true
    245     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    246     if [[ "$unsettled" == "0" ]]; then
    247         echo "enable_htlc_settle did not work, $unsettled"
    248         exit 1
    249     fi
    250     ctx=$($alice get_channel_ctx $channel --iknowwhatimdoing)
    251     $bob enable_htlc_settle true
    252     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    253     if [[ "$unsettled" != "0" ]]; then
    254         echo "enable_htlc_settle did not work, $unsettled"
    255         exit 1
    256     fi
    257     echo "alice breaches with old ctx"
    258     $bitcoin_cli sendrawtransaction $ctx
    259     wait_for_balance bob 0.14
    260 fi
    261 
    262 
    263 if [[ $1 == "breach_with_spent_htlc" ]]; then
    264     $bob enable_htlc_settle false
    265     wait_for_balance alice 1
    266     echo "alice opens channel"
    267     bob_node=$($bob nodeid)
    268     channel=$($alice open_channel $bob_node 0.15)
    269     new_blocks 3
    270     wait_until_channel_open alice
    271     echo "alice pays bob"
    272     invoice=$($bob add_lightning_request 0.04 -m "test" | jq -r ".invoice")
    273     $alice lnpay $invoice --timeout=1 || true
    274     ctx=$($alice get_channel_ctx $channel --iknowwhatimdoing)
    275     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    276     if [[ "$unsettled" == "0" ]]; then
    277         echo "enable_htlc_settle did not work, $unsettled"
    278         exit 1
    279     fi
    280     cp /tmp/alice/regtest/wallets/default_wallet /tmp/alice/regtest/wallets/toxic_wallet
    281     $bob enable_htlc_settle true
    282     unsettled=$($alice list_channels | jq '.[] | .local_unsettled_sent')
    283     if [[ "$unsettled" != "0" ]]; then
    284         echo "enable_htlc_settle did not work, $unsettled"
    285         exit 1
    286     fi
    287     echo $($bob getbalance)
    288     echo "bob goes offline"
    289     $bob stop
    290     ctx_id=$($bitcoin_cli sendrawtransaction $ctx)
    291     echo "alice breaches with old ctx:" $ctx_id
    292     new_blocks 1
    293     if [[ $($bitcoin_cli gettxout $ctx_id 0 | jq '.confirmations') != "1" ]]; then
    294         echo "breach tx not confirmed"
    295         exit 1
    296     fi
    297     echo "wait for cltv_expiry blocks"
    298     # note: this will let alice redeem both to_local and the htlc.
    299     # (to_local needs to_self_delay blocks; htlc needs whatever we put in invoice)
    300     new_blocks 150
    301     $alice stop
    302     $alice daemon -d
    303     sleep 1
    304     $alice load_wallet -w /tmp/alice/regtest/wallets/toxic_wallet
    305     # wait until alice has spent both ctx outputs
    306     echo "alice spends to_local and htlc outputs"
    307     wait_until_spent $ctx_id 0
    308     wait_until_spent $ctx_id 1
    309     new_blocks 1
    310     echo "bob comes back"
    311     $bob daemon -d
    312     sleep 1
    313     $bob load_wallet
    314     wait_for_balance bob 0.039
    315     $bob getbalance
    316 fi
    317 
    318 
    319 if [[ $1 == "configure_test_watchtower" ]]; then
    320     # carol is the watchtower of bob
    321     $carol setconfig -o run_local_watchtower true
    322     $carol setconfig -o watchtower_user wtuser
    323     $carol setconfig -o watchtower_password wtpassword
    324     $carol setconfig -o watchtower_address 127.0.0.1:12345
    325     $bob setconfig -o watchtower_url http://wtuser:wtpassword@127.0.0.1:12345
    326 fi
    327 
    328 if [[ $1 == "watchtower" ]]; then
    329     wait_for_balance alice 1
    330     echo "alice opens channel"
    331     bob_node=$($bob nodeid)
    332     channel=$($alice open_channel $bob_node 0.15)
    333     echo "channel outpoint: $channel"
    334     new_blocks 3
    335     wait_until_channel_open alice
    336     echo "alice pays bob"
    337     invoice1=$($bob add_lightning_request 0.01 -m "invoice1" | jq -r ".invoice")
    338     $alice lnpay $invoice1
    339     ctx=$($alice get_channel_ctx $channel --iknowwhatimdoing)
    340     echo "alice pays bob again"
    341     invoice2=$($bob add_lightning_request 0.01 -m "invoice2" | jq -r ".invoice")
    342     $alice lnpay $invoice2
    343     msg="waiting until watchtower is synchronized"
    344     while watchtower_ctn=$($carol get_watchtower_ctn $channel) && [ $watchtower_ctn != "3" ]; do
    345         sleep 1
    346 	msg="$msg."
    347 	printf "$msg\r"
    348     done
    349     printf "\n"
    350 fi