mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
lightningd/channel: generate htlc txs and wscripts as well.
In practice, this is what we want, either to generate or check signatures. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
dd1a81d8bd
commit
075092411e
@ -3,6 +3,8 @@
|
||||
#include "type_to_string.h"
|
||||
#include <assert.h>
|
||||
#include <bitcoin/preimage.h>
|
||||
#include <bitcoin/script.h>
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/structeq/structeq.h>
|
||||
@ -10,6 +12,7 @@
|
||||
#include <daemon/htlc.h>
|
||||
#include <inttypes.h>
|
||||
#include <lightningd/channel_config.h>
|
||||
#include <lightningd/htlc_tx.h>
|
||||
#include <lightningd/key_derive.h>
|
||||
#include <lightningd/status.h>
|
||||
#include <string.h>
|
||||
@ -110,6 +113,8 @@ struct channel *new_channel(const tal_t *ctx,
|
||||
const struct channel_config *remote,
|
||||
const struct basepoints *local_basepoints,
|
||||
const struct basepoints *remote_basepoints,
|
||||
const struct pubkey *local_funding_pubkey,
|
||||
const struct pubkey *remote_funding_pubkey,
|
||||
enum side funder)
|
||||
{
|
||||
struct channel *channel = tal(ctx, struct channel);
|
||||
@ -126,6 +131,8 @@ struct channel *new_channel(const tal_t *ctx,
|
||||
channel->funder = funder;
|
||||
channel->config[LOCAL] = local;
|
||||
channel->config[REMOTE] = remote;
|
||||
channel->funding_pubkey[LOCAL] = *local_funding_pubkey;
|
||||
channel->funding_pubkey[REMOTE] = *remote_funding_pubkey;
|
||||
htlc_map_init(&channel->htlcs);
|
||||
|
||||
channel->view[LOCAL].feerate_per_kw
|
||||
@ -154,14 +161,78 @@ struct channel *new_channel(const tal_t *ctx,
|
||||
return channel;
|
||||
}
|
||||
|
||||
/* FIXME: We could cache this. */
|
||||
struct bitcoin_tx *channel_tx(const tal_t *ctx,
|
||||
const struct channel *channel,
|
||||
const struct pubkey *per_commitment_point,
|
||||
const struct htlc ***htlcmap,
|
||||
enum side side)
|
||||
static void add_htlcs(struct bitcoin_tx ***txs,
|
||||
const u8 ***wscripts,
|
||||
const struct htlc **htlcmap,
|
||||
const struct channel *channel,
|
||||
const struct pubkey *side_payment_key,
|
||||
const struct pubkey *other_payment_key,
|
||||
const struct pubkey *side_revocation_key,
|
||||
const struct pubkey *side_delayed_payment_key,
|
||||
enum side side)
|
||||
{
|
||||
struct bitcoin_tx *tx;
|
||||
size_t i, n;
|
||||
struct sha256_double txid;
|
||||
u32 feerate_per_kw = channel->view[side].feerate_per_kw;
|
||||
|
||||
/* Get txid of commitment transaction */
|
||||
bitcoin_txid((*txs)[0], &txid);
|
||||
|
||||
for (i = 0; i < tal_count(htlcmap); i++) {
|
||||
const struct htlc *htlc = htlcmap[i];
|
||||
struct bitcoin_tx *tx;
|
||||
u8 *wscript;
|
||||
|
||||
if (!htlc)
|
||||
continue;
|
||||
|
||||
if (htlc_owner(htlc) == side) {
|
||||
tx = htlc_timeout_tx(*txs, &txid, i,
|
||||
htlc,
|
||||
to_self_delay(channel, side),
|
||||
side_revocation_key,
|
||||
side_delayed_payment_key,
|
||||
feerate_per_kw);
|
||||
wscript = bitcoin_wscript_htlc_offer(*wscripts,
|
||||
side_payment_key,
|
||||
other_payment_key,
|
||||
&htlc->rhash,
|
||||
side_revocation_key);
|
||||
} else {
|
||||
tx = htlc_success_tx(*txs, &txid, i,
|
||||
htlc,
|
||||
to_self_delay(channel, side),
|
||||
side_revocation_key,
|
||||
side_delayed_payment_key,
|
||||
feerate_per_kw);
|
||||
wscript = bitcoin_wscript_htlc_receive(*wscripts,
|
||||
&htlc->expiry,
|
||||
side_payment_key,
|
||||
other_payment_key,
|
||||
&htlc->rhash,
|
||||
side_revocation_key);
|
||||
}
|
||||
|
||||
/* Append to array. */
|
||||
n = tal_count(*txs);
|
||||
assert(n == tal_count(*wscripts));
|
||||
|
||||
tal_resize(wscripts, n+1);
|
||||
tal_resize(txs, n+1);
|
||||
(*wscripts)[n] = wscript;
|
||||
(*txs)[n] = tx;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: We could cache these. */
|
||||
struct bitcoin_tx **channel_txs(const tal_t *ctx,
|
||||
const struct htlc ***htlcmap,
|
||||
const u8 ***wscripts,
|
||||
const struct channel *channel,
|
||||
const struct pubkey *per_commitment_point,
|
||||
enum side side)
|
||||
{
|
||||
struct bitcoin_tx **txs;
|
||||
const struct htlc **committed;
|
||||
/* Payment keys for @side and !@side */
|
||||
struct pubkey side_payment_key, other_payment_key;
|
||||
@ -193,7 +264,12 @@ struct bitcoin_tx *channel_tx(const tal_t *ctx,
|
||||
/* Figure out what @side will already be committed to. */
|
||||
gather_htlcs(ctx, channel, side, &committed, NULL, NULL);
|
||||
|
||||
tx = commit_tx(ctx, &channel->funding_txid,
|
||||
/* NULL map only allowed at beginning, when we know no HTLCs */
|
||||
if (!htlcmap)
|
||||
assert(tal_count(committed) == 0);
|
||||
|
||||
txs = tal_arr(ctx, struct bitcoin_tx *, 1);
|
||||
txs[0] = commit_tx(ctx, &channel->funding_txid,
|
||||
channel->funding_txout,
|
||||
channel->funding_msat / 1000,
|
||||
channel->funder,
|
||||
@ -212,8 +288,19 @@ struct bitcoin_tx *channel_tx(const tal_t *ctx,
|
||||
^ channel->commitment_number_obscurer,
|
||||
side);
|
||||
|
||||
*wscripts = tal_arr(ctx, const u8 *, 1);
|
||||
(*wscripts)[0] = bitcoin_redeem_2of2(*wscripts,
|
||||
&channel->funding_pubkey[side],
|
||||
&channel->funding_pubkey[!side]);
|
||||
|
||||
if (htlcmap)
|
||||
add_htlcs(&txs, wscripts, *htlcmap, channel,
|
||||
&side_payment_key, &other_payment_key,
|
||||
&side_revocation_key, &side_delayed_payment_key,
|
||||
side);
|
||||
|
||||
tal_free(committed);
|
||||
return tx;
|
||||
return txs;
|
||||
}
|
||||
|
||||
struct channel *copy_channel(const tal_t *ctx, const struct channel *old)
|
||||
|
@ -29,6 +29,9 @@ struct channel {
|
||||
struct sha256_double funding_txid;
|
||||
unsigned int funding_txout;
|
||||
|
||||
/* Keys used to spend funding tx. */
|
||||
struct pubkey funding_pubkey[NUM_SIDES];
|
||||
|
||||
/* Millisatoshis in from commitment tx */
|
||||
u64 funding_msat;
|
||||
|
||||
@ -126,6 +129,8 @@ static inline u16 to_self_delay(const struct channel *channel, enum side side)
|
||||
* @remote: remote channel configuration
|
||||
* @local_basepoints: local basepoints.
|
||||
* @remote_basepoints: remote basepoints.
|
||||
* @local_fundingkey: local funding key
|
||||
* @remote_fundingkey: remote funding key
|
||||
* @funder: which side initiated it.
|
||||
*
|
||||
* Returns state, or NULL if malformed.
|
||||
@ -140,24 +145,30 @@ struct channel *new_channel(const tal_t *ctx,
|
||||
const struct channel_config *remote,
|
||||
const struct basepoints *local_basepoints,
|
||||
const struct basepoints *remote_basepoints,
|
||||
const struct pubkey *local_funding_pubkey,
|
||||
const struct pubkey *remote_funding_pubkey,
|
||||
enum side funder);
|
||||
|
||||
/**
|
||||
* channel_tx: Get the current commitment transaction for the channel.
|
||||
* channel_txs: Get the current commitment and htlc txs for the channel.
|
||||
* @ctx: tal context to allocate return value from.
|
||||
* @channel: The channel to evaluate
|
||||
* @per_commitment_point: Per-commitment point to determine keys
|
||||
* @htlc_map: Pointer to htlcs for each tx output (allocated off @ctx) or NULL.
|
||||
* @wscripts: Pointer to array of wscript for each tx returned (alloced off @ctx)
|
||||
* @per_commitment_point: Per-commitment point to determine keys
|
||||
* @side: which side to get the commitment transaction for
|
||||
*
|
||||
* Returns the unsigned commitment transaction for the committed state
|
||||
* for @side and fills in @htlc_map (if not NULL), or NULL on key
|
||||
* derivation failure.
|
||||
* for @side, followed by the htlc transactions in output order, and
|
||||
* fills in @htlc_map (if not NULL), or NULL on key derivation
|
||||
* failure.
|
||||
*/
|
||||
struct bitcoin_tx *channel_tx(const tal_t *ctx,
|
||||
const struct channel *channel,
|
||||
const struct pubkey *per_commitment_point,
|
||||
const struct htlc ***htlcmap,
|
||||
enum side side);
|
||||
struct bitcoin_tx **channel_txs(const tal_t *ctx,
|
||||
const struct htlc ***htlcmap,
|
||||
const u8 ***wscripts,
|
||||
const struct channel *channel,
|
||||
const struct pubkey *per_commitment_point,
|
||||
enum side side);
|
||||
|
||||
/**
|
||||
* actual_feerate: what is the actual feerate for the local side.
|
||||
|
@ -43,7 +43,6 @@ struct peer {
|
||||
struct channel_config conf[NUM_SIDES];
|
||||
struct pubkey next_per_commit[NUM_SIDES];
|
||||
bool funding_locked[NUM_SIDES];
|
||||
struct pubkey funding_pubkey[NUM_SIDES];
|
||||
|
||||
/* Their sig for current commit. */
|
||||
secp256k1_ecdsa_signature their_commit_sig;
|
||||
@ -143,8 +142,8 @@ static void send_channel_announcement(struct peer *peer)
|
||||
&peer->announcement_bitcoin_sigs[first],
|
||||
&peer->announcement_bitcoin_sigs[second],
|
||||
&peer->short_channel_ids[LOCAL], &peer->node_ids[first],
|
||||
&peer->node_ids[second], &peer->funding_pubkey[first],
|
||||
&peer->funding_pubkey[second], features);
|
||||
&peer->node_ids[second], &peer->channel->funding_pubkey[first],
|
||||
&peer->channel->funding_pubkey[second], features);
|
||||
|
||||
msg_enqueue(&peer->peer_out, cannounce);
|
||||
daemon_conn_send(&peer->gossip_client, take(cannounce));
|
||||
@ -232,6 +231,7 @@ static void init_channel(struct peer *peer, const u8 *msg)
|
||||
u32 feerate;
|
||||
u64 funding_satoshi, push_msat;
|
||||
u16 funding_txout;
|
||||
struct pubkey funding_pubkey[NUM_SIDES];
|
||||
struct sha256_double funding_txid;
|
||||
bool am_funder;
|
||||
|
||||
@ -240,7 +240,7 @@ static void init_channel(struct peer *peer, const u8 *msg)
|
||||
&peer->conf[LOCAL], &peer->conf[REMOTE],
|
||||
&peer->their_commit_sig,
|
||||
&peer->pcs.cs,
|
||||
&peer->funding_pubkey[REMOTE],
|
||||
&funding_pubkey[REMOTE],
|
||||
&points[REMOTE].revocation,
|
||||
&points[REMOTE].payment,
|
||||
&points[REMOTE].delayed_payment,
|
||||
@ -254,7 +254,7 @@ static void init_channel(struct peer *peer, const u8 *msg)
|
||||
tal_hex(msg, msg));
|
||||
|
||||
/* We derive everything from the one secret seed. */
|
||||
derive_basepoints(&seed, &peer->funding_pubkey[LOCAL], &points[LOCAL],
|
||||
derive_basepoints(&seed, &funding_pubkey[LOCAL], &points[LOCAL],
|
||||
&peer->our_secrets, &peer->shaseed,
|
||||
&peer->next_per_commit[LOCAL], 1);
|
||||
|
||||
@ -262,6 +262,8 @@ static void init_channel(struct peer *peer, const u8 *msg)
|
||||
funding_satoshi, push_msat, feerate,
|
||||
&peer->conf[LOCAL], &peer->conf[REMOTE],
|
||||
&points[LOCAL], &points[REMOTE],
|
||||
&funding_pubkey[LOCAL],
|
||||
&funding_pubkey[REMOTE],
|
||||
am_funder ? LOCAL : REMOTE);
|
||||
|
||||
peer->channel_direction = get_channel_direction(
|
||||
|
@ -144,42 +144,6 @@ static void check_config_bounds(struct state *state,
|
||||
remoteconf->max_accepted_htlcs);
|
||||
}
|
||||
|
||||
static bool check_commit_sig(const struct state *state,
|
||||
const struct pubkey *our_funding_key,
|
||||
const struct pubkey *their_funding_key,
|
||||
struct bitcoin_tx *tx,
|
||||
const secp256k1_ecdsa_signature *remotesig)
|
||||
{
|
||||
u8 *wscript;
|
||||
bool ret;
|
||||
|
||||
wscript = bitcoin_redeem_2of2(state,
|
||||
our_funding_key, their_funding_key);
|
||||
|
||||
ret = check_tx_sig(tx, 0, NULL, wscript, their_funding_key, remotesig);
|
||||
tal_free(wscript);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static secp256k1_ecdsa_signature
|
||||
sign_remote_commit(const struct state *state,
|
||||
const struct pubkey *our_funding_key,
|
||||
const struct pubkey *their_funding_key,
|
||||
struct bitcoin_tx *tx)
|
||||
{
|
||||
u8 *wscript;
|
||||
secp256k1_ecdsa_signature sig;
|
||||
|
||||
wscript = bitcoin_redeem_2of2(state,
|
||||
our_funding_key, their_funding_key);
|
||||
|
||||
/* Commit tx only has one input: funding tx. */
|
||||
sign_tx_input(tx, 0, NULL, wscript, &state->our_secrets.funding_privkey,
|
||||
our_funding_key, &sig);
|
||||
tal_free(wscript);
|
||||
return sig;
|
||||
}
|
||||
|
||||
/* We always set channel_reserve_satoshis to 1%, rounded up. */
|
||||
static void set_reserve(u64 *reserve, u64 funding)
|
||||
{
|
||||
@ -220,12 +184,14 @@ static u8 *open_channel(struct state *state,
|
||||
const struct basepoints *ours,
|
||||
u32 max_minimum_depth)
|
||||
{
|
||||
const tal_t *tmpctx = tal_tmpctx(state);
|
||||
struct channel_id channel_id, id_in;
|
||||
u8 *msg;
|
||||
struct bitcoin_tx *tx;
|
||||
struct bitcoin_tx **txs;
|
||||
struct basepoints theirs;
|
||||
struct pubkey their_funding_pubkey;
|
||||
secp256k1_ecdsa_signature sig;
|
||||
const u8 **wscripts;
|
||||
|
||||
set_reserve(&state->localconf.channel_reserve_satoshis,
|
||||
state->funding_satoshis);
|
||||
@ -249,7 +215,7 @@ static u8 *open_channel(struct state *state,
|
||||
"push-msat must be < %"PRIu64,
|
||||
1000 * state->funding_satoshis);
|
||||
|
||||
msg = towire_open_channel(state, &genesis_blockhash.sha, &channel_id,
|
||||
msg = towire_open_channel(tmpctx, &genesis_blockhash.sha, &channel_id,
|
||||
state->funding_satoshis, state->push_msat,
|
||||
state->localconf.dust_limit_satoshis,
|
||||
state->localconf.max_htlc_value_in_flight_msat,
|
||||
@ -269,7 +235,7 @@ static u8 *open_channel(struct state *state,
|
||||
|
||||
state->remoteconf = tal(state, struct channel_config);
|
||||
|
||||
msg = sync_crypto_read(state, &state->cs, PEER_FD);
|
||||
msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD);
|
||||
if (!msg)
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
|
||||
"Reading accept_channel");
|
||||
@ -324,12 +290,12 @@ static u8 *open_channel(struct state *state,
|
||||
check_config_bounds(state, state->remoteconf);
|
||||
|
||||
/* Now, ask master create a transaction to pay those two addresses. */
|
||||
msg = towire_opening_open_reply(state, our_funding_pubkey,
|
||||
msg = towire_opening_open_reply(tmpctx, our_funding_pubkey,
|
||||
&their_funding_pubkey);
|
||||
wire_sync_write(REQ_FD, msg);
|
||||
|
||||
/* Expect funding tx. */
|
||||
msg = wire_sync_read(state, REQ_FD);
|
||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||
if (!fromwire_opening_open_funding(msg, NULL,
|
||||
&state->funding_txid,
|
||||
&state->funding_txout))
|
||||
@ -347,6 +313,8 @@ static u8 *open_channel(struct state *state,
|
||||
&state->localconf,
|
||||
state->remoteconf,
|
||||
ours, &theirs,
|
||||
our_funding_pubkey,
|
||||
&their_funding_pubkey,
|
||||
LOCAL);
|
||||
if (!state->channel)
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
|
||||
@ -360,17 +328,18 @@ static u8 *open_channel(struct state *state,
|
||||
* for the initial commitment transactions. After receiving the
|
||||
* peer's signature, it will broadcast the funding transaction.
|
||||
*/
|
||||
tx = channel_tx(state, state->channel,
|
||||
&state->next_per_commit[REMOTE], NULL, REMOTE);
|
||||
sig = sign_remote_commit(state,
|
||||
our_funding_pubkey, &their_funding_pubkey,
|
||||
tx);
|
||||
txs = channel_txs(tmpctx, NULL, &wscripts, state->channel,
|
||||
&state->next_per_commit[REMOTE], REMOTE);
|
||||
|
||||
sign_tx_input(txs[0], 0, NULL, wscripts[0],
|
||||
&state->our_secrets.funding_privkey,
|
||||
our_funding_pubkey, &sig);
|
||||
status_trace("signature %s on tx %s using key %s",
|
||||
type_to_string(trc, secp256k1_ecdsa_signature, &sig),
|
||||
type_to_string(trc, struct bitcoin_tx, tx),
|
||||
type_to_string(trc, struct bitcoin_tx, txs[0]),
|
||||
type_to_string(trc, struct pubkey, our_funding_pubkey));
|
||||
|
||||
msg = towire_funding_created(state, &channel_id,
|
||||
msg = towire_funding_created(tmpctx, &channel_id,
|
||||
&state->funding_txid.sha,
|
||||
state->funding_txout,
|
||||
&sig);
|
||||
@ -386,7 +355,7 @@ static u8 *open_channel(struct state *state,
|
||||
* commitment transaction, so they can broadcast it knowing they can
|
||||
* redeem their funds if they need to.
|
||||
*/
|
||||
msg = sync_crypto_read(state, &state->cs, PEER_FD);
|
||||
msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD);
|
||||
if (!msg)
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
|
||||
"Reading funding_signed");
|
||||
@ -417,18 +386,21 @@ static u8 *open_channel(struct state *state,
|
||||
*
|
||||
* The recipient MUST fail the channel if `signature` is incorrect.
|
||||
*/
|
||||
tx = channel_tx(state, state->channel,
|
||||
&state->next_per_commit[LOCAL], NULL, LOCAL);
|
||||
txs = channel_txs(tmpctx, NULL, &wscripts, state->channel,
|
||||
&state->next_per_commit[LOCAL], LOCAL);
|
||||
|
||||
if (!check_commit_sig(state, our_funding_pubkey,
|
||||
&their_funding_pubkey, tx, &sig))
|
||||
if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], &their_funding_pubkey,
|
||||
&sig)) {
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
|
||||
"Bad signature %s on tx %s using key %s",
|
||||
type_to_string(trc, secp256k1_ecdsa_signature,
|
||||
&sig),
|
||||
type_to_string(trc, struct bitcoin_tx, tx),
|
||||
type_to_string(trc, struct bitcoin_tx, txs[0]),
|
||||
type_to_string(trc, struct pubkey,
|
||||
&their_funding_pubkey));
|
||||
}
|
||||
|
||||
tal_free(tmpctx);
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
@ -456,9 +428,10 @@ static u8 *recv_channel(struct state *state,
|
||||
struct basepoints theirs;
|
||||
struct pubkey their_funding_pubkey;
|
||||
secp256k1_ecdsa_signature theirsig, sig;
|
||||
struct bitcoin_tx *tx;
|
||||
struct bitcoin_tx **txs;
|
||||
struct sha256_double chain_hash;
|
||||
u8 *msg;
|
||||
const u8 **wscripts;
|
||||
|
||||
state->remoteconf = tal(state, struct channel_config);
|
||||
|
||||
@ -590,6 +563,8 @@ static u8 *recv_channel(struct state *state,
|
||||
&state->localconf,
|
||||
state->remoteconf,
|
||||
ours, &theirs,
|
||||
our_funding_pubkey,
|
||||
&their_funding_pubkey,
|
||||
REMOTE);
|
||||
if (!state->channel)
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
|
||||
@ -613,18 +588,19 @@ static u8 *recv_channel(struct state *state,
|
||||
*
|
||||
* The recipient MUST fail the channel if `signature` is incorrect.
|
||||
*/
|
||||
tx = channel_tx(state, state->channel,
|
||||
&state->next_per_commit[LOCAL], NULL, LOCAL);
|
||||
txs = channel_txs(state, NULL, &wscripts, state->channel,
|
||||
&state->next_per_commit[LOCAL], LOCAL);
|
||||
|
||||
if (!check_commit_sig(state, our_funding_pubkey,
|
||||
&their_funding_pubkey, tx, &theirsig))
|
||||
if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], &their_funding_pubkey,
|
||||
&theirsig)) {
|
||||
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
|
||||
"Bad signature %s on tx %s using key %s",
|
||||
type_to_string(trc, secp256k1_ecdsa_signature,
|
||||
&theirsig),
|
||||
type_to_string(trc, struct bitcoin_tx, tx),
|
||||
type_to_string(trc, struct bitcoin_tx, txs[0]),
|
||||
type_to_string(trc, struct pubkey,
|
||||
&their_funding_pubkey));
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
@ -645,11 +621,11 @@ static u8 *recv_channel(struct state *state,
|
||||
* commitment transaction, so they can broadcast it knowing they can
|
||||
* redeem their funds if they need to.
|
||||
*/
|
||||
tx = channel_tx(state, state->channel,
|
||||
&state->next_per_commit[REMOTE], NULL, REMOTE);
|
||||
sig = sign_remote_commit(state,
|
||||
our_funding_pubkey, &their_funding_pubkey,
|
||||
tx);
|
||||
txs = channel_txs(state, NULL, &wscripts, state->channel,
|
||||
&state->next_per_commit[REMOTE], REMOTE);
|
||||
sign_tx_input(txs[0], 0, NULL, wscripts[0],
|
||||
&state->our_secrets.funding_privkey,
|
||||
our_funding_pubkey, &sig);
|
||||
|
||||
msg = towire_funding_signed(state, &channel_id, &sig);
|
||||
if (!sync_crypto_write(&state->cs, PEER_FD, msg))
|
||||
|
@ -36,6 +36,11 @@ static struct sha256_double txid_from_hex(const char *hex)
|
||||
return sha256;
|
||||
}
|
||||
|
||||
static struct bitcoin_tx *tx_from_hex(const tal_t *ctx, const char *hex)
|
||||
{
|
||||
return bitcoin_tx_from_hex(ctx, hex, strlen(hex));
|
||||
}
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* local_feerate_per_kw: 0
|
||||
@ -99,7 +104,7 @@ static u64 feerates[] = {
|
||||
* htlc 4 expiry: 504
|
||||
* htlc 4 payment_preimage: 0404040404040404040404040404040404040404040404040404040404040404
|
||||
*/
|
||||
static const struct htlc **add_htlcs(struct channel *channel, enum side side)
|
||||
static const struct htlc **include_htlcs(struct channel *channel, enum side side)
|
||||
{
|
||||
int i;
|
||||
const struct htlc **htlcs = tal_arr(channel, const struct htlc *, 5);
|
||||
@ -202,6 +207,18 @@ static void tx_must_be_eq(const struct bitcoin_tx *a,
|
||||
tal_free(tmpctx);
|
||||
}
|
||||
|
||||
static void txs_must_be_eq(struct bitcoin_tx **a, struct bitcoin_tx **b)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (tal_count(a) != tal_count(b))
|
||||
errx(1, "A has %zu txs, B has %zu",
|
||||
tal_count(a), tal_count(b));
|
||||
|
||||
for (i = 0; i < tal_count(a); i++)
|
||||
tx_must_be_eq(a[i], b[i]);
|
||||
}
|
||||
|
||||
static void send_and_fulfill_htlc(struct channel *channel,
|
||||
enum side sender,
|
||||
u64 msatoshi)
|
||||
@ -255,16 +272,18 @@ int main(void)
|
||||
u64 funding_amount_satoshi, feerate_per_kw;
|
||||
unsigned int funding_output_index;
|
||||
struct pubkey localkey, remotekey;
|
||||
struct pubkey local_funding_pubkey, remote_funding_pubkey;
|
||||
struct pubkey local_delayedkey;
|
||||
struct pubkey local_revocation_key;
|
||||
struct pubkey local_per_commitment_point;
|
||||
struct basepoints localbase, remotebase;
|
||||
struct pubkey *unknown = tal(tmpctx, struct pubkey);
|
||||
struct bitcoin_tx *raw_tx, *tx;
|
||||
struct bitcoin_tx *raw_tx, **txs, **txs2;
|
||||
struct channel_config *local_config = tal(tmpctx, struct channel_config);
|
||||
struct channel_config *remote_config = tal(tmpctx, struct channel_config);
|
||||
u64 to_local_msat, to_remote_msat;
|
||||
const struct htlc **htlc_map, **htlcs;
|
||||
const u8 *funding_wscript, **wscripts;
|
||||
size_t i;
|
||||
|
||||
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||
@ -338,6 +357,20 @@ int main(void)
|
||||
localbase.revocation = *unknown;
|
||||
remotebase.delayed_payment = *unknown;
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* local_funding_pubkey: 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb
|
||||
* remote_funding_pubkey: 030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1
|
||||
*/
|
||||
local_funding_pubkey = pubkey_from_hex("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb");
|
||||
remote_funding_pubkey = pubkey_from_hex("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1");
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* # funding wscript = 5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae
|
||||
*/
|
||||
funding_wscript = tal_hexdata(tmpctx, "5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae", strlen("5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae"));
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* name: simple commitment tx with no HTLCs
|
||||
@ -355,6 +388,7 @@ int main(void)
|
||||
local_config,
|
||||
remote_config,
|
||||
&localbase, &remotebase,
|
||||
&local_funding_pubkey, &remote_funding_pubkey,
|
||||
LOCAL);
|
||||
|
||||
rchannel = new_channel(tmpctx, &funding_txid, funding_output_index,
|
||||
@ -363,6 +397,7 @@ int main(void)
|
||||
remote_config,
|
||||
local_config,
|
||||
&remotebase, &localbase,
|
||||
&remote_funding_pubkey, &local_funding_pubkey,
|
||||
REMOTE);
|
||||
/* BOLT #3:
|
||||
*
|
||||
@ -400,13 +435,17 @@ int main(void)
|
||||
to_remote_msat,
|
||||
NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL);
|
||||
|
||||
tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
|
||||
&htlc_map, LOCAL);
|
||||
tx_must_be_eq(tx, raw_tx);
|
||||
txs = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
lchannel, &local_per_commitment_point, LOCAL);
|
||||
assert(tal_count(txs) == 1);
|
||||
assert(tal_count(htlc_map) == 2);
|
||||
assert(tal_count(wscripts) == 1);
|
||||
assert(scripteq(wscripts[0], funding_wscript));
|
||||
tx_must_be_eq(txs[0], raw_tx);
|
||||
|
||||
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
|
||||
&htlc_map, REMOTE);
|
||||
tx_must_be_eq(tx, raw_tx);
|
||||
txs2 = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
rchannel, &local_per_commitment_point, REMOTE);
|
||||
txs_must_be_eq(txs, txs2);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
@ -431,23 +470,73 @@ int main(void)
|
||||
assert(lchannel->view[REMOTE].owed_msat[REMOTE]
|
||||
== rchannel->view[LOCAL].owed_msat[LOCAL]);
|
||||
|
||||
raw_tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
|
||||
&htlc_map, LOCAL);
|
||||
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
|
||||
&htlc_map, REMOTE);
|
||||
tx_must_be_eq(tx, raw_tx);
|
||||
txs = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
lchannel, &local_per_commitment_point, LOCAL);
|
||||
assert(tal_count(txs) == 1);
|
||||
txs2 = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
rchannel, &local_per_commitment_point, REMOTE);
|
||||
txs_must_be_eq(txs, txs2);
|
||||
|
||||
/* FIXME: Adjust properly! */
|
||||
lchannel->view[LOCAL].feerate_per_kw = feerate_per_kw;
|
||||
rchannel->view[REMOTE].feerate_per_kw = feerate_per_kw;
|
||||
htlcs = add_htlcs(lchannel, LOCAL);
|
||||
add_htlcs(rchannel, REMOTE);
|
||||
htlcs = include_htlcs(lchannel, LOCAL);
|
||||
include_htlcs(rchannel, REMOTE);
|
||||
|
||||
assert(lchannel->view[LOCAL].owed_msat[LOCAL]
|
||||
== rchannel->view[REMOTE].owed_msat[REMOTE]);
|
||||
assert(lchannel->view[REMOTE].owed_msat[REMOTE]
|
||||
== rchannel->view[LOCAL].owed_msat[LOCAL]);
|
||||
|
||||
txs = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
lchannel, &local_per_commitment_point, LOCAL);
|
||||
assert(tal_count(txs) == 6);
|
||||
txs2 = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
rchannel, &local_per_commitment_point, REMOTE);
|
||||
txs_must_be_eq(txs, txs2);
|
||||
|
||||
/* FIXME: Compare signatures! */
|
||||
/* BOLT #3:
|
||||
*
|
||||
* output htlc_success_tx 0: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000
|
||||
*/
|
||||
raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000");
|
||||
raw_tx->input[0].witness = NULL;
|
||||
tx_must_be_eq(raw_tx, txs[1]);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* output htlc_timeout_tx 2: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000
|
||||
*/
|
||||
raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000");
|
||||
raw_tx->input[0].witness = NULL;
|
||||
tx_must_be_eq(raw_tx, txs[2]);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* output htlc_success_tx 1: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000
|
||||
*/
|
||||
raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000");
|
||||
raw_tx->input[0].witness = NULL;
|
||||
tx_must_be_eq(raw_tx, txs[3]);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* output htlc_timeout_tx 3: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000
|
||||
*/
|
||||
raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000");
|
||||
raw_tx->input[0].witness = NULL;
|
||||
tx_must_be_eq(raw_tx, txs[4]);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* output htlc_success_tx 4: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000
|
||||
*/
|
||||
raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000");
|
||||
raw_tx->input[0].witness = NULL;
|
||||
tx_must_be_eq(raw_tx, txs[5]);
|
||||
|
||||
/* FIXME: Compare HTLCs for these too! */
|
||||
for (i = 0; i < ARRAY_SIZE(feerates); i++) {
|
||||
feerate_per_kw = feerates[i];
|
||||
|
||||
@ -468,13 +557,13 @@ int main(void)
|
||||
htlcs, &htlc_map,
|
||||
0x2bb038521914 ^ 42, LOCAL);
|
||||
|
||||
tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point,
|
||||
&htlc_map, LOCAL);
|
||||
tx_must_be_eq(tx, raw_tx);
|
||||
txs = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
lchannel, &local_per_commitment_point, LOCAL);
|
||||
tx_must_be_eq(txs[0], raw_tx);
|
||||
|
||||
tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point,
|
||||
&htlc_map, REMOTE);
|
||||
tx_must_be_eq(tx, raw_tx);
|
||||
txs2 = channel_txs(tmpctx, &htlc_map, &wscripts,
|
||||
rchannel, &local_per_commitment_point, REMOTE);
|
||||
txs_must_be_eq(txs, txs2);
|
||||
}
|
||||
|
||||
/* No memory leaks please */
|
||||
|
Loading…
Reference in New Issue
Block a user