test.sh: split into multiple scripts.

This significantly reduces re-testing of the same paths, and simplifies
the addition of new tests.

make check -j12 times:
	Before: 9m24.973s
	After:	7m52.005s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-11-10 23:44:49 +10:30
parent fae7f68731
commit ce96812ef0
11 changed files with 1063 additions and 823 deletions

View File

@ -2,52 +2,58 @@ check: daemon-tests
# We run three different bitcoinds, for different types of tests.
# Provides limited paralellism.
daemon-test.sh-0-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=0 daemon/test/test.sh --$*
daemon-test.sh-1-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=1 daemon/test/test.sh --$*
daemon-test.sh-2-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=2 daemon/test/test.sh --$*
daemon-test-0-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=0 daemon/test/test-$*
daemon-test-1-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=1 daemon/test/test-$*
daemon-test-2-%:
NO_VALGRIND=$(NO_VALGRIND) VARIANT=2 daemon/test/test-$*
# These don't work in parallel, so chain the deps
daemon-test.sh-0-steal: daemon-test.sh-0-dump-onchain
daemon-test.sh-0-dump-onchain: daemon-test.sh-0-timeout-anchor
daemon-test.sh-0-timeout-anchor: daemon-test.sh-0-different-fee-rates
daemon-test.sh-0-different-fee-rates: daemon-test.sh-0-mutual-close-with-htlcs
daemon-test.sh-0-mutual-close-with-htlcs: daemon-test.sh-0-manual-commit
daemon-test.sh-0-manual-commit: daemon-test.sh-0-normal
daemon-test.sh-0-normal: daemon-test-setup-0
daemon-test-0-steal: daemon-test-0-unilateral
daemon-test-0-unilateral: daemon-test-0-funding-timeout
daemon-test-0-funding-timeout: daemon-test-0-mutual-close-with-htlcs
daemon-test-0-mutual-close-with-htlcs: daemon-test-0-different-fees
daemon-test-0-different-fees: daemon-test-0-routing
daemon-test-0-routing: daemon-test-0-invoice
daemon-test-0-invoice: daemon-test-0-basic\ manual-commit
daemon-test-0-basic\ manual-commit: daemon-test-0-basic
daemon-test-0-basic: daemon-test-setup-0
daemon-test.sh-1-steal\ --restart: daemon-test.sh-1-dump-onchain\ --restart
daemon-test.sh-1-dump-onchain\ --restart: daemon-test.sh-1-timeout-anchor\ --restart
daemon-test.sh-1-timeout-anchor\ --restart: daemon-test.sh-1-different-fee-rates\ --restart
daemon-test.sh-1-different-fee-rates\ --restart: daemon-test.sh-1-mutual-close-with-htlcs\ --restart
daemon-test.sh-1-mutual-close-with-htlcs\ --restart: daemon-test.sh-1-manual-commit\ --restart
daemon-test.sh-1-manual-commit\ --restart: daemon-test.sh-1-normal\ --restart
daemon-test.sh-1-normal\ --restart: daemon-test-setup-1
daemon-test-2-steal\ --reconnect: daemon-test-2-unilateral\ --reconnect
daemon-test-2-unilateral\ --reconnect: daemon-test-2-funding-timeout\ --reconnect
daemon-test-2-funding-timeout\ --reconnect: daemon-test-2-mutual-close-with-htlcs\ --reconnect
daemon-test-2-mutual-close-with-htlcs\ --reconnect: daemon-test-2-different-fees\ --reconnect
daemon-test-2-different-fees\ --reconnect: daemon-test-2-routing\ --reconnect
daemon-test-2-routing\ --reconnect: daemon-test-2-invoice\ --reconnect
daemon-test-2-invoice\ --reconnect: daemon-test-2-basic\ manual-commit\ --reconnect
daemon-test-2-basic\ manual-commit\ --reconnect: daemon-test-2-basic\ --reconnect
daemon-test-2-basic\ --reconnect: daemon-test-setup-2
daemon-test.sh-2-steal\ --reconnect: daemon-test.sh-2-dump-onchain\ --reconnect
daemon-test.sh-2-dump-onchain\ --reconnect: daemon-test.sh-2-timeout-anchor\ --reconnect
daemon-test.sh-2-timeout-anchor\ --reconnect: daemon-test.sh-2-different-fee-rates\ --reconnect
daemon-test.sh-2-different-fee-rates\ --reconnect: daemon-test.sh-2-mutual-close-with-htlcs\ --reconnect
daemon-test.sh-2-mutual-close-with-htlcs\ --reconnect: daemon-test.sh-2-manual-commit\ --reconnect
daemon-test.sh-2-manual-commit\ --reconnect: daemon-test.sh-2-normal\ --reconnect
daemon-test.sh-2-normal\ --reconnect: daemon-test-setup-2
daemon-test-1-steal\ --restart: daemon-test-1-unilateral\ --restart
daemon-test-1-unilateral\ --restart: daemon-test-1-funding-timeout\ --restart
daemon-test-1-funding-timeout\ --restart: daemon-test-1-mutual-close-with-htlcs\ --restart
daemon-test-1-mutual-close-with-htlcs\ --restart: daemon-test-1-different-fees\ --restart
daemon-test-1-different-fees\ --restart: daemon-test-1-routing\ --restart
daemon-test-1-routing\ --restart: daemon-test-1-invoice\ --restart
daemon-test-1-invoice\ --restart: daemon-test-1-basic\ manual-commit\ --restart
daemon-test-1-basic\ manual-commit\ --restart: daemon-test-1-basic\ --restart
daemon-test-1-basic\ --restart: daemon-test-setup-1
# We shutdown first in case something is left over.
daemon-test-setup-%: daemon-all
VARIANT=$* daemon/test/scripts/shutdown.sh 2>/dev/null || true
VARIANT=$* daemon/test/scripts/setup.sh
daemon-test-shutdown-0: daemon-test.sh-0-steal
daemon-test-shutdown-0: daemon-test-0-steal
VARIANT=0 daemon/test/scripts/shutdown.sh
daemon-test-shutdown-1: daemon-test.sh-1-steal\ --restart
daemon-test-shutdown-1: daemon-test-1-steal\ --restart
VARIANT=1 daemon/test/scripts/shutdown.sh
daemon-test-shutdown-2: daemon-test.sh-2-steal\ --reconnect
daemon-test-shutdown-2: daemon-test-2-steal\ --reconnect
VARIANT=2 daemon/test/scripts/shutdown.sh
# Forms long dependency chains.
daemon-all-test.sh: daemon-test-shutdown-0 daemon-test-shutdown-1 daemon-test-shutdown-2
daemon-all-test: daemon-test-shutdown-0 daemon-test-shutdown-1 daemon-test-shutdown-2
# Note that these actually #include everything they need, except ccan/ and bitcoin/.
# That allows for unit testing of statics, and special effects.
@ -82,5 +88,5 @@ VALGRIND_TEST_ARGS = --track-origins=yes --leak-check=full --show-reachable=yes
daemon-unit-tests: $(DAEMON_TEST_PROGRAMS)
set -e; for f in $(DAEMON_TEST_PROGRAMS); do $(VALGRIND) $(VALGRIND_TEST_ARGS) $$f; done
daemon-tests: daemon-unit-tests daemon-all-test.sh
daemon-tests: daemon-unit-tests daemon-all-test

View File

@ -148,6 +148,7 @@ start_lightningd()
# If bitcoind not already running, start it.
if ! $CLI getinfo >/dev/null 2>&1; then
echo Starting bitcoind...
scripts/setup.sh
SHUTDOWN_BITCOIN=scripts/shutdown.sh
else

358
daemon/test/test-basic Executable file
View File

@ -0,0 +1,358 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
if [ x"$1" = x"manual-commit" ]; then
MANUALCOMMIT=1
shift
fi
parse_cmdline 2 "$@"
setup_lightning 2
if [ -n "$MANUALCOMMIT" ]; then
# Aka. never.
echo 'commit-time=1h' >> $DIR1/config
echo 'commit-time=1h' >> $DIR2/config
fi
start_lightningd 2
# Check IDs match logs
[ `$LCLI1 getlog | sed -n 's/.*"ID: \([0-9a-f]*\)".*/\1/p'` = $ID1 ]
[ `$LCLI2 getlog | sed -n 's/.*"ID: \([0-9a-f]*\)".*/\1/p'` = $ID2 ]
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Expect them to be waiting for anchor, and ack from other side.
check_peerstate lcli1 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
check_peerstate lcli2 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
# Enable reconnect from here.
DO_RECONNECT=$RECONNECT
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
# We turn off routing failure for the moment.
lcli1 dev-routefail false
lcli2 dev-routefail false
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# This is 10,000 satoshi, so not dust!
HTLC_AMOUNT=10000000
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
if [ -n "$MANUALCOMMIT" ]; then
# They should register a staged htlc.
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_HTLC } " $B_AMOUNT $B_FEE ""
# Now commit it.
lcli1 dev-commit $ID2
# Node 1 hasn't got it committed, but node2 should have told it to stage.
check_status_single lcli1 $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_REVOCATION } " $B_AMOUNT $B_FEE ""
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
# Node 2 has it committed.
check_status_single lcli2 $B_AMOUNT $B_FEE "" $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_REVOCATION } "
# There should be no "both committed" here yet
if lcli1 getlog debug | $FGREP "Both committed"; then
echo "Node1 thinks they are both committed";
exit 1
fi
if lcli2 getlog debug | $FGREP "Both committed"; then
echo "Node2 thinks they are both committed";
exit 1
fi
# Now node2 gives commitment to node1.
lcli2 dev-commit $ID1
# After revocation, they should know they're both committed.
check lcli1 "getlog debug | $FGREP 'Both committed to ADD of our HTLC'"
check lcli2 "getlog debug | $FGREP 'Both committed to ADD of their HTLC'"
else
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
fi
# Both should have committed tx.
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Without manual commit, this check is racy.
if [ -n "$MANUALCOMMIT" ]; then
if lcli1 getlog debug | $FGREP 'Both committed to FULFILL'; then
echo "Node1 thinks they are both committed";
exit 1
fi
if lcli2 getlog debug | $FGREP 'Both committed to FULFILL'; then
echo "Node2 thinks they are both committed";
exit 1
fi
fi
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# If we're very slow, manually committed above, and we're restarting,
# we may restart *after* this and thus not see it in the log.
[ "$RECONNECT$MANUALCOMMIT" = restart1 ] || check lcli1 "getlog debug | $FGREP 'Both committed to FULFILL of our HTLC'"
check lcli2 "getlog debug | $FGREP 'Both committed to FULFILL of their HTLC'"
# We've transferred the HTLC amount to 2, who now has to pay fees,
# so no net change for A who saves on fees.
B_FEE=$HTLC_AMOUNT
# With no HTLCs, extra fee no longer required.
A_FEE=$(($A_FEE - $EXTRA_FEE - $B_FEE))
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# A new one, at 10x the amount.
HTLC_AMOUNT=100000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
lcli2 dev-failhtlc $ID1 $HTLCID 695
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# Back to how we were before.
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
A_FEE=$(($A_FEE - $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Same again, but this time it expires.
HTLC_AMOUNT=10000001
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
# Make sure node1 accepts the expiry packet.
while [ $(blockheight) != $EXPIRY ]; do
$CLI generate 1
done
# This should make node2 send it.
$CLI generate 1
if [ -n "$MANUALCOMMIT" ]; then
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_REMOVE_HTLC } " $B_AMOUNT $B_FEE ""
lcli2 dev-commit $ID1
lcli1 dev-commit $ID2
fi
# Back to how we were before.
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
A_FEE=$(($A_FEE - $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# First, give more money to node2, so it can offer HTLCs.
EXPIRY=$(( $(blockheight) + 10))
HTLC_AMOUNT=100000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# Both now pay equal fees.
A_FEE=$(($NO_HTLCS_FEE / 2))
B_FEE=$(($NO_HTLCS_FEE / 2))
# We transferred 10000000 before, and $HTLC_AMOUNT now.
A_AMOUNT=$(($AMOUNT - 10000000 - $HTLC_AMOUNT - $A_FEE))
B_AMOUNT=$((10000000 + $HTLC_AMOUNT - $B_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Two failures crossover
SECRET2=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfe
RHASH2=`lcli1 dev-rhash $SECRET2 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
# This means B will *just* afford it (but can't cover increased fees)
HTLC_AMOUNT=$(($B_AMOUNT - $EXTRA_FEE / 2))
HTLCID=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# Make sure that's committed, in case lcli1 restarts.
lcli2 dev-commit $ID1 >/dev/null || true
HTLCID2=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# A covers the extra part of the fee.
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE - $EXTRA_FEE / 2)) $(($A_FEE + $EXTRA_FEE + $EXTRA_FEE / 2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION } " 0 $(($B_FEE + $EXTRA_FEE / 2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } "
# Fail both, to reset.
lcli1 dev-failhtlc $ID2 $HTLCID 830
lcli2 dev-failhtlc $ID1 $HTLCID2 829
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Now, two HTLCs at once, one from each direction.
# Both sides can afford this.
HTLC_AMOUNT=1000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
HTLCID2=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $(($B_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION } "
lcli1 dev-fulfillhtlc $ID2 $HTLCID2 $SECRET2
lcli2 dev-failhtlc $ID1 $HTLCID 849
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# We transferred amount from B to A.
A_AMOUNT=$(($A_AMOUNT + $HTLC_AMOUNT))
B_AMOUNT=$(($B_AMOUNT - $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Now, test making more changes before receiving commit reply.
DO_RECONNECT=""
lcli2 dev-output $ID1 false
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# Make sure node1 sends commit (in the background, since it will block!)
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2 &
if [ -n "$MANUALCOMMIT" ]; then
# node2 will consider this committed.
check_status_single lcli2 $(($B_AMOUNT - $EXTRA_FEE/2)) $(($B_FEE + $EXTRA_FEE/2)) "" $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE/2)) $(($A_FEE + $EXTRA_FEE/2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_REVOCATION } "
else
# It will start committing by itself
check_status_single lcli2 $(($B_AMOUNT - $EXTRA_FEE/2)) $(($B_FEE + $EXTRA_FEE/2)) "" $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE/2)) $(($A_FEE + $EXTRA_FEE/2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_COMMIT } "
fi
# node1 will still be awaiting node2's revocation reply.
check_status_single lcli1 $(($A_AMOUNT)) $(($A_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_COMMIT } " $B_AMOUNT $B_FEE ""
# Now send another offer, and enable node2 output.
HTLCID2=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
lcli2 dev-output $ID1 true
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
DO_RECONNECT=$RECONNECT
# Both sides should be committed to htlcs
# We open-code check_status here: HTLCs could be in either order.
check_balance_single lcli1 $(($A_AMOUNT - $HTLC_AMOUNT*2 - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) $(($B_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE))
check_balance_single lcli2 $(($B_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) $(($A_AMOUNT - $HTLC_AMOUNT*2 - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE))
# Once both balances are correct, this should be right.
lcli1 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION } ], their_htlcs : [ ]" || lcli1 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } ], their_htlcs : [ ]"
lcli2 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ ], their_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION } ]" || lcli2 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ ], their_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } ]"
# Just for once, reconnect/restart node 2.
case "$RECONNECT" in
reconnect)
echo RECONNECTING NODE2
$LCLI2 dev-reconnect $ID1 >/dev/null
sleep 1
;;
restart)
echo RESTARTING NODE2
$LCLI2 -- dev-restart $LIGHTNINGD2 >/dev/null 2>&1 || true
if ! check "$LCLI2 getlog 2>/dev/null | fgrep -q Hello"; then
echo "Node2 dev-restart failed!">&2
exit 1
fi
;;
esac
if ! check "$LCLI2 getpeers | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
# Node2 collects the HTLCs.
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
lcli2 dev-fulfillhtlc $ID1 $HTLCID2 $SECRET2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# We transferred 2 * amount from A to B.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT * 2))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT * 2))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
lcli1 close $ID2
# They should be negotiating the close.
check_peerstate lcli1 STATE_MUTUAL_CLOSING
check_peerstate lcli2 STATE_MUTUAL_CLOSING
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Give it forever-1 blocks.
$CLI generate 8
# Make sure they saw it!
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Now the final one.
$CLI generate 1
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok

85
daemon/test/test-different-fees Executable file
View File

@ -0,0 +1,85 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
# Simply override default fee (estimatefee fails on regtest anyway)
DEFAULT_FEE_RATE2=50000
# We use 5x fee rate for commits, by defailt.
FEE_RATE2=$(($DEFAULT_FEE_RATE2 * 5))
echo "default-fee-rate=$DEFAULT_FEE_RATE2" >> $DIR2/config
start_lightningd 2
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
# Asymmetry, since fee rates different.
NO_HTLCS_FEE2=$((338 * $FEE_RATE2 / 2000 * 2000))
ONE_HTLCS_FEE2=$(( (338 + 32) * $FEE_RATE2 / 2000 * 2000))
A_AMOUNT1=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE1=$NO_HTLCS_FEE
A_AMOUNT2=$(($AMOUNT - $NO_HTLCS_FEE2))
A_FEE2=$NO_HTLCS_FEE2
B_AMOUNT=0
B_FEE=0
check_status_single lcli1 $A_AMOUNT1 $A_FEE1 "" $B_AMOUNT $B_FEE ""
check_status_single lcli2 $B_AMOUNT $B_FEE "" $(($A_AMOUNT2)) $(($A_FEE2)) ""
# This is 100,000 satoshi, so covers fees.
HTLC_AMOUNT=100000000
RHASH=`lcli2 invoice $HTLC_AMOUNT RHASH3 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
ROUTE=`lcli1 getroute $ID2 $HTLC_AMOUNT 1`
ROUTE=`echo $ROUTE | sed 's/^{ "route" : \(.*\) }$/\1/'`
lcli1 sendpay "$ROUTE" $RHASH
# They should not split fees.
check_status_single lcli1 $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
check_status_single lcli2 $(($HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) "" $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) ""
# FIXME: reactivate feechanges!
# # Change fee rate on node2 to same as node1.
# lcli2 dev-feerate 40000
# $CLI generate 1
# [ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# [ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# check_status $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
# # Change back.
# lcli2 dev-feerate 50000
# $CLI generate 1
# [ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# [ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# check_status_single lcli1 $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
# check_status_single lcli2 $(($HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) "" $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) ""
lcli1 close $ID2
check_tx_spend
# Give it 10 blocks ie "forever"
$CLI generate 10
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok

View File

@ -0,0 +1,81 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
start_lightningd 2
# Prevent anchor broadcast
lcli1 dev-broadcast false
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Expect them to be waiting for anchor, and ack from other side.
check_peerstate lcli1 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
check_peerstate lcli2 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
# Enable reconnect from here.
DO_RECONNECT=$RECONNECT
$CLI generate 99
# Still waiting.
check_peerstate lcli1 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
check_peerstate lcli2 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
# Make sure whichever times out first doesn't tell the other.
lcli1 dev-output $ID2 false
lcli2 dev-output $ID1 false
$CLI generate 1
# Node1 should have gone into STATE_ERR_ANCHOR_TIMEOUT.
check "lcli1 getlog debug | $FGREP STATE_ERR_ANCHOR_TIMEOUT"
# Don't try to reconnect any more if we are.
if [ x"$RECONNECT" = xreconnect ]; then DO_RECONNECT=""; fi
# If we're restarting, don't expect peer.
NO_PEER2=1
# Now let them send errors if they're still trying.
lcli2 dev-output $ID1 true || true
lcli1 dev-output $ID2 true || true
# Peer 2 should give up, and have forgotten all about it.
check "lcli2 getlog debug | $FGREP STATE_CLOSED"
check_no_peers lcli2
# Node1 should be disconnected.
check_peerconnected lcli1 false
# Now let node1 broadcast anchor and unilateral close belatedly!
lcli1 dev-broadcast true
# Now mine that transaction so they see it.
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
# Now move bitcoind 1 day, which is what node2 asked for on commit.
# Get current time from last block (works if we run this twice).
CURTIME=$($CLI getblock $($CLI getblockhash $(($BLOCKHEIGHT + 100))) | sed -n 's/ "time": \([0-9]*\),/\1/p')
$CLI setmocktime $(($CURTIME + 24 * 60 * 60))
# Move average so CSV moves.
$CLI generate 6
# Now it should have spent the commit tx.
check_tx_spend
# 100 blocks pass
$CLI generate 100
# Considers it all done now.
check_no_peers lcli1
lcli1 stop
lcli2 stop
all_ok

86
daemon/test/test-invoice Executable file
View File

@ -0,0 +1,86 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
start_lightningd 2
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# 100k satoshi should cover fees.
HTLC_AMOUNT=100000000
EXPIRY=$(( $(blockheight) + 10))
RHASH3=`lcli2 invoice $HTLC_AMOUNT RHASH3 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
lcli2 listinvoice
[ "`lcli2 listinvoice | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
HTLCID3=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH3 | extract_id`
# We transferred amount from A to B, but fee now split evenly.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT + $NO_HTLCS_FEE / 2))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT - $NO_HTLCS_FEE / 2))
A_FEE=$(($NO_HTLCS_FEE / 2))
B_FEE=$(($NO_HTLCS_FEE / 2))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
[ "`lcli2 listinvoice | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
# Now, failed payment (didn't pay enough)
RHASH4=`lcli2 invoice $HTLC_AMOUNT RHASH4 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
# Shouldn't have this already.
if lcli2 getlog | $FGREP 'Short payment for'; then exit 1; fi
# Test listinvoice with both, or subset (either order possible!)
INVOICES=`lcli2 listinvoice | tr -s '\012\011\" ' ' '`
[ "$INVOICES" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true }, { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ] || [ "$INVOICES" = "[ { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false }, { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli2 listinvoice RHASH3 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli2 listinvoice RHASH4 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
HTLCID4=`lcli1 dev-newhtlc $ID2 $(($HTLC_AMOUNT - 1)) $EXPIRY $RHASH4 | extract_id`
check lcli2 "getlog | $FGREP 'Short payment for'"
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
lcli2 delinvoice RHASH4
if lcli2 delinvoice RHASH3 >/dev/null; then
echo "Should not be able to delete completed invoice!" >&2
exit 1
fi
lcli1 close $ID2
# They should be negotiate the close.
check_tx_spend
# Bury it in "forever" blocks.
$CLI generate 10
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok

View File

@ -0,0 +1,95 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
start_lightningd 2
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
# Send funds to 2 so it can offer HTLCS
HTLC_AMOUNT=100000000
RHASH=`lcli2 invoice $HTLC_AMOUNT RHASH3 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
ROUTE=`lcli1 getroute $ID2 $HTLC_AMOUNT 1`
ROUTE=`echo $ROUTE | sed 's/^{ "route" : \(.*\) }$/\1/'`
lcli1 sendpay "$ROUTE" $RHASH
# They pay half fees each.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT + $NO_HTLCS_FEE / 2))
A_FEE=$(($NO_HTLCS_FEE / 2))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT - $NO_HTLCS_FEE / 2))
B_FEE=$(($NO_HTLCS_FEE / 2))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# For next step, make sure neither node fails HTLCs we're about to set up.
lcli1 dev-routefail false
lcli2 dev-routefail false
# Set up HTLCs both ways.
# This is 10,000 satoshi, so not dust!
HTLC_AMOUNT=10000000
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID1=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# FIXME: Test with dust htlc, too.
HTLCID2=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $(($B_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } "
# Now begin close
lcli1 close $ID2
# They should be waiting for it to clear up.
check_peerstate lcli1 STATE_SHUTDOWN
check_peerstate lcli2 STATE_SHUTDOWN
# Fail one, still waiting.
lcli2 dev-failhtlc $ID1 $HTLCID1 800
check_peerstate lcli1 STATE_SHUTDOWN
check_peerstate lcli2 STATE_SHUTDOWN
# Fulfill the other causes them to actually complete the close.
lcli1 dev-fulfillhtlc $ID2 $HTLCID2 $SECRET
check_peerstate lcli1 STATE_MUTUAL_CLOSING
check_peerstate lcli2 STATE_MUTUAL_CLOSING
check_tx_spend
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Give it "forever" blocks.
$CLI generate 9
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok

143
daemon/test/test-routing Executable file
View File

@ -0,0 +1,143 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 3 "$@"
setup_lightning 3
start_lightningd 3
# We connect 1->2->3
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
check_tx_spend
$CLI generate 1
P2SHADDR2=`$LCLI2 newaddr | sed -n 's/{ "address" : "\(.*\)" }/\1/p'`
TXID2=`$CLI sendtoaddress $P2SHADDR2 0.01`
FUND_INPUT_TX2=`$CLI getrawtransaction $TXID2`
$CLI generate 1
lcli2 connect localhost $PORT3 $FUND_INPUT_TX2 &
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
# Make sure all in STATE_NORMAL.
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli3 STATE_NORMAL
# More than enough to cover commit fees.
HTLC_AMOUNT=100000000
# Tell node 1 about the 2->3 route.
# Add to config in case we are restaring.
echo "add-route=$ID2/$ID3/546000/10/36/36" >> $DIR1/config
lcli1 dev-add-route $ID2 $ID3 546000 10 36 36
RHASH=`lcli3 invoice $HTLC_AMOUNT RHASH | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
BAD_RHASH=`echo $RHASH | tr '0-9a-f' 'a-f0-9'`
# Get route.
ROUTE=`lcli1 getroute $ID3 $HTLC_AMOUNT 1`
ROUTE=`echo $ROUTE | sed 's/^{ "route" : \(.*\) }$/\1/'`
# Try wrong hash.
if lcli1 sendpay "$ROUTE" $BAD_RHASH; then
echo Paid with wrong hash? >&2
exit 1
fi
# Try underpaying.
PAID=`echo "$ROUTE" | sed -n 's/.*"msatoshi" : \([0-9]*\),.*/\1/p'`
UNDERPAY=`echo "$ROUTE" | sed "s/: $PAID,/: $(($PAID - 1)),/"`
if lcli1 sendpay "$UNDERPAY" $RHASH; then
echo Paid with too little? >&2
exit 1
fi
# If restarting, make sure node3 remembers incoming payment.
if [ "$RECONNECT" = restart ]; then
$LCLI3 -- dev-restart $LIGHTNINGD3 >/dev/null 2>&1 || true
if ! check "$LCLI3 getpeers 2>/dev/null | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
fi
[ "`lcli3 listinvoice RHASH | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH , rhash : $RHASH , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
# Pay correctly.
lcli1 sendpay "$ROUTE" $RHASH
# Node 3 should end up with that amount (minus 1/2 tx fee)
# Note that it is delayed a little, since node2 fulfils as soon as fulfill
# starts.
check lcli3 "getpeers | $FGREP \"\\\"our_amount\\\" : $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2))\""
# If restarting, make sure node3 remembers completed payment.
if [ "$RECONNECT" = restart ]; then
echo RESTARTING NODE3
$LCLI3 -- dev-restart $LIGHTNINGD3 >/dev/null 2>&1 || true
if ! check "$LCLI3 getpeers 2>/dev/null | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
fi
[ "`lcli3 listinvoice RHASH | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH , rhash : $RHASH , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli3 waitinvoice | tr -s '\012\011\" ' ' '`" = "{ label : RHASH , rhash : $RHASH , msatoshi : $HTLC_AMOUNT } " ]
# Can't pay twice (try from node2)
ROUTE2=`lcli2 getroute $ID3 $HTLC_AMOUNT 1`
ROUTE2=`echo $ROUTE2 | sed 's/^{ "route" : \(.*\) }$/\1/'`
if lcli2 sendpay "$ROUTE2" $RHASH; then
echo "Paying twice worked?" >&2
exit 1
fi
lcli3 close $ID2
check_peerstate lcli3 STATE_MUTUAL_CLOSING
# Re-send should be a noop (doesn't matter that node3 is down!)
lcli1 sendpay "$ROUTE" $RHASH
# Re-send to different id or amount should complain.
SHORTROUTE=`echo "$ROUTE" | sed 's/, { "id" : .* }//' | sed 's/"msatoshi" : [0-9]*,/"msatoshi" : '$HTLC_AMOUNT,/`
lcli1 sendpay "$SHORTROUTE" $RHASH | $FGREP "already succeeded to $ID3"
lcli1 sendpay "$UNDERPAY" $RHASH | $FGREP "already succeeded with amount $HTLC_AMOUNT"
# Now node2 should fail to route.
if lcli1 sendpay "$ROUTE" $BAD_RHASH | $FGREP "failed: error code 404 node $ID2 reason Unknown peer"; then : ;
else
echo "Pay to node3 didn't give 404" >&2
exit 1
fi
# Now node1 should fail to route (route deleted)
if lcli1 getroute $ID3 $HTLC_AMOUNT 1 | $FGREP "no route found"; then : ;
else
echo "Pay to node3 didn't fail instantly second time" >&2
exit 1
fi
lcli1 close $ID2
check_peerstate lcli1 STATE_MUTUAL_CLOSING
# Make sure both txs broadcast.
check '[ `$CLI getrawmempool | egrep -c "[a-f0-9]{32}"` = 2 ]'
# Bury them in "forever" blocks.
$CLI generate 10
check_no_peers lcli1
check_no_peers lcli2
check_no_peers lcli3
lcli1 stop
lcli2 stop
lcli3 stop
all_ok

90
daemon/test/test-steal Executable file
View File

@ -0,0 +1,90 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
start_lightningd 2
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
# Send funds to 2 so it can offer HTLCS
HTLC_AMOUNT=100000000
RHASH=`lcli2 invoice $HTLC_AMOUNT RHASH3 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
ROUTE=`lcli1 getroute $ID2 $HTLC_AMOUNT 1`
ROUTE=`echo $ROUTE | sed 's/^{ "route" : \(.*\) }$/\1/'`
lcli1 sendpay "$ROUTE" $RHASH
# They pay half fees each noe.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT + $NO_HTLCS_FEE / 2))
A_FEE=$(($NO_HTLCS_FEE / 2))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT - $NO_HTLCS_FEE / 2))
B_FEE=$(($NO_HTLCS_FEE / 2))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# For next step, make sure neither node fails HTLCs we're about to set up.
lcli1 dev-routefail false
lcli2 dev-routefail false
# Set up HTLCs both ways.
# This is 10,000 satoshi, so not dust!
HTLC_AMOUNT=10000000
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID1=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# FIXME: Test with dust htlc, too.
HTLCID2=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $(($B_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } "
# This is the tx we're going to try to spend.
STEAL_TX=`$LCLI1 dev-signcommit $ID2 | cut -d\" -f4`
# Fail one, succeed 2->1 payment
lcli2 dev-failhtlc $ID1 $HTLCID1 800
lcli1 dev-fulfillhtlc $ID2 $HTLCID2 $SECRET
A_AMOUNT=$(($A_AMOUNT + $HTLC_AMOUNT))
B_AMOUNT=$(($B_AMOUNT - $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Send out old commit tx from peer 1.
$CLI sendrawtransaction $STEAL_TX
$CLI generate 1
# Node1 should get really upset; node2 should steal the transaction.
check_peerstate lcli1 STATE_ERR_INFORMATION_LEAK
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_CHEATED
check_tx_spend
# Give it "forever" blocks.
$CLI generate 10
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok

86
daemon/test/test-unilateral Executable file
View File

@ -0,0 +1,86 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
parse_cmdline 2 "$@"
setup_lightning 2
start_lightningd 2
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
DO_RECONNECT=$RECONNECT
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
# Make sure node2 doesn't fail
lcli2 dev-routefail false
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
# This is 10,000 satoshi, so not dust!
HTLC_AMOUNT=10000000
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
B_AMOUNT=0
B_FEE=0
# Wait for both to committed.
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
# make node1 disconnect with node2.
lcli1 dev-disconnect $ID2
check_peerconnected lcli1 false
# lcli1 should have sent out commitment tx
check_peerstate lcli1 STATE_ERR_BREAKDOWN
check_tx_spend
# Mine it.
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL
# both still know about htlc
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
# Generate 6 blocks so CSV timeout has expired.
$CLI generate 6
# Now, lcli1 should spend its own output.
check_tx_spend
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
while [ $(blockheight) != $EXPIRY ]; do
$CLI generate 1
done
# lcli1 should have gotten HTLC back.
check_tx_spend
# Now, after "forever" blocks, should all be concluded.
$CLI generate 10
# Both consider it all done now.
check_no_peers lcli1
lcli1 stop
all_ok

View File

@ -1,791 +0,0 @@
#! /bin/sh -e
# Wherever we are, we want to be in daemon/test dir.
cd `git rev-parse --show-toplevel`/daemon/test
. scripts/vars.sh
. scripts/helpers.sh
# Bash variables for in-depth debugging.
#set -vx
#export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
STYLE=${1:-normal}
shift
parse_cmdline 3 "$@"
case x"$STYLE" in
x"--timeout-anchor")
TIMEOUT_ANCHOR=1
;;
x"--dump-onchain")
DUMP_ONCHAIN=1
;;
x"--steal")
STEAL=1
;;
x"--manual-commit")
MANUALCOMMIT=1
;;
x"--mutual-close-with-htlcs")
CLOSE_WITH_HTLCS=1
;;
x"--different-fee-rates")
DIFFERENT_FEES=1
;;
x"--normal")
;;
*)
echo Unknown arg "$STYLE" >&2
exit 1
;;
esac
setup_lightning 3
if [ -n "$DIFFERENT_FEES" ]; then
# Simply override default fee (estimatefee fails on regtest anyway)
DEFAULT_FEE_RATE2=50000
# We use 5x fee rate for commits, by defailt.
FEE_RATE2=$(($DEFAULT_FEE_RATE2 * 5))
echo "default-fee-rate=$DEFAULT_FEE_RATE2" >> $DIR2/config
fi
if [ -n "$MANUALCOMMIT" ]; then
# Aka. never.
echo 'commit-time=1h' >> $DIR1/config
echo 'commit-time=1h' >> $DIR2/config
echo 'commit-time=1h' >> $DIR3/config
fi
start_lightningd 3
# Check IDs match logs
[ `$LCLI1 getlog | sed -n 's/.*"ID: \([0-9a-f]*\)".*/\1/p'` = $ID1 ]
[ `$LCLI2 getlog | sed -n 's/.*"ID: \([0-9a-f]*\)".*/\1/p'` = $ID2 ]
[ $NUM_LIGHTNINGD = 2 ] || [ `$LCLI3 getlog | sed -n 's/.*"ID: \([0-9a-f]*\)".*/\1/p'` = $ID3 ]
# Make sure they see it (for timeout we need to know what height they were)
BLOCKHEIGHT=`$CLI getblockcount`
check '[ `get_info_field "$LCLI1" blockheight` = $BLOCKHEIGHT ]'
check '[ `get_info_field "$LCLI2" blockheight` = $BLOCKHEIGHT ]'
# Prevent anchor broadcast if we want to test timeout.
if [ -n "$TIMEOUT_ANCHOR" ]; then
lcli1 dev-broadcast false
fi
lcli1 connect localhost $PORT2 $FUND_INPUT_TX &
# Expect them to be waiting for anchor, and ack from other side.
check_peerstate lcli1 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
check_peerstate lcli2 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
DO_RECONNECT=$RECONNECT
if [ -n "$TIMEOUT_ANCHOR" ]; then
# Blocks before anchor committed (100 to hit chain, 1 to reach depth)
$CLI generate 100
# Still waiting.
check_peerstate lcli1 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
check_peerstate lcli2 STATE_OPEN_WAIT_ANCHORDEPTH_AND_THEIRCOMPLETE
# Make sure whichever times out first doesn't tell the other.
lcli1 dev-output $ID2 false
lcli2 dev-output $ID1 false
$CLI generate 1
# Node1 should have gone into STATE_ERR_ANCHOR_TIMEOUT.
check "lcli1 getlog debug | $FGREP STATE_ERR_ANCHOR_TIMEOUT"
# Don't try to reconnect any more if we are.
if [ x"$RECONNECT" = xreconnect ]; then DO_RECONNECT=""; fi
NO_PEER2=1
# Now let them send errors if they're still trying.
lcli2 dev-output $ID1 true || true
lcli1 dev-output $ID2 true || true
# Peer 2 should give up, and have forgotten all about it.
check "lcli2 getlog debug | $FGREP STATE_CLOSED"
check_no_peers lcli2
# Node1 should be disconnected.
check_peerconnected lcli1 false
# Now let node1 broadcast anchor and unilateral close belatedly!
lcli1 dev-broadcast true
# Now mine that transaction so they see it.
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
# Now move bitcoind 1 day, which is what node2 asked for on commit.
# Get current time from last block (works if we run this twice).
CURTIME=$($CLI getblock $($CLI getblockhash $(($BLOCKHEIGHT + 100))) | sed -n 's/ "time": \([0-9]*\),/\1/p')
$CLI setmocktime $(($CURTIME + 24 * 60 * 60))
# Move average so CSV moves.
$CLI generate 6
# Now it should have spent the commit tx.
check_tx_spend
# 100 blocks pass
$CLI generate 100
# Considers it all done now.
check_no_peers lcli1
lcli1 stop
lcli2 stop
all_ok
fi
# Now make it pass anchor (should be in mempool: one block to bury it)
check_tx_spend
$CLI generate 1
check_peerstate lcli1 STATE_NORMAL
check_peerstate lcli2 STATE_NORMAL
# We turn off routing failure for the moment.
lcli1 dev-routefail false
lcli2 dev-routefail false
if [ -n "$DIFFERENT_FEES" ]; then
# This is 100,000 satoshi, so covers fees.
HTLC_AMOUNT=100000000
# Asymmetry, since fee rates different.
NO_HTLCS_FEE2=$((338 * $FEE_RATE2 / 2000 * 2000))
ONE_HTLCS_FEE2=$(( (338 + 32) * $FEE_RATE2 / 2000 * 2000))
A_AMOUNT1=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE1=$NO_HTLCS_FEE
A_AMOUNT2=$(($AMOUNT - $NO_HTLCS_FEE2))
A_FEE2=$NO_HTLCS_FEE2
B_AMOUNT=0
B_FEE=0
check_status_single lcli1 $A_AMOUNT1 $A_FEE1 "" $B_AMOUNT $B_FEE ""
check_status_single lcli2 $B_AMOUNT $B_FEE "" $(($A_AMOUNT2)) $(($A_FEE2)) ""
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
check_status_single lcli2 0 0 "" $(($AMOUNT - $HTLC_AMOUNT - $ONE_HTLCS_FEE2)) $(($ONE_HTLCS_FEE2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } "
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
check_status_single lcli1 $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
check_status_single lcli2 $(($HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) "" $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) ""
# FIXME: reactivate feechanges!
# # Change fee rate on node2 to same as node1.
# lcli2 dev-feerate 40000
# $CLI generate 1
# [ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# [ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# check_status $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
# # Change back.
# lcli2 dev-feerate 50000
# $CLI generate 1
# [ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# [ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# check_status_single lcli1 $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) "" $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2)) $(($NO_HTLCS_FEE / 2)) ""
# check_status_single lcli2 $(($HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) "" $(($AMOUNT - $HTLC_AMOUNT - $NO_HTLCS_FEE2 / 2)) $(($NO_HTLCS_FEE2 / 2)) ""
lcli1 close $ID2
# Make sure they notice it.
check_peerstate lcli1 STATE_MUTUAL_CLOSING
check_peerstate lcli2 STATE_MUTUAL_CLOSING
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Give it 10 blocks ie "forever"
$CLI generate 10
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok
fi
A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE))
A_FEE=$NO_HTLCS_FEE
B_AMOUNT=0
B_FEE=0
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# This is 10,000 satoshi, so not dust!
HTLC_AMOUNT=10000000
EXPIRY=$(( $(blockheight) + 10))
SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd
RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
if [ -n "$MANUALCOMMIT" ]; then
# They should register a staged htlc.
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_HTLC } " $B_AMOUNT $B_FEE ""
# Now commit it.
lcli1 dev-commit $ID2
# Node 1 hasn't got it committed, but node2 should have told it to stage.
check_status_single lcli1 $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_REVOCATION } " $B_AMOUNT $B_FEE ""
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
# Node 2 has it committed.
check_status_single lcli2 $B_AMOUNT $B_FEE "" $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_REVOCATION } "
# There should be no "both committed" here yet
if lcli1 getlog debug | $FGREP "Both committed"; then
echo "Node1 thinks they are both committed";
exit 1
fi
if lcli2 getlog debug | $FGREP "Both committed"; then
echo "Node2 thinks they are both committed";
exit 1
fi
# Now node2 gives commitment to node1.
lcli2 dev-commit $ID1
# After revocation, they should know they're both committed.
check lcli1 "getlog debug | $FGREP 'Both committed to ADD of our HTLC'"
check lcli2 "getlog debug | $FGREP 'Both committed to ADD of their HTLC'"
else
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
fi
# Both should have committed tx.
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
if [ -n "$STEAL" ]; then
STEAL_TX=`$LCLI1 dev-signcommit $ID2 | cut -d\" -f4`
fi
if [ -n "$DUMP_ONCHAIN" ]; then
# make node1 disconnect with node2.
lcli1 dev-disconnect $ID2
check_peerconnected lcli1 false
# lcli1 should have sent out commitment tx
check_peerstate lcli1 STATE_ERR_BREAKDOWN
check_tx_spend
# Mine it.
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL
# both still know about htlc
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
# Generate 6 blocks so CSV timeout has expired.
$CLI generate 6
# Now, lcli1 should spend its own output.
check_tx_spend
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_OUR_UNILATERAL
while [ $(blockheight) != $EXPIRY ]; do
$CLI generate 1
done
# lcli1 should have gotten HTLC back.
check_tx_spend
# Now, after 10 blocks, should all be concluded.
$CLI generate 10
# Both consider it all done now.
check_no_peers lcli1
lcli1 stop
all_ok
fi
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Without manual commit, this check is racy.
if [ -n "$MANUALCOMMIT" ]; then
if lcli1 getlog debug | $FGREP 'Both committed to FULFILL'; then
echo "Node1 thinks they are both committed";
exit 1
fi
if lcli2 getlog debug | $FGREP 'Both committed to FULFILL'; then
echo "Node2 thinks they are both committed";
exit 1
fi
fi
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# If we're very slow, manually committed above, and we're restarting,
# we may restart *after* this and thus not see it in the log.
[ "$RECONNECT$MANUALCOMMIT" = restart1 ] || check lcli1 "getlog debug | $FGREP 'Both committed to FULFILL of our HTLC'"
check lcli2 "getlog debug | $FGREP 'Both committed to FULFILL of their HTLC'"
# We've transferred the HTLC amount to 2, who now has to pay fees,
# so no net change for A who saves on fees.
B_FEE=$HTLC_AMOUNT
# With no HTLCs, extra fee no longer required.
A_FEE=$(($A_FEE - $EXTRA_FEE - $B_FEE))
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# A new one, at 10x the amount.
HTLC_AMOUNT=100000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
lcli2 dev-failhtlc $ID1 $HTLCID 695
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# Back to how we were before.
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
A_FEE=$(($A_FEE - $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Same again, but this time it expires.
HTLC_AMOUNT=10000001
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# Check channel status
A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - $HTLC_AMOUNT))
A_FEE=$(($A_FEE + $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
# Make sure node1 accepts the expiry packet.
while [ $(blockheight) != $EXPIRY ]; do
$CLI generate 1
done
# This should make node2 send it.
$CLI generate 1
if [ -n "$MANUALCOMMIT" ]; then
check_status $A_AMOUNT $A_FEE "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_REMOVE_HTLC } " $B_AMOUNT $B_FEE ""
lcli2 dev-commit $ID1
lcli1 dev-commit $ID2
fi
# Back to how we were before.
A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + $HTLC_AMOUNT))
A_FEE=$(($A_FEE - $EXTRA_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
if [ -n "$STEAL" ]; then
# Send out old commit tx from peer 1.
$CLI sendrawtransaction $STEAL_TX
$CLI generate 1
# Node1 should get really upset; node2 should steal the transaction.
check_peerstate lcli1 STATE_ERR_INFORMATION_LEAK
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_CHEATED
check_tx_spend
# Give it "forever" blocks.
$CLI generate 10
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok
fi
# First, give more money to node2, so it can offer HTLCs.
EXPIRY=$(( $(blockheight) + 10))
HTLC_AMOUNT=100000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $B_AMOUNT $B_FEE ""
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# Both now pay equal fees.
A_FEE=$(($NO_HTLCS_FEE / 2))
B_FEE=$(($NO_HTLCS_FEE / 2))
# We transferred 10000000 before, and $HTLC_AMOUNT now.
A_AMOUNT=$(($AMOUNT - 10000000 - $HTLC_AMOUNT - $A_FEE))
B_AMOUNT=$((10000000 + $HTLC_AMOUNT - $B_FEE))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Two failures crossover
SECRET2=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfe
RHASH2=`lcli1 dev-rhash $SECRET2 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
# This means B will *just* afford it (but can't cover increased fees)
HTLC_AMOUNT=$(($B_AMOUNT - $EXTRA_FEE / 2))
HTLCID=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# Make sure that's committed, in case lcli1 restarts.
lcli2 dev-commit $ID1 >/dev/null || true
HTLCID2=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# A covers the extra part of the fee.
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE - $EXTRA_FEE / 2)) $(($A_FEE + $EXTRA_FEE + $EXTRA_FEE / 2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION } " 0 $(($B_FEE + $EXTRA_FEE / 2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } "
# Fail both, to reset.
lcli1 dev-failhtlc $ID2 $HTLCID 830
lcli2 dev-failhtlc $ID1 $HTLCID2 829
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Now, two HTLCs at once, one from each direction.
# Both sides can afford this.
HTLC_AMOUNT=1000000
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
HTLCID2=`lcli2 dev-newhtlc $ID1 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
check_status $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } " $(($B_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION } "
if [ -n "$CLOSE_WITH_HTLCS" ]; then
# Now begin close
lcli1 close $ID2
# They should be waiting for it to clear up.
check_peerstate lcli1 STATE_SHUTDOWN
check_peerstate lcli2 STATE_SHUTDOWN
# Fail one, still waiting.
lcli2 dev-failhtlc $ID1 $HTLCID 800
check_peerstate lcli1 STATE_SHUTDOWN
check_peerstate lcli2 STATE_SHUTDOWN
# Fulfill the other causes them to actually complete the close.
lcli1 dev-fulfillhtlc $ID2 $HTLCID2 $SECRET2
check_peerstate lcli1 STATE_MUTUAL_CLOSING
check_peerstate lcli2 STATE_MUTUAL_CLOSING
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Give it "forever" blocks.
$CLI generate 9
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok
fi
lcli1 dev-fulfillhtlc $ID2 $HTLCID2 $SECRET2
lcli2 dev-failhtlc $ID1 $HTLCID 849
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
# We transferred amount from B to A.
A_AMOUNT=$(($A_AMOUNT + $HTLC_AMOUNT))
B_AMOUNT=$(($B_AMOUNT - $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Now, test making more changes before receiving commit reply.
DO_RECONNECT=""
lcli2 dev-output $ID1 false
HTLCID=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH | extract_id`
# Make sure node1 sends commit (in the background, since it will block!)
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2 &
if [ -n "$MANUALCOMMIT" ]; then
# node2 will consider this committed.
check_status_single lcli2 $(($B_AMOUNT - $EXTRA_FEE/2)) $(($B_FEE + $EXTRA_FEE/2)) "" $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE/2)) $(($A_FEE + $EXTRA_FEE/2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_REVOCATION } "
else
# It will start committing by itself
check_status_single lcli2 $(($B_AMOUNT - $EXTRA_FEE/2)) $(($B_FEE + $EXTRA_FEE/2)) "" $(($A_AMOUNT - $HTLC_AMOUNT - $EXTRA_FEE/2)) $(($A_FEE + $EXTRA_FEE/2)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_COMMIT } "
fi
# node1 will still be awaiting node2's revocation reply.
check_status_single lcli1 $(($A_AMOUNT)) $(($A_FEE)) "{ msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_COMMIT } " $B_AMOUNT $B_FEE ""
# Now send another offer, and enable node2 output.
HTLCID2=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH2 | extract_id`
lcli2 dev-output $ID1 true
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
DO_RECONNECT=$RECONNECT
# Both sides should be committed to htlcs
# We open-code check_status here: HTLCs could be in either order.
check_balance_single lcli1 $(($A_AMOUNT - $HTLC_AMOUNT*2 - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE)) $(($B_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE))
check_balance_single lcli2 $(($B_AMOUNT - $EXTRA_FEE)) $(($B_FEE + $EXTRA_FEE)) $(($A_AMOUNT - $HTLC_AMOUNT*2 - $EXTRA_FEE)) $(($A_FEE + $EXTRA_FEE))
# Once both balances are correct, this should be right.
lcli1 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION } ], their_htlcs : [ ]" || lcli1 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : SENT_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : SENT_ADD_ACK_REVOCATION } ], their_htlcs : [ ]"
lcli2 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ ], their_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION } ]" || lcli2 getpeers | tr -s '\012\011" ' ' ' | $FGREP "our_htlcs : [ ], their_htlcs : [ { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH2 , state : RCVD_ADD_ACK_REVOCATION }, { msatoshi : $HTLC_AMOUNT, expiry : { block : $EXPIRY }, rhash : $RHASH , state : RCVD_ADD_ACK_REVOCATION } ]"
# Just for once, reconnect/restart node 2.
case "$RECONNECT" in
reconnect)
echo RECONNECTING NODE2
$LCLI2 dev-reconnect $ID1 >/dev/null
sleep 1
;;
restart)
echo RESTARTING NODE2
$LCLI2 -- dev-restart $LIGHTNINGD2 >/dev/null 2>&1 || true
if ! check "$LCLI2 getlog 2>/dev/null | fgrep -q Hello"; then
echo "Node2 dev-restart failed!">&2
exit 1
fi
;;
esac
if ! check "$LCLI2 getpeers | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
# Node2 collects the HTLCs.
lcli2 dev-fulfillhtlc $ID1 $HTLCID $SECRET
lcli2 dev-fulfillhtlc $ID1 $HTLCID2 $SECRET2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# We transferred 2 * amount from A to B.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT * 2))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT * 2))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
# Now, use automatic payment redemption
lcli1 dev-routefail true
lcli2 dev-routefail true
RHASH3=`lcli2 invoice $HTLC_AMOUNT RHASH3 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
lcli2 listinvoice
[ "`lcli2 listinvoice | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
HTLCID3=`lcli1 dev-newhtlc $ID2 $HTLC_AMOUNT $EXPIRY $RHASH3 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
# We transferred amount from A to B.
A_AMOUNT=$(($A_AMOUNT - $HTLC_AMOUNT))
B_AMOUNT=$(($B_AMOUNT + $HTLC_AMOUNT))
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
[ "`lcli2 listinvoice | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
# Now, failed payment (didn't pay enough)
RHASH4=`lcli2 invoice $HTLC_AMOUNT RHASH4 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
# Shouldn't have this already.
if lcli2 getlog | $FGREP 'Short payment for'; then exit 1; fi
# Test listinvoice with both, or subset (either order possible!)
INVOICES=`lcli2 listinvoice | tr -s '\012\011\" ' ' '`
[ "$INVOICES" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true }, { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ] || [ "$INVOICES" = "[ { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false }, { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli2 listinvoice RHASH3 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH3 , rhash : $RHASH3 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli2 listinvoice RHASH4 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH4 , rhash : $RHASH4 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
HTLCID4=`lcli1 dev-newhtlc $ID2 $(($HTLC_AMOUNT - 1)) $EXPIRY $RHASH4 | extract_id`
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli2 dev-commit $ID1
[ ! -n "$MANUALCOMMIT" ] || lcli1 dev-commit $ID2
check lcli2 "getlog | $FGREP 'Short payment for'"
check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE ""
lcli2 delinvoice RHASH4
if lcli2 delinvoice RHASH3 >/dev/null; then
echo "Should not be able to delete completed invoice!" >&2
exit 1
fi
if [ ! -n "$MANUALCOMMIT" ]; then
# Test routing to a third node.
P2SHADDR2=`$LCLI2 newaddr | sed -n 's/{ "address" : "\(.*\)" }/\1/p'`
TXID2=`$CLI sendtoaddress $P2SHADDR2 0.01`
TX2=`$CLI getrawtransaction $TXID2`
$CLI generate 1
lcli2 connect localhost $PORT3 $TX2 &
check_tx_spend
$CLI generate 1
# Make sure it's STATE_NORMAL.
check_peerstate lcli3 STATE_NORMAL
# More than enough to cover commit fees.
HTLC_AMOUNT=100000000
# Tell node 1 about the 2->3 route.
# Add to config in case we are restaring.
echo "add-route=$ID2/$ID3/546000/10/36/36" >> $DIR1/config
lcli1 dev-add-route $ID2 $ID3 546000 10 36 36
RHASH5=`lcli3 invoice $HTLC_AMOUNT RHASH5 | sed 's/.*"\([0-9a-f]*\)".*/\1/'`
# Get route.
ROUTE=`lcli1 getroute $ID3 $HTLC_AMOUNT 1`
ROUTE=`echo $ROUTE | sed 's/^{ "route" : \(.*\) }$/\1/'`
# Try wrong hash.
if lcli1 sendpay "$ROUTE" $RHASH4; then
echo Paid with wrong hash? >&2
exit 1
fi
# Try underpaying.
PAID=`echo "$ROUTE" | sed -n 's/.*"msatoshi" : \([0-9]*\),.*/\1/p'`
UNDERPAY=`echo "$ROUTE" | sed "s/: $PAID,/: $(($PAID - 1)),/"`
if lcli1 sendpay "$UNDERPAY" $RHASH5; then
echo Paid with too little? >&2
exit 1
fi
# If restarting, make sure node3 remembers incoming payment.
if [ "$RECONNECT" = restart ]; then
$LCLI3 -- dev-restart $LIGHTNINGD3 >/dev/null 2>&1 || true
if ! check "$LCLI3 getpeers 2>/dev/null | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
fi
[ "`lcli3 listinvoice RHASH5 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT, complete : false } ] " ]
# Pay correctly.
lcli1 sendpay "$ROUTE" $RHASH5
# Node 3 should end up with that amount (minus 1/2 tx fee)
# Note that it is delayed a little, since node2 fulfils as soon as fulfill
# starts.
check lcli3 "getpeers | $FGREP \"\\\"our_amount\\\" : $(($HTLC_AMOUNT - $NO_HTLCS_FEE / 2))\""
# If restarting, make sure node3 remembers completed payment.
if [ "$RECONNECT" = restart ]; then
echo RESTARTING NODE3
$LCLI3 -- dev-restart $LIGHTNINGD3 >/dev/null 2>&1 || true
if ! check "$LCLI3 getpeers 2>/dev/null | tr -s '\012\011\" ' ' ' | fgrep -q 'connected : true'"; then
echo "Failed to reconnect!">&2
exit 1
fi
fi
[ "`lcli3 listinvoice RHASH5 | tr -s '\012\011\" ' ' '`" = "[ { label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT, complete : true } ] " ]
[ "`lcli3 waitinvoice | tr -s '\012\011\" ' ' '`" = "{ label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT } " ]
# Can't pay twice (try from node2)
ROUTE2=`lcli2 getroute $ID3 $HTLC_AMOUNT 1`
ROUTE2=`echo $ROUTE2 | sed 's/^{ "route" : \(.*\) }$/\1/'`
if lcli2 sendpay "$ROUTE2" $RHASH5; then
echo "Paying twice worked?" >&2
exit 1
fi
lcli3 close $ID2
# Re-send should be a noop (doesn't matter that node3 is down!)
lcli1 sendpay "$ROUTE" $RHASH5
# Re-send to different id or amount should complain.
SHORTROUTE=`echo "$ROUTE" | sed 's/, { "id" : .* }//' | sed 's/"msatoshi" : [0-9]*,/"msatoshi" : '$HTLC_AMOUNT,/`
lcli1 sendpay "$SHORTROUTE" $RHASH5 | $FGREP "already succeeded to $ID3"
lcli1 sendpay "$UNDERPAY" $RHASH5 | $FGREP "already succeeded with amount $HTLC_AMOUNT"
# Now node2 should fail to route.
if lcli1 sendpay "$ROUTE" $RHASH4 | $FGREP "failed: error code 404 node $ID2 reason Unknown peer"; then : ;
else
echo "Pay to node3 didn't give 404" >&2
exit 1
fi
# Now node1 should fail to route (route deleted)
if lcli1 getroute $ID3 $HTLC_AMOUNT 1 | $FGREP "no route found"; then : ;
else
echo "Pay to node3 didn't fail instantly second time" >&2
exit 1
fi
fi
lcli1 close $ID2
# They should be negotiating the close.
check_peerstate lcli1 STATE_MUTUAL_CLOSING
check_peerstate lcli2 STATE_MUTUAL_CLOSING
$CLI generate 1
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Give it forever-1 blocks.
$CLI generate 8
# Make sure they saw it!
check_peerstate lcli1 STATE_CLOSE_ONCHAIN_MUTUAL
check_peerstate lcli2 STATE_CLOSE_ONCHAIN_MUTUAL
# Now the final one.
$CLI generate 1
check_no_peers lcli1
check_no_peers lcli2
lcli1 stop
lcli2 stop
all_ok