diff --git a/bitcoin/script.c b/bitcoin/script.c index 1b606f107..d45d1e8cf 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -259,6 +259,18 @@ u8 *bitcoin_redeem_p2wpkh(const tal_t *ctx, const struct pubkey *key) return script; } +u8 *bitcoin_scriptsig_p2sh_p2wpkh(const tal_t *ctx, const struct pubkey *key) +{ + u8 *redeemscript = bitcoin_redeem_p2wpkh(ctx, key), *script; + + /* BIP141: The scriptSig must be exactly a push of the BIP16 + * redeemScript or validation fails. */ + script = tal_arr(ctx, u8, 0); + add_push_bytes(&script, redeemscript, tal_count(redeemscript)); + tal_free(redeemscript); + return script; +} + /* Create an input which spends the p2sh-p2wpkh. */ void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx, struct bitcoin_tx_input *input, diff --git a/bitcoin/script.h b/bitcoin/script.h index b6ceb79c1..6f10be179 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -51,6 +51,9 @@ void bitcoin_witness_p2sh_p2wpkh(const tal_t *ctx, const secp256k1_ecdsa_signature *sig, const struct pubkey *key); +/* Create scriptsig for p2sh-p2wpkh */ +u8 *bitcoin_scriptsig_p2sh_p2wpkh(const tal_t *ctx, const struct pubkey *key); + /* Create scriptcode (fake witness, basically) for P2WPKH */ u8 *p2wpkh_scriptcode(const tal_t *ctx, const struct pubkey *key); diff --git a/lightningd/build_utxos.c b/lightningd/build_utxos.c index 9223852ae..a737e1175 100644 --- a/lightningd/build_utxos.c +++ b/lightningd/build_utxos.c @@ -246,20 +246,3 @@ const struct utxo **build_utxos(const tal_t *ctx, return tal_free(utxos); } - -bool bip32_pubkey(const struct ext_key *bip32_base, - struct pubkey *pubkey, u32 index) -{ - struct ext_key ext; - - assert(index < BIP32_INITIAL_HARDENED_CHILD); - if (bip32_key_from_parent(bip32_base, index, - BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) - return false; - - if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey->pubkey, - ext.pub_key, sizeof(ext.pub_key))) - return false; - return true; -} - diff --git a/lightningd/build_utxos.h b/lightningd/build_utxos.h index b00344b49..9fa0fde91 100644 --- a/lightningd/build_utxos.h +++ b/lightningd/build_utxos.h @@ -13,9 +13,4 @@ const struct utxo **build_utxos(const tal_t *ctx, /* Once we've spent them, mark them confirmed. */ void confirm_utxos(struct lightningd *ld, const struct utxo **utxos); - -struct ext_key; -bool bip32_pubkey(const struct ext_key *bip32_base, - struct pubkey *pubkey, u32 index); - #endif /* LIGHTNING_LIGHTNINGD_BUILD_UTXOS_H */ diff --git a/lightningd/funding_tx.c b/lightningd/funding_tx.c index e9d51194d..b3a12ce97 100644 --- a/lightningd/funding_tx.c +++ b/lightningd/funding_tx.c @@ -1,8 +1,10 @@ #include "funding_tx.h" #include +#include #include #include #include +#include #include #include @@ -17,7 +19,8 @@ struct bitcoin_tx *funding_tx(const tal_t *ctx, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, u64 change_satoshis, - const struct pubkey *changekey) + const struct pubkey *changekey, + const struct ext_key *bip32_base) { struct bitcoin_tx *tx = bitcoin_tx(ctx, tal_count(utxomap), change_satoshis ? 2 : 1); @@ -28,6 +31,13 @@ struct bitcoin_tx *funding_tx(const tal_t *ctx, tx->input[i].txid = utxomap[i]->txid; tx->input[i].index = utxomap[i]->outnum; tx->input[i].amount = tal_dup(tx, u64, &utxomap[i]->amount); + if (utxomap[i]->is_p2sh && bip32_base) { + struct pubkey key; + + bip32_pubkey(bip32_base, &key, utxomap[i]->keyindex); + tx->input[i].script + = bitcoin_scriptsig_p2sh_p2wpkh(tx, &key); + } } tx->output[0].amount = funding_satoshis; diff --git a/lightningd/funding_tx.h b/lightningd/funding_tx.h index acf6f60ea..5784d333a 100644 --- a/lightningd/funding_tx.h +++ b/lightningd/funding_tx.h @@ -5,6 +5,7 @@ #include struct bitcoin_tx; +struct ext_key; struct privkey; struct pubkey; struct sha256_double; @@ -20,6 +21,16 @@ struct utxo; * @remote_fundingkey: (in) remote key for 2of2 funding output. * @change_satoshis: (in) amount to send as change. * @changekey: (in) key to send change to (only used if change_satoshis != 0). + * @bip32_base: (in) bip32 base for key derivation, or NULL. + * + * If bip32_base is supplied, scriptSig will be added for p2sh inputs: this + * means our signing code will fail, but txid will be correct. If NULL, + * the txid will be incorrect, by signing will succeed. + * + * This is done because all other txs have no scriptSig (being pure Segwit) + * so our signature code simply asserts there's no scriptsig (which would + * have to be removed for signing anyway). The funding transaction is + * a special case because of the P2SH inputs. */ struct bitcoin_tx *funding_tx(const tal_t *ctx, u32 *outnum, @@ -28,5 +39,6 @@ struct bitcoin_tx *funding_tx(const tal_t *ctx, const struct pubkey *local_fundingkey, const struct pubkey *remote_fundingkey, u64 change_satoshis, - const struct pubkey *changekey); + const struct pubkey *changekey, + const struct ext_key *bip32_base); #endif /* LIGHTNING_LIGHTNINGD_FUNDING_TX_H */ diff --git a/lightningd/gossip/Makefile b/lightningd/gossip/Makefile index ab19c656a..b2a5d20a1 100644 --- a/lightningd/gossip/Makefile +++ b/lightningd/gossip/Makefile @@ -39,7 +39,7 @@ $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) : $(LIGHTNINGD_GOSSIP_CONTROL_HEADERS) lightningd/gossip-all: lightningd/lightningd_gossip $(LIGHTNINGD_GOSSIP_CLIENT_OBJS) -lightningd/lightningd_gossip: $(LIGHTNINGD_GOSSIP_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a +lightningd/lightningd_gossip: $(LIGHTNINGD_GOSSIP_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a libwallycore.a $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) lightningd/gossip/gen_gossip_control_wire.h: $(WIRE_GEN) lightningd/gossip/gossip_control_wire_csv diff --git a/lightningd/handshake/Makefile b/lightningd/handshake/Makefile index ee586910b..3a4cff2e2 100644 --- a/lightningd/handshake/Makefile +++ b/lightningd/handshake/Makefile @@ -44,7 +44,7 @@ lightningd/handshake/gen_handshake_status_wire.c: $(WIRE_GEN) lightningd/handsha LIGHTNINGD_HANDSHAKE_OBJS := $(LIGHTNINGD_HANDSHAKE_SRC:.c=.o) $(LIGHTNINGD_HANDSHAKE_GEN_SRC:.c=.o) -lightningd/lightningd_handshake: $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_HANDSHAKE_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a +lightningd/lightningd_handshake: $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_HANDSHAKE_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a libwallycore.a $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) check-source: $(LIGHTNINGD_HANDSHAKE_SRC_NOGEN:%=check-src-include-order/%) diff --git a/lightningd/handshake/test/Makefile b/lightningd/handshake/test/Makefile index 4e110267f..80f63f011 100644 --- a/lightningd/handshake/test/Makefile +++ b/lightningd/handshake/test/Makefile @@ -8,7 +8,7 @@ LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS := $(LIGHTNINGD_HANDSHAKE_TEST_OBJS:.o=) update-mocks: $(LIGHTNINGD_HANDSHAKE_TEST_SRC:%=update-mocks/%) -$(LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS): $(CCAN_OBJS) $(BITCOIN_OBJS) $(CORE_TX_OBJS) $(CORE_OBJS) $(WIRE_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) libsecp256k1.a libsodium.a utils.o $(LIGHTNINGD_HANDSHAKE_GEN_SRC:.c=.o) +$(LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS): $(CCAN_OBJS) $(BITCOIN_OBJS) $(CORE_TX_OBJS) $(CORE_OBJS) $(WIRE_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) libsecp256k1.a libsodium.a utils.o $(LIGHTNINGD_HANDSHAKE_GEN_SRC:.c=.o) libwallycore.a $(LIGHTNINGD_HANDSHAKE_TEST_OBJS): $(LIGHTNINGD_HANDSHAKE_HEADERS) $(LIGHTNINGD_LIB_HEADERS) $(BITCOIN_HEADERS) $(CORE_HEADERS) $(GEN_HEADERS) $(WIRE_HEADERS) $(CCAN_HEADERS) $(LIBBASE58_HEADERS) $(LIBSODIUM_HEADERS) diff --git a/lightningd/hsm/hsm.c b/lightningd/hsm/hsm.c index 6c30b0b35..32fc182ca 100644 --- a/lightningd/hsm/hsm.c +++ b/lightningd/hsm/hsm.c @@ -386,7 +386,8 @@ static u8 *sign_funding_tx(const tal_t *ctx, const u8 *data) tx = funding_tx(tmpctx, &outnum, utxomap, satoshi_out, &local_pubkey, &remote_pubkey, - change_out, &changekey); + change_out, &changekey, + NULL); /* Now generate signatures. */ sig = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(inputs)); diff --git a/lightningd/key_derive.c b/lightningd/key_derive.c index 808792a0f..f5aee1538 100644 --- a/lightningd/key_derive.c +++ b/lightningd/key_derive.c @@ -3,6 +3,7 @@ #include #include #include +#include /* BOLT #3: * @@ -236,3 +237,22 @@ bool derive_revocation_privkey(const struct privkey *base_secret, #endif return true; } + + +bool bip32_pubkey(const struct ext_key *bip32_base, + struct pubkey *pubkey, u32 index) +{ + struct ext_key ext; + + if (index >= BIP32_INITIAL_HARDENED_CHILD) + return false; + + if (bip32_key_from_parent(bip32_base, index, + BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) + return false; + + if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey->pubkey, + ext.pub_key, sizeof(ext.pub_key))) + return false; + return true; +} diff --git a/lightningd/key_derive.h b/lightningd/key_derive.h index 13e1a7030..a46a5bde1 100644 --- a/lightningd/key_derive.h +++ b/lightningd/key_derive.h @@ -25,4 +25,8 @@ bool derive_revocation_privkey(const struct privkey *base_secret, const struct pubkey *per_commitment_point, struct privkey *key); + +struct ext_key; +bool bip32_pubkey(const struct ext_key *bip32_base, + struct pubkey *pubkey, u32 index); #endif /* LIGHTNING_LIGHTNINGD_KEY_DERIVE_H */ diff --git a/lightningd/opening/Makefile b/lightningd/opening/Makefile index a93ccebe0..bf25cabef 100644 --- a/lightningd/opening/Makefile +++ b/lightningd/opening/Makefile @@ -50,7 +50,7 @@ lightningd/opening/gen_opening_status_wire.c: $(WIRE_GEN) lightningd/opening/ope LIGHTNINGD_OPENING_OBJS := $(LIGHTNINGD_OPENING_SRC:.c=.o) $(LIGHTNINGD_OPENING_GEN_SRC:.c=.o) -lightningd/lightningd_opening: $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_OPENING_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a +lightningd/lightningd_opening: $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_OPENING_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a libsodium.a libwallycore.a $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) check-source: $(LIGHTNINGD_OPENING_SRC_NOGEN:%=check-src-include-order/%) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index aeee6ab2f..1642f35ac 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -18,12 +18,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include static void destroy_peer(struct peer *peer) @@ -583,7 +583,8 @@ static void opening_gen_funding(struct subdaemon *opening, const u8 *resp, fc->funding_tx = funding_tx(fc, &outnum, fc->utxomap, fc->satoshi, &fc->local_fundingkey, &fc->remote_fundingkey, - fc->change, &changekey); + fc->change, &changekey, + fc->peer->ld->bip32_base); bitcoin_txid(fc->funding_tx, &txid); msg = towire_opening_open_funding(fc, &txid, outnum); diff --git a/lightningd/test/Makefile b/lightningd/test/Makefile index 707fc390e..00c4a1efb 100644 --- a/lightningd/test/Makefile +++ b/lightningd/test/Makefile @@ -8,7 +8,7 @@ LIGHTNINGD_TEST_PROGRAMS := $(LIGHTNINGD_TEST_OBJS:.o=) update-mocks: $(LIGHTNINGD_TEST_SRC:%=update-mocks/%) -$(LIGHTNINGD_TEST_PROGRAMS): $(CCAN_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) utils.o libsecp256k1.a libsodium.a +$(LIGHTNINGD_TEST_PROGRAMS): $(CCAN_OBJS) $(CORE_OBJS) $(CORE_TX_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(LIBBASE58_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) utils.o libsecp256k1.a libsodium.a libwallycore.a $(LIGHTNINGD_TEST_OBJS): $(LIGHTNINGD_HEADERS) $(LIGHTNINGD_SRC) $(LIGHTNINGD_LIB_SRC) diff --git a/lightningd/test/run-funding_tx.c b/lightningd/test/run-funding_tx.c index 6a059a535..b883f2887 100644 --- a/lightningd/test/run-funding_tx.c +++ b/lightningd/test/run-funding_tx.c @@ -8,6 +8,8 @@ #include #define SUPERVERBOSE printf #include "../funding_tx.c" +#undef SUPERVERBOSE + #include "../key_derive.c" #if 0 static struct sha256 sha256_from_hex(const char *hex) @@ -93,6 +95,7 @@ int main(void) bitcoin_txid(input, &utxo.txid); utxo.outnum = 0; utxo.amount = 5000000000; + utxo.is_p2sh = false; funding_satoshis = 10000000; fee = 13920; @@ -108,7 +111,7 @@ int main(void) &local_funding_pubkey, &remote_funding_pubkey, utxo.amount - fee - funding_satoshis, - &inputkey); + &inputkey, NULL); printf("# fee: %"PRIu64"\n", fee); printf("change satoshis: %"PRIu64"\n", funding->output[!funding_outnum].amount);