44from fixtures import TEST_NETWORK
55from flaky import flaky # noqa: F401
66from lightning import RpcError
7- from utils import DEVELOPER , only_one , wait_for , sync_blockheight , VALGRIND , TIMEOUT , SLOW_MACHINE , COMPAT , expected_features
7+ from utils import DEVELOPER , only_one , wait_for , sync_blockheight , VALGRIND , TIMEOUT , SLOW_MACHINE , COMPAT , expected_features , EXPERIMENTAL_FEATURES
88from bitcoin .core import CMutableTransaction , CMutableTxOut
99
1010import binascii
@@ -1110,12 +1110,16 @@ def test_funding_cancel_race(node_factory, bitcoind, executor):
11101110
11111111
11121112@unittest .skipIf (TEST_NETWORK != 'regtest' , "External wallet support doesn't work with elements yet." )
1113+ @unittest .skipIf (not EXPERIMENTAL_FEATURES , "Dual funding needs experimental" )
11131114def test_funding_close_upfront (node_factory , bitcoind ):
11141115 l1 = node_factory .get_node ()
11151116
11161117 opts = {'plugin' : os .path .join (os .getcwd (), 'tests/plugins/accepter_close_to.py' )}
11171118 l2 = node_factory .get_node (options = opts )
11181119
1120+ l1 .fundwallet (100000000 )
1121+ l2 .fundwallet (100000000 )
1122+
11191123 # The 'accepter_close_to' plugin uses the channel funding amount to determine
11201124 # whether or not to include a 'close_to' address
11211125 amt_normal = 100007 # continues without returning a close_to
@@ -1128,44 +1132,31 @@ def _fundchannel(l1, l2, amount, close_to):
11281132 assert (l1 .rpc .listpeers ()['peers' ][0 ]['id' ] == l2 .info ['id' ])
11291133
11301134 resp = l1 .rpc .fundchannel_start (l2 .info ['id' ], amount , close_to = close_to )
1131- address = resp ['funding_address' ]
1135+ funding_addr = resp ['funding_address' ]
11321136
11331137 if close_to :
11341138 assert resp ['close_to' ]
11351139 else :
11361140 assert 'close_to' not in resp
11371141
1138- peer = l1 .rpc .listpeers ()['peers' ][0 ]
1139- # Peer should still be connected and in state waiting for funding_txid
1140- assert peer ['id' ] == l2 .info ['id' ]
1141- r = re .compile ('Funding channel start: awaiting funding_txid with output to .*' )
1142- assert any (r .match (line ) for line in peer ['channels' ][0 ]['status' ])
1143- assert 'OPENINGD' in peer ['channels' ][0 ]['state' ]
1144-
1145- # 'Externally' fund the address from fundchannel_start
1146- addr_scriptpubkey = bitcoind .rpc .getaddressinfo (address )['scriptPubKey' ]
1147- txout = CMutableTxOut (amount , bytearray .fromhex (addr_scriptpubkey ))
1148- unfunded_tx = CMutableTransaction ([], [txout ])
1149- hextx = binascii .hexlify (unfunded_tx .serialize ()).decode ('utf8' )
1150-
1151- funded_tx_obj = bitcoind .rpc .fundrawtransaction (hextx )
1152- raw_funded_tx = funded_tx_obj ['hex' ]
1153- txid = bitcoind .rpc .decoderawtransaction (raw_funded_tx )['txid' ]
1154- txout = 1 if funded_tx_obj ['changepos' ] == 0 else 0
1142+ prep = l1 .rpc .txprepare ([{funding_addr : amount }], zero_out_change = True )
1143+ decode = bitcoind .rpc .decoderawtransaction (prep ['unsigned_tx' ])
1144+ assert decode ['txid' ] == prep ['txid' ]
11551145
1156- assert l1 .rpc .fundchannel_complete (l2 .info ['id' ], txid , txout )['commitments_secured' ]
1157-
1158- # Broadcast the transaction manually and confirm that channel locks in
1159- signed_tx = bitcoind .rpc .signrawtransactionwithwallet (raw_funded_tx )['hex' ]
1160- assert txid == bitcoind .rpc .decoderawtransaction (signed_tx )['txid' ]
1146+ # One output will be correct.
1147+ if decode ['vout' ][0 ]['value' ] == Decimal (str (amount / 10 ** 8 )):
1148+ txout = 0
1149+ elif decode ['vout' ][1 ]['value' ] == Decimal (str (amount / 10 ** 8 )):
1150+ txout = 1
1151+ else :
1152+ assert False
11611153
1162- bitcoind .rpc .sendrawtransaction (signed_tx )
1154+ txid = l1 .rpc .fundchannel_complete (l2 .info ['id' ], prep ['txid' ], txout )['txid' ]
1155+ l1 .rpc .txsend (txid )
11631156 bitcoind .generate_block (1 )
11641157
11651158 for node in [l1 , l2 ]:
11661159 node .daemon .wait_for_log (r'State changed from CHANNELD_AWAITING_LOCKIN to CHANNELD_NORMAL' )
1167- channel = node .rpc .listpeers ()['peers' ][0 ]['channels' ][- 1 ]
1168- assert amount * 1000 == channel ['msatoshi_total' ]
11691160
11701161 # check that normal peer close works
11711162 _fundchannel (l1 , l2 , amt_normal , None )
@@ -1184,9 +1175,11 @@ def _fundchannel(l1, l2, amount, close_to):
11841175 addr = bitcoind .rpc .getnewaddress ()
11851176 _fundchannel (l1 , l2 , amt_normal , addr )
11861177 assert addr == only_one (l1 .rpc .listpeers ()['peers' ])['channels' ][2 ]['close_to_addr' ]
1178+ l2_close_to_addr = l2 .rpc .listpeers ()['peers' ][0 ]['channels' ][- 1 ]['close_to_addr' ]
11871179 resp = l1 .rpc .close (l2 .info ['id' ], destination = addr )
11881180 assert resp ['type' ] == 'mutual'
1189- assert only_one (only_one (bitcoind .rpc .decoderawtransaction (resp ['tx' ])['vout' ])['scriptPubKey' ]['addresses' ]) == addr
1181+ for vout in bitcoind .rpc .decoderawtransaction (resp ['tx' ])['vout' ]:
1182+ assert only_one (vout ['scriptPubKey' ]['addresses' ]) in [addr , l2_close_to_addr ]
11901183
11911184 # check that remote peer closing works as expected (and that remote's close_to works)
11921185 _fundchannel (l1 , l2 , amt_addr , addr )
0 commit comments