Browse Source

funding: remove protobufs.

Use our own structure with the information we need about HTLCs,
and remove protobufs from the API.

The is_funder() helper goes inside gather_updates.h.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
6d6abd57e7
  1. 22
      commit_tx.c
  2. 79
      funding.c
  3. 60
      funding.h
  4. 10
      test-cli/check-commit-sig.c
  5. 4
      test-cli/create-commit-spend-tx.c
  6. 5
      test-cli/create-commit-tx.c
  7. 67
      test-cli/gather_updates.c
  8. 9
      test-cli/gather_updates.h
  9. 10
      test-cli/open-anchor.c
  10. 11
      test-cli/open-commit-sig.c
  11. 5
      test-cli/update-channel-accept.c
  12. 5
      test-cli/update-channel-complete.c
  13. 5
      test-cli/update-channel-signature.c

22
commit_tx.c

@ -7,10 +7,10 @@
#include "funding.h" #include "funding.h"
#include "overflows.h" #include "overflows.h"
#include "permute_tx.h" #include "permute_tx.h"
#include "protobuf_convert.h" #include <assert.h>
static bool add_htlc(struct bitcoin_tx *tx, size_t n, static bool add_htlc(struct bitcoin_tx *tx, size_t n,
const UpdateAddHtlc *h, const struct channel_htlc *h,
const struct pubkey *ourkey, const struct pubkey *ourkey,
const struct pubkey *theirkey, const struct pubkey *theirkey,
const struct sha256 *rhash, const struct sha256 *rhash,
@ -23,22 +23,14 @@ static bool add_htlc(struct bitcoin_tx *tx, size_t n,
const struct sha256 *, const struct sha256 *,
const struct sha256 *)) const struct sha256 *))
{ {
struct abs_locktime htlc_abstime;
struct sha256 htlc_rhash;
assert(!tx->output[n].script); assert(!tx->output[n].script);
/* This shouldn't happen... */
if (!proto_to_abs_locktime(h->expiry, &htlc_abstime))
return false;
proto_to_sha256(h->r_hash, &htlc_rhash);
tx->output[n].script = scriptpubkey_p2sh(tx, tx->output[n].script = scriptpubkey_p2sh(tx,
scriptpubkeyfn(tx, ourkey, theirkey, scriptpubkeyfn(tx, ourkey, theirkey,
&htlc_abstime, locktime, rhash, &h->expiry, locktime, rhash,
&htlc_rhash)); &h->rhash));
tx->output[n].script_length = tal_count(tx->output[n].script); tx->output[n].script_length = tal_count(tx->output[n].script);
tx->output[n].amount = h->amount_msat / 1000; tx->output[n].amount = h->msatoshis / 1000;
return true; return true;
} }
@ -88,7 +80,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
/* HTLCs we've sent. */ /* HTLCs we've sent. */
for (i = 0; i < tal_count(cstate->a.htlcs); i++) { for (i = 0; i < tal_count(cstate->a.htlcs); i++) {
if (!add_htlc(tx, num, cstate->a.htlcs[i], if (!add_htlc(tx, num, &cstate->a.htlcs[i],
our_final, their_final, our_final, their_final,
rhash, their_locktime, scriptpubkey_htlc_send)) rhash, their_locktime, scriptpubkey_htlc_send))
return tal_free(tx); return tal_free(tx);
@ -96,7 +88,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
} }
/* HTLCs we've received. */ /* HTLCs we've received. */
for (i = 0; i < tal_count(cstate->b.htlcs); i++) { for (i = 0; i < tal_count(cstate->b.htlcs); i++) {
if (!add_htlc(tx, num, cstate->b.htlcs[i], if (!add_htlc(tx, num, &cstate->b.htlcs[i],
our_final, their_final, our_final, their_final,
rhash, their_locktime, scriptpubkey_htlc_recv)) rhash, their_locktime, scriptpubkey_htlc_recv))
return tal_free(tx); return tal_free(tx);

79
funding.c

@ -2,11 +2,6 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
static bool is_funder(const OpenChannel *o)
{
return o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR;
}
static bool subtract_fees(uint64_t *funder, uint64_t *non_funder, static bool subtract_fees(uint64_t *funder, uint64_t *non_funder,
uint64_t *funder_fee, uint64_t *non_funder_fee, uint64_t *funder_fee, uint64_t *non_funder_fee,
bool non_funder_paying, uint64_t fee) bool non_funder_paying, uint64_t fee)
@ -38,19 +33,18 @@ static bool subtract_fees(uint64_t *funder, uint64_t *non_funder,
} }
/* Total, in millisatoshi. */ /* Total, in millisatoshi. */
static uint32_t htlcs_total(UpdateAddHtlc *const *htlcs) static uint64_t htlcs_total(const struct channel_htlc *htlcs)
{ {
size_t i, n = tal_count(htlcs); size_t i, n = tal_count(htlcs);
uint32_t total = 0; uint64_t total = 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
total += htlcs[i]->amount_msat; total += htlcs[i].msatoshis;
return total; return total;
} }
bool funding_delta(const OpenChannel *oa, bool funding_delta(bool a_is_funder,
const OpenChannel *ob, uint64_t anchor_satoshis,
const OpenAnchor *anchor,
int64_t delta_a_msat, int64_t delta_a_msat,
int64_t htlc_msat, int64_t htlc_msat,
struct channel_oneside *a_side, struct channel_oneside *a_side,
@ -65,11 +59,7 @@ bool funding_delta(const OpenChannel *oa,
b = b_side->pay_msat + b_side->fee_msat; b = b_side->pay_msat + b_side->fee_msat;
fee = a_side->fee_msat + b_side->fee_msat; fee = a_side->fee_msat + b_side->fee_msat;
assert(a + b + htlcs_total(a_side->htlcs) + htlcs_total(b_side->htlcs) assert(a + b + htlcs_total(a_side->htlcs) + htlcs_total(b_side->htlcs)
== anchor->amount * 1000); == anchor_satoshis * 1000);
/* Only one can be funder. */
if (is_funder(oa) == is_funder(ob))
return false;
/* B gets whatever A gives. */ /* B gets whatever A gives. */
delta_b_msat = -delta_a_msat; delta_b_msat = -delta_a_msat;
@ -87,7 +77,7 @@ bool funding_delta(const OpenChannel *oa,
b += delta_b_msat; b += delta_b_msat;
/* Take off fee from both parties if possible. */ /* Take off fee from both parties if possible. */
if (is_funder(oa)) if (a_is_funder)
got_fees = subtract_fees(&a, &b, &a_fee, &b_fee, got_fees = subtract_fees(&a, &b, &a_fee, &b_fee,
delta_b_msat < 0, fee); delta_b_msat < 0, fee);
else else
@ -106,42 +96,41 @@ bool funding_delta(const OpenChannel *oa,
} }
struct channel_state *initial_funding(const tal_t *ctx, struct channel_state *initial_funding(const tal_t *ctx,
const OpenChannel *a, bool am_funder,
const OpenChannel *b, uint64_t anchor_satoshis,
const OpenAnchor *anchor,
uint64_t fee) uint64_t fee)
{ {
struct channel_state *state = talz(ctx, struct channel_state); struct channel_state *state = talz(ctx, struct channel_state);
state->a.htlcs = tal_arr(state, UpdateAddHtlc *, 0); state->a.htlcs = tal_arr(state, struct channel_htlc, 0);
state->b.htlcs = tal_arr(state, UpdateAddHtlc *, 0); state->b.htlcs = tal_arr(state, struct channel_htlc, 0);
if (fee > anchor->amount) if (fee > anchor_satoshis)
return tal_free(state); return tal_free(state);
if (anchor->amount > (1ULL << 32) / 1000) if (anchor_satoshis > (1ULL << 32) / 1000)
return tal_free(state); return tal_free(state);
/* Initially, all goes back to funder. */ /* Initially, all goes back to funder. */
state->a.pay_msat = anchor->amount * 1000 - fee * 1000; state->a.pay_msat = anchor_satoshis * 1000 - fee * 1000;
state->a.fee_msat = fee * 1000; state->a.fee_msat = fee * 1000;
/* If B (not A) is funder, invert. */ /* If B (not A) is funder, invert. */
if (is_funder(b)) if (!am_funder)
invert_cstate(state); invert_cstate(state);
/* This checks we only have 1 anchor, and is nice code reuse. */ /* Make sure it checks out. */
if (!funding_delta(a, b, anchor, 0, 0, &state->a, &state->b)) assert(funding_delta(am_funder, anchor_satoshis, 0, 0,
return tal_free(state); &state->a, &state->b));
return state; return state;
} }
/* We take the minimum. If one side offers too little, it should be rejected */ /* We take the minimum. If one side offers too little, it should be rejected */
uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b) uint64_t commit_fee(uint64_t a_satoshis, uint64_t b_satoshis)
{ {
if (a->commitment_fee < b->commitment_fee) if (a_satoshis < b_satoshis)
return a->commitment_fee; return a_satoshis;
return b->commitment_fee; return b_satoshis;
} }
void invert_cstate(struct channel_state *cstate) void invert_cstate(struct channel_state *cstate)
@ -152,3 +141,27 @@ void invert_cstate(struct channel_state *cstate)
cstate->a = cstate->b; cstate->a = cstate->b;
cstate->b = tmp; cstate->b = tmp;
} }
void funding_add_htlc(struct channel_oneside *creator,
u32 msatoshis, const struct abs_locktime *expiry,
const struct sha256 *rhash)
{
size_t n = tal_count(creator->htlcs);
tal_resize(&creator->htlcs, n+1);
creator->htlcs[n].msatoshis = msatoshis;
creator->htlcs[n].expiry = *expiry;
creator->htlcs[n].rhash = *rhash;
}
struct channel_state *copy_funding(const tal_t *ctx,
const struct channel_state *cstate)
{
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
cs->a.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->a.htlcs,
tal_count(cs->a.htlcs), 0);
cs->b.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->b.htlcs,
tal_count(cs->b.htlcs), 0);
return cs;
}

60
funding.h

@ -1,15 +1,22 @@
#ifndef LIGHTNING_FUNDING_H #ifndef LIGHTNING_FUNDING_H
#define LIGHTNING_FUNDING_H #define LIGHTNING_FUNDING_H
#include "config.h" #include "config.h"
#include "lightning.pb-c.h" #include "bitcoin/locktime.h"
#include <ccan/crypto/sha256/sha256.h>
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
#include <stdbool.h> #include <stdbool.h>
struct channel_htlc {
u64 msatoshis;
struct abs_locktime expiry;
struct sha256 rhash;
};
struct channel_oneside { struct channel_oneside {
/* Payment and fee is in millisatoshi. */ /* Payment and fee is in millisatoshi. */
uint32_t pay_msat, fee_msat; uint32_t pay_msat, fee_msat;
/* Use tal_count to get the number */ /* Use tal_count to get the number */
UpdateAddHtlc **htlcs; struct channel_htlc *htlcs;
}; };
struct channel_state { struct channel_state {
@ -19,43 +26,47 @@ struct channel_state {
/** /**
* initial_funding: Given A, B, and anchor, what is initial state? * initial_funding: Given A, B, and anchor, what is initial state?
* @ctx: tal context to allocate return value from. * @ctx: tal context to allocate return value from.
* @a: A's openchannel offer * @am_funder: am I paying for the anchor?
* @b: B's openchannel offer * @anchor_satoshis: The anchor amount.
* @anchor: The anchor offer (A or B)
* @fee: amount to pay in fees (in satoshi). * @fee: amount to pay in fees (in satoshi).
* *
* Returns state, or NULL if malformed. * Returns state, or NULL if malformed.
*/ */
struct channel_state *initial_funding(const tal_t *ctx, struct channel_state *initial_funding(const tal_t *ctx,
const OpenChannel *a, bool am_funder,
const OpenChannel *b, uint64_t anchor_satoshis,
const OpenAnchor *anchor,
uint64_t fee); uint64_t fee);
/**
* copy_funding: Make a deep copy of channel_state
* @ctx: tal context to allocate return value from.
* @cstate: state to copy.
*/
struct channel_state *copy_funding(const tal_t *ctx,
const struct channel_state *cstate);
/** /**
* funding_delta: With this change, what's the new state? * funding_delta: With this change, what's the new state?
* @a: A's openchannel offer * @a_is_funder: is A paying for the anchor?
* @b: B's openchannel offer * @anchor_satoshis: The anchor amount.
* @anchor: The anchor offer (A or B)
* @delta_a: How many millisatoshi A changes (-ve => A pay B, +ve => B pays A) * @delta_a: How many millisatoshi A changes (-ve => A pay B, +ve => B pays A)
* @htlc: Millisatoshi A is putting into a HTLC (-ve if htlc is cancelled) * @htlc: Millisatoshi A is putting into a HTLC (-ve if htlc is cancelled)
* @a_side: channel a's state to update. * @a_side: channel a's state to update.
* @b_side: channel b's state to update. * @b_side: channel b's state to update.
*/ */
bool funding_delta(const OpenChannel *a, bool funding_delta(bool a_is_funder,
const OpenChannel *b, uint64_t anchor_satoshis,
const OpenAnchor *anchor, int64_t delta_a_msat,
int64_t delta_a, int64_t htlc_msat,
int64_t htlc,
struct channel_oneside *a_side, struct channel_oneside *a_side,
struct channel_oneside *b_side); struct channel_oneside *b_side);
/** /**
* commit_fee: Fee amount for commit tx. * commit_fee: Fee amount for commit tx.
* @a: A's openchannel offer * @a_satoshis: A's openchannel->commitment_fee offer
* @b: B's openchannel offer * @b_satoshis: B's openchannel->commitment_fee offer
*/ */
uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b); uint64_t commit_fee(uint64_t a_satoshis, uint64_t b_satoshis);
/** /**
* invert_cstate: Get the other side's state. * invert_cstate: Get the other side's state.
@ -63,4 +74,15 @@ uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b);
*/ */
void invert_cstate(struct channel_state *cstate); void invert_cstate(struct channel_state *cstate);
/**
* funding_add_htlc: append an HTLC to this side of the channel.
* @creator: channel_state->a or channel_state->b, whichever originated htlc
* @msatoshis: amount in millisatoshi
* @expiry: time it expires
* @rhash: hash of redeem secret
*/
void funding_add_htlc(struct channel_oneside *creator,
u32 msatoshis, const struct abs_locktime *expiry,
const struct sha256 *rhash);
#endif /* LIGHTNING_FUNDING_H */ #endif /* LIGHTNING_FUNDING_H */

10
test-cli/check-commit-sig.c

@ -15,6 +15,7 @@
#include "bitcoin/privkey.h" #include "bitcoin/privkey.h"
#include "protobuf_convert.h" #include "protobuf_convert.h"
#include "funding.h" #include "funding.h"
#include "gather_updates.h"
#include "version.h" #include "version.h"
#include <unistd.h> #include <unistd.h>
@ -70,9 +71,14 @@ int main(int argc, char *argv[])
if (!proto_to_pubkey(o2->commit_key, &pubkey2)) if (!proto_to_pubkey(o2->commit_key, &pubkey2))
errx(1, "Invalid o2 commit_key"); errx(1, "Invalid o2 commit_key");
cstate = initial_funding(ctx, o1, o2, a, commit_fee(o1, o2)); if (is_funder(o1) == is_funder(o2))
errx(1, "Must be exactly one funder");
cstate = initial_funding(ctx, is_funder(o1), a->amount,
commit_fee(o1->commitment_fee,
o2->commitment_fee));
if (!cstate) if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need to cover fees)");
/* Now create our commitment tx. */ /* Now create our commitment tx. */
proto_to_sha256(o1->revocation_hash, &rhash); proto_to_sha256(o1->revocation_hash, &rhash);

4
test-cli/create-commit-spend-tx.c

@ -85,7 +85,9 @@ int main(int argc, char *argv[])
errx(1, "Invalid o2 final pubkey"); errx(1, "Invalid o2 final pubkey");
/* We use this simply to get final revocation hash. */ /* We use this simply to get final revocation hash. */
gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 7, gather_updates(ctx, o1, o2, a,
commit_fee(o1->commitment_fee, o2->commitment_fee),
argv + 7,
NULL, &rhash, NULL, NULL); NULL, &rhash, NULL, NULL);
/* Create redeem script */ /* Create redeem script */

5
test-cli/create-commit-tx.c

@ -67,7 +67,10 @@ int main(int argc, char *argv[])
sig2.stype = SIGHASH_ALL; sig2.stype = SIGHASH_ALL;
cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5, cstate = gather_updates(ctx, o1, o2, a,
commit_fee(o1->commitment_fee,
o2->commitment_fee),
argv + 5,
NULL, &rhash, NULL, &sig2.sig); NULL, &rhash, NULL, &sig2.sig);
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

67
test-cli/gather_updates.c

@ -28,28 +28,32 @@ static size_t find_htlc(struct channel_oneside *oneside,
const Sha256Hash *rhash) const Sha256Hash *rhash)
{ {
size_t i, n; size_t i, n;
struct sha256 h;
proto_to_sha256(rhash, &h);
n = tal_count(oneside->htlcs); n = tal_count(oneside->htlcs);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (oneside->htlcs[i]->r_hash->a == rhash->a if (structeq(&oneside->htlcs[i].rhash, &h))
&& oneside->htlcs[i]->r_hash->b == rhash->b
&& oneside->htlcs[i]->r_hash->c == rhash->c
&& oneside->htlcs[i]->r_hash->d == rhash->d)
break; break;
} }
return i; return i;
} }
static void add_htlc(struct channel_oneside *oneside, UpdateAddHtlc *ah, static void add_htlc(struct channel_oneside *oneside,
const UpdateAddHtlc *ah,
const char *file) const char *file)
{ {
size_t num = tal_count(oneside->htlcs); size_t num = tal_count(oneside->htlcs);
struct sha256 rhash;
struct abs_locktime expiry;
if (find_htlc(oneside, ah->r_hash) != num) if (find_htlc(oneside, ah->r_hash) != num)
errx(1, "Duplicate R hash in %s", file); errx(1, "Duplicate R hash in %s", file);
tal_resize(&oneside->htlcs, num+1); proto_to_sha256(ah->r_hash, &rhash);
oneside->htlcs[num] = ah; proto_to_abs_locktime(ah->expiry, &expiry);
funding_add_htlc(oneside, ah->amount_msat, &expiry, &rhash);
} }
static void remove_htlc(struct channel_oneside *oneside, size_t n) static void remove_htlc(struct channel_oneside *oneside, size_t n)
@ -85,13 +89,13 @@ static void update_rhash(const Sha256Hash *rhash,
(*num_updates)++; (*num_updates)++;
} }
static uint32_t htlcs_total(UpdateAddHtlc *const *htlcs) static uint32_t htlcs_total(const struct channel_htlc *htlcs)
{ {
size_t i, n = tal_count(htlcs); size_t i, n = tal_count(htlcs);
uint32_t total = 0; uint32_t total = 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
total += htlcs[i]->amount_msat; total += htlcs[i].msatoshis;
return total; return total;
} }
@ -110,9 +114,12 @@ struct channel_state *gather_updates(const tal_t *ctx,
struct channel_state *cstate; struct channel_state *cstate;
/* Start sanity check. */ /* Start sanity check. */
cstate = initial_funding(NULL, o1, o2, oa, fee); if (is_funder(o1) == is_funder(o2))
errx(1, "Must be exactly one funder");
cstate = initial_funding(NULL, is_funder(o1), oa->amount, fee);
if (!cstate) if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need to cover fees)");
/* If they don't want these, use dummy ones. */ /* If they don't want these, use dummy ones. */
if (!our_rhash) if (!our_rhash)
@ -156,14 +163,16 @@ struct channel_state *gather_updates(const tal_t *ctx,
case PKT__PKT_UPDATE_ADD_HTLC: case PKT__PKT_UPDATE_ADD_HTLC:
amount = pkt->update_add_htlc->amount_msat; amount = pkt->update_add_htlc->amount_msat;
if (received) { if (received) {
if (!funding_delta(o2, o1, oa, 0, amount, if (!funding_delta(is_funder(o2), oa->amount,
0, amount,
&cstate->b, &cstate->a)) &cstate->b, &cstate->a))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
add_htlc(&cstate->b, pkt->update_add_htlc, add_htlc(&cstate->b, pkt->update_add_htlc,
*argv); *argv);
} else { } else {
if (!funding_delta(o1, o2, oa, 0, amount, if (!funding_delta(is_funder(o1), oa->amount,
0, amount,
&cstate->a, &cstate->b)) &cstate->a, &cstate->b))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -183,8 +192,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
pkt->update_timedout_htlc->r_hash); pkt->update_timedout_htlc->r_hash);
if (n == tal_count(cstate->b.htlcs)) if (n == tal_count(cstate->b.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->b.htlcs[n]->amount_msat; amount = cstate->b.htlcs[n].msatoshis;
if (!funding_delta(o2, o1, oa, 0, -amount, if (!funding_delta(is_funder(o2), oa->amount,
0, -amount,
&cstate->b, &cstate->a)) &cstate->b, &cstate->a))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -194,8 +204,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
pkt->update_timedout_htlc->r_hash); pkt->update_timedout_htlc->r_hash);
if (n == tal_count(cstate->a.htlcs)) if (n == tal_count(cstate->a.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->a.htlcs[n]->amount_msat; amount = cstate->a.htlcs[n].msatoshis;
if (!funding_delta(o1, o2, oa, 0, -amount, if (!funding_delta(is_funder(o1), oa->amount,
0, -amount,
&cstate->a, &cstate->b)) &cstate->a, &cstate->b))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -214,8 +225,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
pkt->update_routefail_htlc->r_hash); pkt->update_routefail_htlc->r_hash);
if (n == tal_count(cstate->a.htlcs)) if (n == tal_count(cstate->a.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->a.htlcs[n]->amount_msat; amount = cstate->a.htlcs[n].msatoshis;
if (!funding_delta(o1, o2, oa, 0, -amount, if (!funding_delta(is_funder(o1), oa->amount,
0, -amount,
&cstate->a, &cstate->b)) &cstate->a, &cstate->b))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -225,8 +237,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
pkt->update_routefail_htlc->r_hash); pkt->update_routefail_htlc->r_hash);
if (n == tal_count(cstate->b.htlcs)) if (n == tal_count(cstate->b.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->b.htlcs[n]->amount_msat; amount = cstate->b.htlcs[n].msatoshis;
if (!funding_delta(o2, o1, oa, 0, -amount, if (!funding_delta(is_funder(o2), oa->amount,
0, -amount,
&cstate->b, &cstate->a)) &cstate->b, &cstate->a))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -253,8 +266,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
n = find_htlc(&cstate->a, rh); n = find_htlc(&cstate->a, rh);
if (n == tal_count(cstate->a.htlcs)) if (n == tal_count(cstate->a.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->a.htlcs[n]->amount_msat; amount = cstate->a.htlcs[n].msatoshis;
if (!funding_delta(o1, o2, oa, -amount, -amount, if (!funding_delta(is_funder(o1), oa->amount,
-amount, -amount,
&cstate->a, &cstate->b)) &cstate->a, &cstate->b))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -266,8 +280,9 @@ struct channel_state *gather_updates(const tal_t *ctx,
n = find_htlc(&cstate->b, rh); n = find_htlc(&cstate->b, rh);
if (n == tal_count(cstate->b.htlcs)) if (n == tal_count(cstate->b.htlcs))
errx(1, "Unknown R hash in %s", *argv); errx(1, "Unknown R hash in %s", *argv);
amount = cstate->b.htlcs[n]->amount_msat; amount = cstate->b.htlcs[n].msatoshis;
if (!funding_delta(o2, o1, oa, -amount, -amount, if (!funding_delta(is_funder(o2), oa->amount,
-amount, -amount,
&cstate->b, &cstate->a)) &cstate->b, &cstate->a))
errx(1, "Impossible htlc %llu %s", errx(1, "Impossible htlc %llu %s",
(long long)amount, *argv); (long long)amount, *argv);
@ -285,7 +300,7 @@ struct channel_state *gather_updates(const tal_t *ctx,
delta = -pkt->update->delta_msat; delta = -pkt->update->delta_msat;
else else
delta = pkt->update->delta_msat; delta = pkt->update->delta_msat;
if (!funding_delta(o1, o2, oa, delta, 0, if (!funding_delta(is_funder(o1), oa->amount, delta, 0,
&cstate->a, &cstate->b)) &cstate->a, &cstate->b))
errx(1, "Impossible funding update %lli %s", errx(1, "Impossible funding update %lli %s",
(long long)delta, *argv); (long long)delta, *argv);

9
test-cli/gather_updates.h

@ -15,4 +15,13 @@ struct channel_state *gather_updates(const tal_t *ctx,
struct sha256 *our_rhash, struct sha256 *our_rhash,
struct sha256 *their_rhash, struct sha256 *their_rhash,
struct signature *their_commit_sig); struct signature *their_commit_sig);
/**
* is_funder: helper to tell you if this is offering to fund channel.
* @o: the openchannel packet.
*/
static inline bool is_funder(const OpenChannel *o)
{
return o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR;
}
#endif /* GATHER_UPDATES_H */ #endif /* GATHER_UPDATES_H */

10
test-cli/open-anchor.c

@ -9,6 +9,7 @@
#include "bitcoin/base58.h" #include "bitcoin/base58.h"
#include "pkt.h" #include "pkt.h"
#include "funding.h" #include "funding.h"
#include "gather_updates.h"
#include "bitcoin/script.h" #include "bitcoin/script.h"
#include "bitcoin/address.h" #include "bitcoin/address.h"
#include "bitcoin/tx.h" #include "bitcoin/tx.h"
@ -73,9 +74,14 @@ int main(int argc, char *argv[])
oa.amount = anchor->output[oa.output_index].amount; oa.amount = anchor->output[oa.output_index].amount;
/* Figure out initial how much to us, how much to them. */ /* Figure out initial how much to us, how much to them. */
cstate = initial_funding(ctx, o1, o2, &oa, commit_fee(o1, o2)); if (is_funder(o1) == is_funder(o2))
errx(1, "Must be exactly one funder");
cstate = initial_funding(ctx, is_funder(o1), oa.amount,
commit_fee(o1->commitment_fee,
o2->commitment_fee));
if (!cstate) if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need to cover fees)");
/* Now, create signature for their commitment tx. */ /* Now, create signature for their commitment tx. */
proto_to_sha256(o2->revocation_hash, &rhash); proto_to_sha256(o2->revocation_hash, &rhash);

11
test-cli/open-commit-sig.c

@ -16,6 +16,7 @@
#include "bitcoin/privkey.h" #include "bitcoin/privkey.h"
#include "protobuf_convert.h" #include "protobuf_convert.h"
#include "funding.h" #include "funding.h"
#include "gather_updates.h"
#include "version.h" #include "version.h"
#include <unistd.h> #include <unistd.h>
@ -56,13 +57,17 @@ int main(int argc, char *argv[])
if (!testnet) if (!testnet)
errx(1, "Private key '%s' not on testnet!", argv[4]); errx(1, "Private key '%s' not on testnet!", argv[4]);
if (is_funder(o1) == is_funder(o2))
errx(1, "Must be exactly one funder");
/* Now create THEIR commitment tx to spend 2/2 output of anchor. */ /* Now create THEIR commitment tx to spend 2/2 output of anchor. */
cstate = initial_funding(ctx, o1, o2, a, commit_fee(o1, o2)); cstate = initial_funding(ctx, is_funder(o2), a->amount,
commit_fee(o2->commitment_fee,
o1->commitment_fee));
if (!cstate) if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (too low for fees)");
proto_to_sha256(o2->revocation_hash, &rhash); proto_to_sha256(o2->revocation_hash, &rhash);
invert_cstate(cstate);
commit = commit_tx_from_pkts(ctx, o2, o1, a, &rhash, cstate); commit = commit_tx_from_pkts(ctx, o2, o1, a, &rhash, cstate);
/* If contributions don't exceed fees, this fails. */ /* If contributions don't exceed fees, this fails. */

5
test-cli/update-channel-accept.c

@ -63,7 +63,10 @@ int main(int argc, char *argv[])
errx(1, "Private key '%s' not on testnet!", argv[5]); errx(1, "Private key '%s' not on testnet!", argv[5]);
/* Figure out cumulative delta since anchor. */ /* Figure out cumulative delta since anchor. */
cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6, cstate = gather_updates(ctx, o1, o2, a,
commit_fee(o1->commitment_fee,
o2->commitment_fee),
argv + 6,
&num_updates, NULL, &their_rhash, NULL); &num_updates, NULL, &their_rhash, NULL);
/* Get next revocation hash. */ /* Get next revocation hash. */

5
test-cli/update-channel-complete.c

@ -58,7 +58,10 @@ int main(int argc, char *argv[])
sig.stype = SIGHASH_ALL; sig.stype = SIGHASH_ALL;
/* This also checks that preimage is correct! */ /* This also checks that preimage is correct! */
cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5, cstate = gather_updates(ctx, o1, o2, a,
commit_fee(o1->commitment_fee,
o2->commitment_fee),
argv + 5,
&num_updates, &num_updates,
&our_rhash, &their_rhash, &sig.sig); &our_rhash, &their_rhash, &sig.sig);
if (num_updates < 1) if (num_updates < 1)

5
test-cli/update-channel-signature.c

@ -65,7 +65,10 @@ int main(int argc, char *argv[])
sig.stype = SIGHASH_ALL; sig.stype = SIGHASH_ALL;
/* Figure out cumulative delta since anchor. */ /* Figure out cumulative delta since anchor. */
cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6, cstate = gather_updates(ctx, o1, o2, a,
commit_fee(o1->commitment_fee,
o2->commitment_fee),
argv + 6,
&num_updates, &num_updates,
&our_rhash, &their_rhash, &sig.sig); &our_rhash, &their_rhash, &sig.sig);
if (num_updates < 1) if (num_updates < 1)

Loading…
Cancel
Save