@ -1,13 +1,16 @@
from decimal import Decimal
from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK
from flaky import flaky # noqa: F401
from lightning import RpcError , Millisatoshi
from utils import only_one , wait_for , sync_blockheight
import pytest
import time
import unittest
@unittest . skipIf ( TEST_NETWORK != ' regtest ' , " Test relies on a number of example addresses valid only in regtest " )
def test_withdraw ( node_factory , bitcoind ) :
amount = 1000000
# Don't get any funds from previous runs.
@ -213,9 +216,10 @@ def test_addfunds_from_block(node_factory, bitcoind):
assert output [ ' address ' ] == addr
def test_txprepare ( node_factory , bitcoind ) :
def test_txprepare ( node_factory , bitcoind , chainparams ) :
amount = 1000000
l1 = node_factory . get_node ( random_hsm = True )
addr = chainparams [ ' example_addr ' ]
# Add some funds to withdraw later: both bech32 and p2sh
for i in range ( 5 ) :
@ -227,59 +231,54 @@ def test_txprepare(node_factory, bitcoind):
bitcoind . generate_block ( 1 )
wait_for ( lambda : len ( l1 . rpc . listfunds ( ) [ ' outputs ' ] ) == 10 )
prep = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : Millisatoshi ( amount * 3 * 1000 ) } ] )
prep = l1 . rpc . txprepare ( [ { addr : Millisatoshi ( amount * 3 * 1000 ) } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep [ ' txid ' ]
# 4 inputs, 2 outputs.
# 4 inputs, 2 outputs (3 if we have a fee output) .
assert len ( decode [ ' vin ' ] ) == 4
assert len ( decode [ ' vout ' ] ) == 2
assert len ( decode [ ' vout ' ] ) == 2 if not chainparams [ ' feeoutput ' ] else 3
# One output will be correct.
if decode [ ' vout ' ] [ 0 ] [ ' value ' ] == Decimal ( amount * 3 ) / 10 * * 8 :
outnum = 0
changenum = 1
elif decode [ ' vout ' ] [ 1 ] [ ' value ' ] == Decimal ( amount * 3 ) / 10 * * 8 :
outnum = 1
changenum = 0
else :
assert False
assert decode [ ' vout ' ] [ outnum ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ outnum ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
outnum = [ i for i , o in enumerate ( decode [ ' vout ' ] ) if o [ ' value ' ] == Decimal ( amount * 3 ) / 10 * * 8 ] [ 0 ]
assert decode [ ' vout ' ] [ changenum ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
for i , o in enumerate ( decode [ ' vout ' ] ) :
if i == outnum :
assert o [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert o [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
else :
assert o [ ' scriptPubKey ' ] [ ' type ' ] in [ ' witness_v0_keyhash ' , ' fee ' ]
# Now prepare one with no change.
prep2 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep2 = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep2 [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep2 [ ' txid ' ]
# 6 inputs, 1 outputs.
assert len ( decode [ ' vin ' ] ) == 6
assert len ( decode [ ' vout ' ] ) == 1
assert len ( decode [ ' vout ' ] ) == 1 if not chainparams [ ' feeoutput ' ] else 2
# Some fees will be paid.
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] < Decimal ( amount * 6 ) / 10 * * 8
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] > Decimal ( amount * 6 ) / 10 * * 8 - Decimal ( 0.0002 )
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
# If I cancel the first one, I can get those first 4 outputs.
discard = l1 . rpc . txdiscard ( prep [ ' txid ' ] )
assert discard [ ' txid ' ] == prep [ ' txid ' ]
assert discard [ ' unsigned_tx ' ] == prep [ ' unsigned_tx ' ]
prep3 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep3 = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep3 [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep3 [ ' txid ' ]
# 4 inputs, 1 outputs.
assert len ( decode [ ' vin ' ] ) == 4
assert len ( decode [ ' vout ' ] ) == 1
assert len ( decode [ ' vout ' ] ) == 1 if not chainparams [ ' feeoutput ' ] else 2
# Some fees will be taken
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] < Decimal ( amount * 4 ) / 10 * * 8
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] > Decimal ( amount * 4 ) / 10 * * 8 - Decimal ( 0.0002 )
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
# Cannot discard twice.
with pytest . raises ( RpcError , match = r ' not an unreleased txid ' ) :
@ -288,24 +287,24 @@ def test_txprepare(node_factory, bitcoind):
# Discard everything, we should now spend all inputs.
l1 . rpc . txdiscard ( prep2 [ ' txid ' ] )
l1 . rpc . txdiscard ( prep3 [ ' txid ' ] )
prep4 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep4 = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep4 [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep4 [ ' txid ' ]
# 10 inputs, 1 outputs.
assert len ( decode [ ' vin ' ] ) == 10
assert len ( decode [ ' vout ' ] ) == 1
assert len ( decode [ ' vout ' ] ) == 1 if not chainparams [ ' feeoutput ' ] else 2
# Some fees will be taken
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] < Decimal ( amount * 10 ) / 10 * * 8
assert decode [ ' vout ' ] [ 0 ] [ ' value ' ] > Decimal ( amount * 10 ) / 10 * * 8 - Decimal ( 0.0003 )
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
assert decode [ ' vout ' ] [ 0 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
l1 . rpc . txdiscard ( prep4 [ ' txid ' ] )
# Try passing in a utxo set
utxos = [ utxo [ " txid " ] + " : " + str ( utxo [ " output " ] ) for utxo in l1 . rpc . listfunds ( ) [ " outputs " ] ] [ : 4 ]
prep5 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' :
prep5 = l1 . rpc . txprepare ( [ { addr :
Millisatoshi ( amount * 3.5 * 1000 ) } ] , utxos = utxos )
decode = bitcoind . rpc . decoderawtransaction ( prep5 [ ' unsigned_tx ' ] )
@ -318,26 +317,26 @@ def test_txprepare(node_factory, bitcoind):
assert utxo in vins
# We should have a change output, so this is exact
assert len ( decode [ ' vout ' ] ) == 2
assert len ( decode [ ' vout ' ] ) == 3 if chainparams [ ' feeoutput ' ] else 2
assert decode [ ' vout ' ] [ 1 ] [ ' value ' ] == Decimal ( amount * 3.5 ) / 10 * * 8
assert decode [ ' vout ' ] [ 1 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ 1 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
assert decode [ ' vout ' ] [ 1 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
# Discard prep4 and get all funds again
l1 . rpc . txdiscard ( prep5 [ ' txid ' ] )
with pytest . raises ( RpcError , match = r ' this destination wants all satoshi. The count of outputs can \' t be more than 1 ' ) :
prep5 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : Millisatoshi ( amount * 3 * 1000 ) } ,
{ ' bcrt1qw508 d6qejxt dg4y5 r3zarvary0c5xw7kygt080 ' : ' all ' } ] )
prep5 = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : Millisatoshi ( amount * 3 * 500 + 100000 ) } ,
{ ' bcrt1qw508 d6qejxt dg4y5 r3zarvary0c5xw7kygt080 ' : Millisatoshi ( amount * 3 * 500 - 100000 ) } ] )
prep5 = l1 . rpc . txprepare ( [ { addr : Millisatoshi ( amount * 3 * 1000 ) } ,
{ a ddr: ' all ' } ] )
prep5 = l1 . rpc . txprepare ( [ { addr : Millisatoshi ( amount * 3 * 500 + 100000 ) } ,
{ a ddr: Millisatoshi ( amount * 3 * 500 - 100000 ) } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep5 [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep5 [ ' txid ' ]
# 4 inputs, 3 outputs(include change).
assert len ( decode [ ' vin ' ] ) == 4
assert len ( decode [ ' vout ' ] ) == 3
assert len ( decode [ ' vout ' ] ) == 4 if chainparams [ ' feeoutput ' ] else 3
# One output will be correct.
for i in range ( 3 ) :
for i in range ( 3 + chainparams [ ' feeoutput ' ] ) :
if decode [ ' vout ' ] [ i - 1 ] [ ' value ' ] == Decimal ( ' 0.01500100 ' ) :
outnum1 = i - 1
elif decode [ ' vout ' ] [ i - 1 ] [ ' value ' ] == Decimal ( ' 0.01499900 ' ) :
@ -346,17 +345,18 @@ def test_txprepare(node_factory, bitcoind):
changenum = i - 1
assert decode [ ' vout ' ] [ outnum1 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ outnum1 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' ]
assert decode [ ' vout ' ] [ outnum1 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ addr ]
assert decode [ ' vout ' ] [ outnum2 ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
assert decode [ ' vout ' ] [ outnum2 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ ' bcrt1qw508 d6qejxt dg4y5 r3zarvary0c5xw7kygt080 ' ]
assert decode [ ' vout ' ] [ outnum2 ] [ ' scriptPubKey ' ] [ ' addresses ' ] == [ a ddr]
assert decode [ ' vout ' ] [ changenum ] [ ' scriptPubKey ' ] [ ' type ' ] == ' witness_v0_keyhash '
def test_txsend ( node_factory , bitcoind ) :
def test_txsend ( node_factory , bitcoind , chainparams ) :
amount = 1000000
l1 = node_factory . get_node ( random_hsm = True )
addr = chainparams [ ' example_addr ' ]
# Add some funds to withdraw later: both bech32 and p2sh
for i in range ( 5 ) :
@ -367,7 +367,7 @@ def test_txsend(node_factory, bitcoind):
bitcoind . generate_block ( 1 )
wait_for ( lambda : len ( l1 . rpc . listfunds ( ) [ ' outputs ' ] ) == 10 )
prep = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : Millisatoshi ( amount * 3 * 1000 ) } ] )
prep = l1 . rpc . txprepare ( [ { addr : Millisatoshi ( amount * 3 * 1000 ) } ] )
out = l1 . rpc . txsend ( prep [ ' txid ' ] )
# Cannot discard after send!
@ -397,9 +397,10 @@ def test_txsend(node_factory, bitcoind):
assert decode [ ' vout ' ] [ changenum ] [ ' scriptPubKey ' ] [ ' addresses ' ] [ 0 ] in [ f [ ' address ' ] for f in l1 . rpc . listfunds ( ) [ ' outputs ' ] ]
def test_txprepare_restart ( node_factory , bitcoind ) :
def test_txprepare_restart ( node_factory , bitcoind , chainparams ) :
amount = 1000000
l1 = node_factory . get_node ( may_fail = True )
addr = chainparams [ ' example_addr ' ]
# Add some funds to withdraw later: both bech32 and p2sh
for i in range ( 5 ) :
@ -410,7 +411,7 @@ def test_txprepare_restart(node_factory, bitcoind):
bitcoind . generate_block ( 1 )
wait_for ( lambda : [ o [ ' status ' ] for o in l1 . rpc . listfunds ( ) [ ' outputs ' ] ] == [ ' confirmed ' ] * 10 )
prep = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep [ ' txid ' ]
# All 10 inputs
@ -425,7 +426,7 @@ def test_txprepare_restart(node_factory, bitcoind):
with pytest . raises ( RpcError , match = r ' not an unreleased txid ' ) :
l1 . rpc . txdiscard ( prep [ ' txid ' ] )
prep = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep [ ' txid ' ]
@ -442,7 +443,7 @@ def test_txprepare_restart(node_factory, bitcoind):
for i in decode [ ' vin ' ] :
assert l1 . daemon . is_in_log ( ' wallet: reserved output {} / {} reset to available ' . format ( i [ ' txid ' ] , i [ ' vout ' ] ) )
prep = l1 . rpc . txprepare ( [ { ' bcrt1qeyyk6sl5pr49ycpqyckvmttus5ttj25pd0zpvg ' : ' all ' } ] )
prep = l1 . rpc . txprepare ( [ { addr : ' all ' } ] )
decode = bitcoind . rpc . decoderawtransaction ( prep [ ' unsigned_tx ' ] )
assert decode [ ' txid ' ] == prep [ ' txid ' ]
# All 10 inputs