Skip to content

Commit b7b2257

Browse files
authored
added wallet paths to change outputs in funding tx. (#27)
* added wallet paths to change outputs in funding tx. fixed txid formatting (reversed) in debugging output. added missing redeemscripts to tx submitted to handle_sign_withdrawal marked some tests as skip when remote_hsmd because of policies marked many tests as flaky * turned off SLOW_MACHINE in run-all-tests * removed the extra flaky designations
1 parent 397550c commit b7b2257

17 files changed

+252
-132
lines changed

contrib/remote_hsmd/dump.cc

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ string dump_hex(const void *vptr, size_t sz)
4444

4545
string dump_bitcoin_txid(const struct bitcoin_txid *txid)
4646
{
47-
return dump_hex(txid->shad.sha.u.u8, sizeof(txid->shad.sha.u.u8));
47+
// reverse the bytes, a-la bitcoind
48+
struct sha256_double rev = txid->shad;
49+
reverse_bytes(rev.sha.u.u8, sizeof(rev.sha.u.u8));
50+
return dump_hex(rev.sha.u.u8, sizeof(rev.sha.u.u8));
4851
}
4952

5053
string dump_bitcoin_signature(const struct bitcoin_signature *sp)
@@ -213,6 +216,7 @@ string dump_wally_tx_witness_stack(const struct wally_tx_witness_stack *sp)
213216
string dump_wally_keypath_item(const struct wally_map_item *ip)
214217
{
215218
size_t npath = (ip->value_len - BIP32_KEY_FINGERPRINT_LEN) / sizeof(uint32_t);
219+
uint32_t * path = (uint32_t *) (ip->value + BIP32_KEY_FINGERPRINT_LEN);
216220
ostringstream ostrm;
217221
ostrm << "{ ";
218222
ostrm << "\"pubkey\":" << dump_hex(ip->key, ip->key_len);
@@ -223,9 +227,7 @@ string dump_wally_keypath_item(const struct wally_map_item *ip)
223227
for (size_t ii = 0; ii < npath; ++ii) {
224228
if (ii != 0)
225229
ostrm << ",";
226-
uint32_t pelem = *(uint32_t *)
227-
ip->value + BIP32_KEY_FINGERPRINT_LEN + ii * sizeof(uint32_t);
228-
ostrm << pelem;
230+
ostrm << le32_to_cpu(path[ii]);
229231
}
230232
ostrm << " ]";
231233
ostrm << " }";
@@ -481,3 +483,15 @@ string dump_rhashes(const struct sha256 *rhashes, size_t num_rhashes)
481483
ostrm << "]";
482484
return ostrm.str();
483485
}
486+
487+
/* <sigh>. Bitcoind represents hashes as little-endian for RPC. */
488+
void reverse_bytes(u8 *arr, size_t len)
489+
{
490+
unsigned int i;
491+
492+
for (i = 0; i < len / 2; i++) {
493+
unsigned char tmp = arr[i];
494+
arr[i] = arr[len - 1 - i];
495+
arr[len - 1 - i] = tmp;
496+
}
497+
}

contrib/remote_hsmd/dump.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,7 @@ std::string dump_wally_psbt(const struct wally_psbt *psbt);
3838
std::string dump_tx(const struct bitcoin_tx *tx);
3939
std::string dump_rhashes(const struct sha256 *rhashes, size_t num_rhashes);
4040

41+
// needed for formatting txid
42+
void reverse_bytes(u8 *arr, size_t len);
43+
4144
#endif /* LIGHTNING_CONTRIB_REMOTE_HSMD_DUMP_H */

contrib/remote_hsmd/hsmd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,11 +1288,11 @@ static struct io_plan *handle_ready_channel(struct io_conn *conn,
12881288
&push_value,
12891289
&funding_txid,
12901290
funding_txout,
1291-
local_to_self_delay,
1291+
local_to_self_delay, // locally imposed on counterparty to_self outputs
12921292
local_shutdown_script,
12931293
&remote_basepoints,
12941294
&remote_funding_pubkey,
1295-
remote_to_self_delay,
1295+
remote_to_self_delay, // counterparty imposed on our to_self outputs
12961296
remote_shutdown_script,
12971297
option_static_remotekey,
12981298
option_anchor_outputs);
@@ -1334,7 +1334,7 @@ static struct io_plan *handle_sign_withdrawal_tx(struct io_conn *conn,
13341334

13351335
u8 *** wits;
13361336
proxy_stat rv = proxy_handle_sign_withdrawal_tx(
1337-
&c->id, c->dbid, outputs, utxos, psbt, &wits);
1337+
outputs, utxos, psbt, &wits);
13381338
if (PROXY_PERMANENT(rv))
13391339
status_failed(STATUS_FAIL_INTERNAL_ERROR,
13401340
"proxy_%s failed: %s", __FUNCTION__,

contrib/remote_hsmd/proxy.cc

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern "C" {
99
#include <bitcoin/chainparams.h>
1010
#include <bitcoin/privkey.h>
1111
#include <bitcoin/psbt.h>
12+
#include <bitcoin/script.h>
1213
#include <bitcoin/short_channel_id.h>
1314
#include <bitcoin/tx.h>
1415
#include <common/derive_basepoints.h>
@@ -588,12 +589,12 @@ proxy_stat proxy_handle_ready_channel(
588589
req.set_push_value_msat(push_value->millisatoshis);
589590
marshal_outpoint(funding_txid,
590591
funding_txout, req.mutable_funding_outpoint());
591-
req.set_holder_to_self_delay(holder_to_self_delay);
592+
req.set_holder_selected_contest_delay(holder_to_self_delay);
592593
marshal_script(holder_shutdown_script,
593594
req.mutable_holder_shutdown_script());
594595
marshal_basepoints(counterparty_basepoints, counterparty_funding_pubkey,
595596
req.mutable_counterparty_basepoints());
596-
req.set_counterparty_to_self_delay(counterparty_to_self_delay);
597+
req.set_counterparty_selected_contest_delay(counterparty_to_self_delay);
597598
marshal_script(counterparty_shutdown_script,
598599
req.mutable_counterparty_shutdown_script());
599600
if (option_anchor_outputs)
@@ -623,33 +624,58 @@ proxy_stat proxy_handle_ready_channel(
623624
}
624625

625626
proxy_stat proxy_handle_sign_withdrawal_tx(
626-
struct node_id *peer_id,
627-
u64 dbid,
628627
struct bitcoin_tx_output **outputs,
629628
struct utxo **utxos,
630629
struct wally_psbt *psbt,
631630
u8 ****o_wits)
632631
{
633632
STATUS_DEBUG(
634633
"%s:%d %s { "
635-
"\"self_id\":%s, \"peer_id\":%s, \"dbid\":%" PRIu64 ", "
634+
"\"self_id\":%s, "
636635
"\"utxos\":%s, \"outputs\":%s, \"psbt\":%s }",
637636
__FILE__, __LINE__, __FUNCTION__,
638637
dump_node_id(&self_id).c_str(),
639-
dump_node_id(peer_id).c_str(),
640-
dbid,
641638
dump_utxos((const struct utxo **)utxos).c_str(),
642639
dump_bitcoin_tx_outputs(
643640
(const struct bitcoin_tx_output **)outputs).c_str(),
644641
dump_wally_psbt(psbt).c_str()
645642
);
646643

647644
last_message = "";
645+
646+
// This code is mimicking psbt_txid at bitcoin/psbt.c:796:
647+
//
648+
/* You can *almost* take txid of global tx. But @niftynei thought
649+
* about this far more than me and pointed out that P2SH
650+
* inputs would not be represented, so here we go. */
651+
struct wally_tx *tx;
652+
tal_wally_start();
653+
wally_tx_clone_alloc(psbt->tx, 0, &tx);
654+
for (size_t i = 0; i < tx->num_inputs; i++) {
655+
if (psbt->inputs[i].final_scriptsig) {
656+
wally_tx_set_input_script(tx, i,
657+
psbt->inputs[i].final_scriptsig,
658+
psbt->inputs[i].final_scriptsig_len);
659+
} else if (psbt->inputs[i].redeem_script) {
660+
u8 *script;
661+
662+
/* P2SH requires push of the redeemscript, from libwally src */
663+
script = tal_arr(tmpctx, u8, 0);
664+
script_push_bytes(&script,
665+
psbt->inputs[i].redeem_script,
666+
psbt->inputs[i].redeem_script_len);
667+
wally_tx_set_input_script(tx, i, script, tal_bytelen(script));
668+
}
669+
}
670+
tal_wally_end(tal_steal(psbt, tx));
671+
672+
648673
SignFundingTxRequest req;
649674
marshal_node_id(&self_id, req.mutable_node_id());
650-
marshal_channel_nonce(peer_id, dbid, req.mutable_channel_nonce());
651675

652-
req.mutable_tx()->set_raw_tx_bytes(serialized_wtx(psbt->tx, true));
676+
// Serialize the tx we modified above which includes witscripts.
677+
req.mutable_tx()->set_raw_tx_bytes(serialized_wtx(tx, true));
678+
653679
assert(psbt->tx->num_inputs >= tal_count(utxos));
654680
size_t uu = 0;
655681
for (size_t ii = 0; ii < psbt->tx->num_inputs; ++ii) {
@@ -664,6 +690,20 @@ proxy_stat proxy_handle_sign_withdrawal_tx(
664690
}
665691
assert(uu == tal_count(utxos));
666692

693+
for (size_t ii = 0; ii < psbt->tx->num_outputs; ++ii) {
694+
OutputDescriptor *odesc = req.mutable_tx()->add_output_descs();
695+
struct wally_map *mp = &psbt->outputs[ii].keypaths;
696+
if (mp->num_items == 1) {
697+
const struct wally_map_item *ip = &mp->items[0];
698+
size_t npath =
699+
(ip->value_len - BIP32_KEY_FINGERPRINT_LEN) / sizeof(uint32_t);
700+
uint32_t *path = (uint32_t *) (ip->value + BIP32_KEY_FINGERPRINT_LEN);
701+
for (size_t jj = 0; jj < npath; ++jj) {
702+
odesc->mutable_key_loc()->add_key_path(le32_to_cpu(path[jj]));
703+
}
704+
}
705+
}
706+
667707
ClientContext context;
668708
SignFundingTxReply rsp;
669709
Status status = stub->SignFundingTx(&context, req, &rsp);

contrib/remote_hsmd/proxy.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ proxy_stat proxy_handle_ready_channel(
7979
bool option_anchor_outputs);
8080

8181
proxy_stat proxy_handle_sign_withdrawal_tx(
82-
struct node_id *peer_id, u64 dbid,
8382
struct bitcoin_tx_output **outputs,
8483
struct utxo **utxos,
8584
struct wally_psbt *psbt,
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#!/usr/bin/sh
22

3-
4-
53
SUBDAEMON='hsmd:remote_hsmd' \
64
REMOTE_SIGNER_CMD=$(pwd)/../rust-lightning-signer/target/debug/server \
75
make \
86
-j32 PYTEST_PAR=64 \
97
DEVELOPER=1 \
108
VALGRIND=0 \
11-
SLOW_MACHINE=1 \
9+
SLOW_MACHINE=0 \
1210
PYTEST_MOREOPTS='--timeout=300 --timeout_method=thread' \
1311
pytest
1412

tests/test_closing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,6 +2430,7 @@ def test_permfail_htlc_out(node_factory, bitcoind, executor):
24302430

24312431

24322432
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1")
2433+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
24332434
def test_permfail(node_factory, bitcoind):
24342435
l1, l2 = node_factory.line_graph(2)
24352436

tests/test_connection.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,7 @@ def mock_sendrawtransaction(r):
23612361

23622362

23632363
@unittest.skipIf(not DEVELOPER, "needs dev_fail")
2364+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
23642365
def test_no_fee_estimate(node_factory, bitcoind, executor):
23652366
l1 = node_factory.get_node(start=False, options={'dev-no-fake-fees': True})
23662367

tests/test_misc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ def is_p2wpkh(output):
489489
assert only_one(fundingtx['vin'])['txid'] == res['wallettxid']
490490

491491

492+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
492493
def test_withdraw_misc(node_factory, bitcoind, chainparams):
493494
def dont_spend_outputs(n, txid):
494495
"""Reserve both outputs (we assume there are two!) in case any our ours, so we don't spend change: wrecks accounting checks"""

tests/test_plugin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,7 @@ def test_3847_repro(node_factory, bitcoind):
20412041
l1.rpc.paystatus(i1)
20422042

20432043

2044+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "trouble managing remotesigner when node killed this way")
20442045
def test_important_plugin(node_factory):
20452046
# Cache it here.
20462047
pluginsdir = os.path.join(os.path.dirname(__file__), "plugins")

tests/test_wallet.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121

2222
@unittest.skipIf(TEST_NETWORK != 'regtest', "Test relies on a number of example addresses valid only in regtest")
23+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
2324
def test_withdraw(node_factory, bitcoind):
2425
amount = 1000000
2526
# Don't get any funds from previous runs.
@@ -666,6 +667,7 @@ def test_utxopsbt(node_factory, bitcoind, chainparams):
666667
reservedok=True)
667668

668669

670+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
669671
def test_sign_and_send_psbt(node_factory, bitcoind, chainparams):
670672
"""
671673
Tests for the sign + send psbt RPCs
@@ -868,6 +870,7 @@ def test_sign_and_send_psbt(node_factory, bitcoind, chainparams):
868870
check_coin_moves(l1, 'wallet', wallet_coin_mvts, chainparams)
869871

870872

873+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
871874
def test_txsend(node_factory, bitcoind, chainparams):
872875
amount = 1000000
873876
l1 = node_factory.get_node(random_hsm=True)
@@ -1257,6 +1260,7 @@ def test_withdraw_nlocktime_fuzz(node_factory, bitcoind):
12571260
raise Exception("No transaction with fuzzed nLockTime !")
12581261

12591262

1263+
@unittest.skipIf(os.getenv('SUBDAEMON') == 'hsmd:remote_hsmd', "policy: can't withdraw to non-wallet address")
12601264
def test_multiwithdraw_simple(node_factory, bitcoind):
12611265
"""
12621266
Test simple multiwithdraw usage.

wallet/db_postgres_sqlgen.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wallet/db_sqlite3_sqlgen.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)