Browse Source

channel_state: encapsulate funding of channel in one place.

This shows where funds are going at any time (fees vs to each side).
funding.c is mainly rewritten, and should be clearer now.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 10 years ago
parent
commit
a4dfe3ad72
  1. 7
      commit_tx.c
  2. 3
      commit_tx.h
  3. 160
      funding.c
  4. 48
      funding.h
  5. 9
      test-cli/check-commit-sig.c
  6. 8
      test-cli/close-channel.c
  7. 10
      test-cli/create-close-tx.c
  8. 7
      test-cli/create-commit-spend-tx.c
  9. 10
      test-cli/create-commit-tx.c
  10. 23
      test-cli/gather_updates.c
  11. 8
      test-cli/gather_updates.h
  12. 8
      test-cli/open-anchor.c
  13. 8
      test-cli/open-commit-sig.c
  14. 13
      test-cli/update-channel-accept.c
  15. 11
      test-cli/update-channel-complete.c
  16. 17
      test-cli/update-channel-signature.c

7
commit_tx.c

@ -3,6 +3,7 @@
#include "bitcoin/shadouble.h" #include "bitcoin/shadouble.h"
#include "bitcoin/tx.h" #include "bitcoin/tx.h"
#include "commit_tx.h" #include "commit_tx.h"
#include "funding.h"
#include "overflows.h" #include "overflows.h"
#include "permute_tx.h" #include "permute_tx.h"
#include "pkt.h" #include "pkt.h"
@ -13,7 +14,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
OpenChannel *theirs, OpenChannel *theirs,
OpenAnchor *anchor, OpenAnchor *anchor,
const struct sha256 *rhash, const struct sha256 *rhash,
uint64_t to_us, uint64_t to_them) const struct channel_state *cstate)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
const u8 *redeemscript; const u8 *redeemscript;
@ -44,14 +45,14 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
rhash); rhash);
tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript); tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript);
tx->output[0].script_length = tal_count(tx->output[0].script); tx->output[0].script_length = tal_count(tx->output[0].script);
tx->output[0].amount = to_us; tx->output[0].amount = cstate->a.pay;
/* Second output is a P2SH payment to them. */ /* Second output is a P2SH payment to them. */
tx->output[1].script = scriptpubkey_p2sh(ctx, tx->output[1].script = scriptpubkey_p2sh(ctx,
bitcoin_redeem_single(ctx, bitcoin_redeem_single(ctx,
&theirkey)); &theirkey));
tx->output[1].script_length = tal_count(tx->output[1].script); tx->output[1].script_length = tal_count(tx->output[1].script);
tx->output[1].amount = to_them; tx->output[1].amount = cstate->b.pay;
/* Calculate fee; difference of inputs and outputs. */ /* Calculate fee; difference of inputs and outputs. */
assert(tx->output[0].amount + tx->output[1].amount assert(tx->output[0].amount + tx->output[1].amount

3
commit_tx.h

@ -3,6 +3,7 @@
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
#include "lightning.pb-c.h" #include "lightning.pb-c.h"
struct channel_state;
struct sha256_double; struct sha256_double;
struct sha256; struct sha256;
@ -13,5 +14,5 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
OpenChannel *theirs, OpenChannel *theirs,
OpenAnchor *anchor, OpenAnchor *anchor,
const struct sha256 *rhash, const struct sha256 *rhash,
uint64_t to_us, uint64_t to_them); const struct channel_state *cstate);
#endif #endif

160
funding.c

@ -1,91 +1,114 @@
#include "funding.h" #include "funding.h"
#include <assert.h> #include <assert.h>
#include <string.h>
bool funding_delta(const OpenChannel *a, static bool is_funder(const OpenChannel *o)
const OpenChannel *b,
const OpenAnchor *anchor,
uint64_t fee,
uint64_t *channel_delta,
int64_t delta_a_to_b,
uint64_t *a_amount,
uint64_t *b_amount)
{ {
uint64_t *funder_amount, *non_funder_amount, new_delta; return o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR;
int64_t delta_to_funder; }
uint64_t funder_fee, non_funder_fee;
assert(*channel_delta <= anchor->amount);
if (a->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) {
if (b->anch != OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR)
return false;
funder_amount = a_amount;
non_funder_amount = b_amount;
delta_to_funder = delta_a_to_b;
} else {
if (a->anch != OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR)
return false;
if (b->anch != OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
return false;
funder_amount = b_amount;
non_funder_amount = a_amount;
delta_to_funder = -delta_a_to_b;
}
/* Trying to spend more than non-funder has? */
if (delta_to_funder > 0) {
if (delta_to_funder > *channel_delta)
return false;
/* Trying to spend more than funder has? */
} else if (-delta_to_funder > anchor->amount - *channel_delta)
return false;
new_delta = *channel_delta - delta_to_funder;
*funder_amount = anchor->amount - new_delta;
*non_funder_amount = new_delta;
/* We try to split fee. */ static bool subtract_fees(uint64_t *funder, uint64_t *non_funder,
funder_fee = fee / 2; uint64_t *funder_fee, uint64_t *non_funder_fee,
/* Funder gets any 1 satoshi rounding benefit! */ bool non_funder_paying, uint64_t fee)
non_funder_fee = fee - funder_fee; {
/* Funder gets 1 satsoshi rounding benefit! */
*non_funder_fee = fee - fee / 2;
if (*non_funder_amount < non_funder_fee) { if (*non_funder < *non_funder_fee) {
/* /*
* This happens initially, as funder has all the money. * This happens initially, as funder has all the money.
* That's OK, but don't let non-funder withdraw if they can't * That's OK, but don't let non-funder spend if they can't
* cover fee. * cover fee.
*/ */
if (delta_to_funder > 0) if (non_funder_paying)
return false; return false;
/* Pay everything they can, funder pays rest. */ /* Pay everything they can, funder pays rest. */
non_funder_fee = *non_funder_amount; *non_funder_fee = *non_funder;
funder_fee = fee - non_funder_fee;
} }
/* Funder must always ensure they can pay their share. */ /* Funder must always ensure they can pay their share. */
if (*funder_amount < funder_fee) *funder_fee = fee - *non_funder_fee;
if (*funder < *funder_fee)
return false;
*non_funder -= *non_funder_fee;
*funder -= *funder_fee;
return true;
}
bool funding_delta(const OpenChannel *oa,
const OpenChannel *ob,
const OpenAnchor *anchor,
int64_t delta_a,
struct channel_oneside *a_side,
struct channel_oneside *b_side)
{
uint64_t a, b, a_fee, b_fee;
uint64_t fee;
bool got_fees;
a = a_side->pay + a_side->fee;
b = b_side->pay + b_side->fee;
fee = a_side->fee + b_side->fee;
assert(a + b == anchor->amount);
/* Only one can be funder. */
if (is_funder(oa) == is_funder(ob))
return false; return false;
*funder_amount -= funder_fee; /* Transferring more than we have? */
*non_funder_amount -= non_funder_fee; if (delta_a > 0 && delta_a > b)
return false;
if (delta_a < 0 && -delta_a > a)
return false;
/* Adjust amounts. */
a += delta_a;
b -= delta_a;
/* Now we know we're succeeding, update caller's channel_delta */ /* Take off fee from both parties if possible. */
*channel_delta = new_delta; if (is_funder(oa))
got_fees = subtract_fees(&a, &b, &a_fee, &b_fee,
delta_a > 0, fee);
else
got_fees = subtract_fees(&b, &a, &b_fee, &a_fee,
delta_a < 0, fee);
if (!got_fees)
return false;
/* Now we know we're succeeding, update caller's state */
a_side->pay = a;
b_side->pay = b;
a_side->fee = a_fee;
b_side->fee = b_fee;
return true; return true;
} }
bool initial_funding(const OpenChannel *a, struct channel_state *initial_funding(const tal_t *ctx,
const OpenChannel *b, const OpenChannel *a,
const OpenAnchor *anchor, const OpenChannel *b,
uint64_t fee, const OpenAnchor *anchor,
uint64_t *a_amount, uint64_t fee)
uint64_t *b_amount)
{ {
uint64_t channel_delta = 0; struct channel_state *state = talz(ctx, struct channel_state);
if (fee > anchor->amount)
return tal_free(state);
/* Initially, all goes back to funder. */
state->a.pay = anchor->amount - fee;
state->a.fee = fee;
/* If B (not A) is funder, invert. */
if (is_funder(b))
invert_cstate(state);
return funding_delta(a, b, anchor, fee, &channel_delta, 0, /* This checks we only have 1 anchor, and is nice code reuse. */
a_amount, b_amount); if (!funding_delta(a, b, anchor, 0, &state->a, &state->b))
return tal_free(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 */
@ -95,3 +118,12 @@ uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b)
return a->commitment_fee; return a->commitment_fee;
return b->commitment_fee; return b->commitment_fee;
} }
void invert_cstate(struct channel_state *cstate)
{
struct channel_oneside tmp;
tmp = cstate->a;
cstate->a = cstate->b;
cstate->b = tmp;
}

48
funding.h

@ -1,44 +1,49 @@
#ifndef LIGHTNING_FUNDING_H #ifndef LIGHTNING_FUNDING_H
#define LIGHTNING_FUNDING_H #define LIGHTNING_FUNDING_H
#include <ccan/tal/tal.h>
#include <stdbool.h> #include <stdbool.h>
#include "lightning.pb-c.h" #include "lightning.pb-c.h"
struct channel_oneside {
uint64_t pay, fee;
};
struct channel_state {
struct channel_oneside a, b;
};
/** /**
* 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.
* @a: A's openchannel offer * @a: A's openchannel offer
* @b: B's openchannel offer * @b: B's openchannel offer
* @anchor: The anchor offer (A or B) * @anchor: The anchor offer (A or B)
* @fee: amount to pay in fees. * @fee: amount to pay in fees.
* @a_amount: amount commit tx will output to A. *
* @b_amount: amount commit tx will output to B. * Returns state, or NULL if malformed.
*/ */
bool initial_funding(const OpenChannel *a, struct channel_state *initial_funding(const tal_t *ctx,
const OpenChannel *b, const OpenChannel *a,
const OpenAnchor *anchor, const OpenChannel *b,
uint64_t fee, const OpenAnchor *anchor,
uint64_t *a_amount, uint64_t fee);
uint64_t *b_amount);
/** /**
* 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: A's openchannel offer
* @b: B's openchannel offer * @b: B's openchannel offer
* @anchor: The anchor offer (A or B) * @anchor: The anchor offer (A or B)
* @fee: amount to pay in fees. * @delta_a: How much A changes (-ve => A pay B, +ve => B pays A)
* @channel_delta: In/out amount funder pays to non-funder (channel state) * @a_side: channel a's state to update.
* @delta_a_to_b: How much A pays to B (satoshi). * @b_side: channel b's state to update.
* @a_amount: amount commit tx will output to A.
* @b_amount: amount commit tx will output to B.
*/ */
bool funding_delta(const OpenChannel *a, bool funding_delta(const OpenChannel *a,
const OpenChannel *b, const OpenChannel *b,
const OpenAnchor *anchor, const OpenAnchor *anchor,
uint64_t fee, int64_t delta_a,
uint64_t *channel_delta, struct channel_oneside *a_side,
int64_t delta_a_to_b, struct channel_oneside *b_side);
uint64_t *a_amount,
uint64_t *b_amount);
/** /**
* commit_fee: Fee amount for commit tx. * commit_fee: Fee amount for commit tx.
@ -46,4 +51,11 @@ bool funding_delta(const OpenChannel *a,
* @b: B's openchannel offer * @b: B's openchannel offer
*/ */
uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b); uint64_t commit_fee(const OpenChannel *a, const OpenChannel *b);
/**
* invert_cstate: Get the other side's state.
* @cstate: the state to invert.
*/
void invert_cstate(struct channel_state *cstate);
#endif /* LIGHTNING_FUNDING_H */ #endif /* LIGHTNING_FUNDING_H */

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

@ -29,7 +29,7 @@ int main(int argc, char *argv[])
struct privkey privkey; struct privkey privkey;
bool testnet; bool testnet;
struct sha256 rhash; struct sha256 rhash;
u64 our_amount, their_amount; struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -68,14 +68,13 @@ 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");
if (!initial_funding(o1, o2, a, commit_fee(o1, o2), cstate = initial_funding(ctx, o1, o2, a, commit_fee(o1, o2));
&our_amount, &their_amount)) if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need 1 anchor offer)");
/* Now create our commitment tx. */ /* Now create our commitment tx. */
proto_to_sha256(o1->revocation_hash, &rhash); proto_to_sha256(o1->revocation_hash, &rhash);
commit = create_commit_tx(ctx, o1, o2, a, &rhash, commit = create_commit_tx(ctx, o1, o2, a, &rhash, cstate);
our_amount, their_amount);
/* Check signature. */ /* Check signature. */
subscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); subscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

8
test-cli/close-channel.c

@ -11,6 +11,7 @@
#include "bitcoin/script.h" #include "bitcoin/script.h"
#include "permute_tx.h" #include "permute_tx.h"
#include "funding.h" #include "funding.h"
#include "commit_tx.h"
#include "bitcoin/signature.h" #include "bitcoin/signature.h"
#include "bitcoin/pubkey.h" #include "bitcoin/pubkey.h"
#include "bitcoin/privkey.h" #include "bitcoin/privkey.h"
@ -33,9 +34,9 @@ int main(int argc, char *argv[])
bool testnet; bool testnet;
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
u8 *redeemscript; u8 *redeemscript;
uint64_t our_amount, their_amount;
char *close_file = NULL; char *close_file = NULL;
u64 close_fee = 10000; u64 close_fee = 10000;
struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -70,8 +71,7 @@ int main(int argc, char *argv[])
close_fee = c->close_fee; close_fee = c->close_fee;
} }
gather_updates(o1, o2, a, close_fee, argv + 5, cstate = gather_updates(ctx, o1, o2, a, close_fee, argv + 5, NULL,
&our_amount, &their_amount,
NULL, NULL, NULL); NULL, NULL, NULL);
/* Get pubkeys */ /* Get pubkeys */
@ -86,7 +86,7 @@ int main(int argc, char *argv[])
/* This is what the anchor pays to. */ /* This is what the anchor pays to. */
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
close_tx = create_close_tx(ctx, o1, o2, a, our_amount, their_amount); close_tx = create_close_tx(ctx, o1, o2, a, cstate->a.pay, cstate->b.pay);
/* Sign it for them. */ /* Sign it for them. */
sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript), sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript),

10
test-cli/create-close-tx.c

@ -15,6 +15,7 @@
#include "find_p2sh_out.h" #include "find_p2sh_out.h"
#include "protobuf_convert.h" #include "protobuf_convert.h"
#include "gather_updates.h" #include "gather_updates.h"
#include "funding.h"
#include <unistd.h> #include <unistd.h>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -28,7 +29,7 @@ int main(int argc, char *argv[])
u8 *redeemscript; u8 *redeemscript;
CloseChannel *close; CloseChannel *close;
CloseChannelComplete *closecomplete; CloseChannelComplete *closecomplete;
uint64_t our_amount, their_amount; struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -56,15 +57,14 @@ int main(int argc, char *argv[])
errx(1, "Invalid o2 commit_key"); errx(1, "Invalid o2 commit_key");
/* Get delta by accumulting all the updates. */ /* Get delta by accumulting all the updates. */
gather_updates(o1, o2, a, close->close_fee, argv + 6, cstate = gather_updates(ctx, o1, o2, a, close->close_fee, argv + 6,
&our_amount, &their_amount, NULL, NULL, NULL, NULL);
NULL, NULL, NULL);
/* This is what the anchor pays to; figure out which output. */ /* This is what the anchor pays to; figure out which output. */
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
/* Now create the close tx to spend 2/2 output of anchor. */ /* Now create the close tx to spend 2/2 output of anchor. */
close_tx = create_close_tx(ctx, o1, o2, a, our_amount, their_amount); close_tx = create_close_tx(ctx, o1, o2, a, cstate->a.pay, cstate->b.pay);
/* Signatures well-formed? */ /* Signatures well-formed? */
sig1.stype = sig2.stype = SIGHASH_ALL; sig1.stype = sig2.stype = SIGHASH_ALL;

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

@ -35,7 +35,7 @@ int main(int argc, char *argv[])
u8 *redeemscript; u8 *redeemscript;
struct sha256 rhash; struct sha256 rhash;
size_t p2sh_out; size_t p2sh_out;
u64 fee = 10000, our_amount, their_amount; u64 fee = 10000;
u32 locktime; u32 locktime;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -82,9 +82,8 @@ 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(o1, o2, a, commit_fee(o1, o2), argv + 7, gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 7,
&our_amount, &their_amount, NULL, &rhash, NULL, NULL);
&rhash, NULL, NULL);
/* Create redeem script */ /* Create redeem script */
redeemscript = bitcoin_redeem_secret_or_delay(ctx, &pubkey1, locktime, redeemscript = bitcoin_redeem_secret_or_delay(ctx, &pubkey1, locktime,

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

@ -31,8 +31,8 @@ int main(int argc, char *argv[])
struct bitcoin_signature sig1, sig2; struct bitcoin_signature sig1, sig2;
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
u8 *redeemscript; u8 *redeemscript;
uint64_t our_amount, their_amount;
struct sha256 rhash; struct sha256 rhash;
struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -66,15 +66,13 @@ int main(int argc, char *argv[])
sig2.stype = SIGHASH_ALL; sig2.stype = SIGHASH_ALL;
gather_updates(o1, o2, a, commit_fee(o1, o2), argv + 5, cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5,
&our_amount, &their_amount, NULL, &rhash, NULL, &sig2.sig);
&rhash, NULL, &sig2.sig);
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
/* Now create commitment tx to spend 2/2 output of anchor. */ /* Now create commitment tx to spend 2/2 output of anchor. */
commit = create_commit_tx(ctx, o1, o2, a, &rhash, commit = create_commit_tx(ctx, o1, o2, a, &rhash, cstate);
our_amount, their_amount);
/* This only fails on malformed packets */ /* This only fails on malformed packets */
if (!commit) if (!commit)

23
test-cli/gather_updates.c

@ -2,6 +2,7 @@
#include <ccan/crypto/sha256/sha256.h> #include <ccan/crypto/sha256/sha256.h>
#include <ccan/structeq/structeq.h> #include <ccan/structeq/structeq.h>
#include "test-cli/gather_updates.h" #include "test-cli/gather_updates.h"
#include "commit_tx.h"
#include "funding.h" #include "funding.h"
#include "pkt.h" #include "pkt.h"
#include "protobuf_convert.h" #include "protobuf_convert.h"
@ -32,21 +33,22 @@ static void get_rhash(const Sha256Hash *rhash, struct sha256 *old,
} }
/* Takes complete update history, gets summary of last state. */ /* Takes complete update history, gets summary of last state. */
uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2, struct channel_state *gather_updates(const tal_t *ctx,
const OpenChannel *o1, const OpenChannel *o2,
const OpenAnchor *oa, uint64_t fee, const OpenAnchor *oa, uint64_t fee,
char **argv, char **argv,
uint64_t *our_amount, uint64_t *their_amount, size_t *num_updates,
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)
{ {
uint64_t cdelta = 0;
uint64_t num_updates = 0;
Signature *sig = NULL; Signature *sig = NULL;
struct sha256 old_our_rhash, old_their_rhash; struct sha256 old_our_rhash, old_their_rhash;
struct channel_state *cstate;
/* Start sanity check. */ /* Start sanity check. */
if (!initial_funding(o1, o2, oa, fee, our_amount, their_amount)) cstate = initial_funding(NULL, o1, o2, oa, fee);
if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need 1 anchor offer)");
if (our_rhash) if (our_rhash)
@ -59,6 +61,8 @@ uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2,
if (o2->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) if (o2->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
sig = oa->commit_sig; sig = oa->commit_sig;
if (num_updates)
*num_updates = 0;
while (*argv) { while (*argv) {
int64_t delta; int64_t delta;
bool received; bool received;
@ -88,11 +92,12 @@ uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2,
get_rhash(pkt->update->revocation_hash, get_rhash(pkt->update->revocation_hash,
&old_our_rhash, our_rhash); &old_our_rhash, our_rhash);
} }
if (!funding_delta(o1, o2, oa, fee, &cdelta, delta, if (!funding_delta(o1, o2, oa, delta,
our_amount, their_amount)) &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);
num_updates++; if (num_updates)
(*num_updates)++;
break; break;
} }
case PKT__PKT_UPDATE_ACCEPT: case PKT__PKT_UPDATE_ACCEPT:
@ -145,5 +150,5 @@ uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2,
errx(1, "Invalid signature"); errx(1, "Invalid signature");
} }
return num_updates; return cstate;
} }

8
test-cli/gather_updates.h

@ -1,16 +1,18 @@
#ifndef GATHER_UPDATES_H #ifndef GATHER_UPDATES_H
#define GATHER_UPDATES_H #define GATHER_UPDATES_H
#include <ccan/tal/tal.h>
#include "lightning.pb-c.h" #include "lightning.pb-c.h"
struct signature; struct signature;
struct sha256; struct sha256;
struct channel_state;
uint64_t gather_updates(const OpenChannel *o1, const OpenChannel *o2, struct channel_state *gather_updates(const tal_t *ctx,
const OpenChannel *o1, const OpenChannel *o2,
const OpenAnchor *oa, uint64_t fee, const OpenAnchor *oa, uint64_t fee,
char **argv, char **argv,
uint64_t *our_amount, uint64_t *their_amount, size_t *num_updates,
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);
#endif /* GATHER_UPDATES_H */ #endif /* GATHER_UPDATES_H */

8
test-cli/open-anchor.c

@ -31,12 +31,12 @@ int main(int argc, char *argv[])
struct sha256_double txid; struct sha256_double txid;
struct sha256 rhash; struct sha256 rhash;
struct pkt *pkt; struct pkt *pkt;
uint64_t to_them, to_us;
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
struct privkey privkey; struct privkey privkey;
struct signature sig; struct signature sig;
bool testnet; bool testnet;
u8 *redeemscript; u8 *redeemscript;
struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -70,12 +70,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. */
if (!initial_funding(o1, o2, &oa, commit_fee(o1, o2), &to_us, &to_them)) cstate = initial_funding(ctx, o1, o2, &oa, commit_fee(o1, o2));
if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need 1 anchor offer)");
/* 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);
commit = create_commit_tx(ctx, o2, o1, &oa, &rhash, to_them, to_us); invert_cstate(cstate);
commit = create_commit_tx(ctx, o2, o1, &oa, &rhash, cstate);
sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript), sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript),
&privkey, &pubkey1, &sig); &privkey, &pubkey1, &sig);

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

@ -31,7 +31,7 @@ int main(int argc, char *argv[])
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
u8 *subscript; u8 *subscript;
struct sha256 rhash; struct sha256 rhash;
uint64_t to_them, to_us; struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -55,11 +55,13 @@ int main(int argc, char *argv[])
errx(1, "Private key '%s' not on testnet!", argv[4]); errx(1, "Private key '%s' not on testnet!", argv[4]);
/* Now create THEIR commitment tx to spend 2/2 output of anchor. */ /* Now create THEIR commitment tx to spend 2/2 output of anchor. */
if (!initial_funding(o1, o2, a, commit_fee(o1, o2), &to_us, &to_them)) cstate = initial_funding(ctx, o1, o2, a, commit_fee(o1, o2));
if (!cstate)
errx(1, "Invalid open combination (need 1 anchor offer)"); errx(1, "Invalid open combination (need 1 anchor offer)");
proto_to_sha256(o2->revocation_hash, &rhash); proto_to_sha256(o2->revocation_hash, &rhash);
commit = create_commit_tx(ctx, o2, o1, a, &rhash, to_them, to_us); invert_cstate(cstate);
commit = create_commit_tx(ctx, o2, o1, a, &rhash, cstate);
/* If contributions don't exceed fees, this fails. */ /* If contributions don't exceed fees, this fails. */
if (!commit) if (!commit)

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

@ -31,10 +31,10 @@ int main(int argc, char *argv[])
struct bitcoin_signature sig; struct bitcoin_signature sig;
struct privkey privkey; struct privkey privkey;
bool testnet; bool testnet;
uint64_t num_updates; size_t num_updates;
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
u8 *redeemscript; u8 *redeemscript;
uint64_t our_amount, their_amount; struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -61,9 +61,8 @@ 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. */
num_updates = gather_updates(o1, o2, a, commit_fee(o1, o2), argv + 6, cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6,
&our_amount, &their_amount, &num_updates, NULL, &their_rhash, NULL);
NULL, &their_rhash, NULL);
/* Get next revocation hash. */ /* Get next revocation hash. */
shachain_from_seed(&seed, num_updates, &revocation_hash); shachain_from_seed(&seed, num_updates, &revocation_hash);
@ -83,8 +82,8 @@ int main(int argc, char *argv[])
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */ /* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, invert_cstate(cstate);
their_amount, our_amount); commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, cstate);
/* If contributions don't exceed fees, this fails. */ /* If contributions don't exceed fees, this fails. */
if (!commit) if (!commit)

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

@ -31,8 +31,8 @@ int main(int argc, char *argv[])
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
size_t num_updates; size_t num_updates;
struct bitcoin_signature sig; struct bitcoin_signature sig;
uint64_t our_amount, their_amount;
u8 *redeemscript; u8 *redeemscript;
struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -56,9 +56,9 @@ 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! */
num_updates = gather_updates(o1, o2, a, commit_fee(o1, o2), argv + 5, cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5,
&our_amount, &their_amount, &num_updates,
&our_rhash, &their_rhash, &sig.sig); &our_rhash, &their_rhash, &sig.sig);
if (num_updates < 1) if (num_updates < 1)
errx(1, "Expected at least one update!"); errx(1, "Expected at least one update!");
@ -72,8 +72,7 @@ int main(int argc, char *argv[])
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
/* Check their signature signs our new commit tx correctly. */ /* Check their signature signs our new commit tx correctly. */
commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
our_amount, their_amount);
if (!commit) if (!commit)
errx(1, "Delta too large"); errx(1, "Delta too large");

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

@ -33,8 +33,8 @@ int main(int argc, char *argv[])
bool testnet; bool testnet;
struct pubkey pubkey1, pubkey2; struct pubkey pubkey1, pubkey2;
u8 *redeemscript; u8 *redeemscript;
uint64_t our_amount, their_amount; size_t num_updates;
uint64_t num_updates; struct channel_state *cstate;
err_set_progname(argv[0]); err_set_progname(argv[0]);
@ -63,9 +63,9 @@ 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. */
num_updates = gather_updates(o1, o2, a, commit_fee(o1, o2), argv + 6, cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6,
&our_amount, &their_amount, &num_updates,
&our_rhash, &their_rhash, &sig.sig); &our_rhash, &their_rhash, &sig.sig);
if (num_updates < 1) if (num_updates < 1)
errx(1, "Expected at least one update!"); errx(1, "Expected at least one update!");
@ -85,8 +85,7 @@ int main(int argc, char *argv[])
redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
/* Check our new commit is signed correctly by them. */ /* Check our new commit is signed correctly by them. */
commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
our_amount, their_amount);
if (!commit) if (!commit)
errx(1, "Invalid packets"); errx(1, "Invalid packets");
@ -96,8 +95,8 @@ int main(int argc, char *argv[])
errx(1, "Invalid signature."); errx(1, "Invalid signature.");
/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */ /* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, invert_cstate(cstate);
their_amount, our_amount); commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, cstate);
if (!commit) if (!commit)
errx(1, "Invalid packets"); errx(1, "Invalid packets");

Loading…
Cancel
Save