tregtest.sh - electrum - Electrum Bitcoin wallet
HTML git clone https://git.parazyd.org/electrum
DIR Log
DIR Files
DIR Refs
DIR Submodules
---
tregtest.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