From de051f0df9a34feb3ad95de96ce11396ae8eaf52 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 29 Jul 2015 16:17:08 +0930 Subject: [PATCH] protocol: add close fee logic. The closer proposes the fee. This is simple, at least. Signed-off-by: Rusty Russell --- lightning.pb-c.c | 19 ++++++++++++++++--- lightning.pb-c.h | 6 +++++- lightning.proto | 2 ++ pkt.c | 5 ++++- pkt.h | 5 ++++- test-cli/close-channel.c | 27 ++++++++++++++++++++------- test-cli/create-close-tx.c | 3 ++- test-cli/scripts/test.sh | 2 +- 8 files changed, 54 insertions(+), 15 deletions(-) diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 8590f7d4b..168fac320 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -1399,7 +1399,7 @@ const ProtobufCMessageDescriptor update_complete__descriptor = (ProtobufCMessageInit) update_complete__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor close_channel__field_descriptors[1] = +static const ProtobufCFieldDescriptor close_channel__field_descriptors[2] = { { "sig", @@ -1413,14 +1413,27 @@ static const ProtobufCFieldDescriptor close_channel__field_descriptors[1] = 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, + { + "close_fee", + 2, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_UINT64, + 0, /* quantifier_offset */ + offsetof(CloseChannel, close_fee), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned close_channel__field_indices_by_name[] = { + 1, /* field[1] = close_fee */ 0, /* field[0] = sig */ }; static const ProtobufCIntRange close_channel__number_ranges[1 + 1] = { { 1, 0 }, - { 0, 1 } + { 0, 2 } }; const ProtobufCMessageDescriptor close_channel__descriptor = { @@ -1430,7 +1443,7 @@ const ProtobufCMessageDescriptor close_channel__descriptor = "CloseChannel", "", sizeof(CloseChannel), - 1, + 2, close_channel__field_descriptors, close_channel__field_indices_by_name, 1, close_channel__number_ranges, diff --git a/lightning.pb-c.h b/lightning.pb-c.h index 2e1818cbc..e275ad17f 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -293,10 +293,14 @@ struct _CloseChannel * as per the last commit tx. */ Signature *sig; + /* + * Fee to pay for close transaction. + */ + uint64_t close_fee; }; #define CLOSE_CHANNEL__INIT \ { PROTOBUF_C_MESSAGE_INIT (&close_channel__descriptor) \ - , NULL } + , NULL, 0 } /* diff --git a/lightning.proto b/lightning.proto index 1cbef50d0..e9b8f2c93 100644 --- a/lightning.proto +++ b/lightning.proto @@ -125,6 +125,8 @@ message close_channel { // output to my open->final and your open->final, // as per the last commit tx. required signature sig = 1; + // Fee to pay for close transaction. + required uint64 close_fee = 2; } // OK, here's my sig so you can broadcast it too. We're done. diff --git a/pkt.c b/pkt.c index de6460213..66a99098b 100644 --- a/pkt.c +++ b/pkt.c @@ -110,9 +110,12 @@ struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig) return to_pkt(ctx, PKT__PKT_OPEN_COMMIT_SIG, &o); } -struct pkt *close_channel_pkt(const tal_t *ctx, const struct signature *sig) +struct pkt *close_channel_pkt(const tal_t *ctx, + uint64_t fee, + const struct signature *sig) { CloseChannel c = CLOSE_CHANNEL__INIT; + c.close_fee = fee; c.sig = signature_to_proto(ctx, sig); return to_pkt(ctx, PKT__PKT_CLOSE, &c); } diff --git a/pkt.h b/pkt.h index 3e18f2241..4d300db0a 100644 --- a/pkt.h +++ b/pkt.h @@ -65,9 +65,12 @@ struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig); /** * close_channel_pkt - create an close_channel message * @ctx: tal context to allocate off. + * @fee: the fee for the transaction. * @sig: the signature for the close transaction input. */ -struct pkt *close_channel_pkt(const tal_t *ctx, const struct signature *sig); +struct pkt *close_channel_pkt(const tal_t *ctx, + uint64_t fee, + const struct signature *sig); /** * close_channel_complete_pkt - create an close_channel_complete message diff --git a/test-cli/close-channel.c b/test-cli/close-channel.c index 51fddfa5e..3270da9dd 100644 --- a/test-cli/close-channel.c +++ b/test-cli/close-channel.c @@ -18,6 +18,7 @@ #include "find_p2sh_out.h" #include "protobuf_convert.h" #include "gather_updates.h" +#include "opt_bits.h" #include int main(int argc, char *argv[]) @@ -29,19 +30,25 @@ int main(int argc, char *argv[]) struct pkt *pkt; struct signature sig; struct privkey privkey; - bool testnet, complete = false; + bool testnet; struct pubkey pubkey1, pubkey2; u8 *redeemscript; uint64_t our_amount, their_amount; + char *close_file = NULL; + u64 close_fee = 10000; err_set_progname(argv[0]); - opt_register_noarg("--complete", opt_set_bool, &complete, - "Create a close_transaction_complete msg instead"); + opt_register_arg("--complete=", + opt_set_charp, NULL, &close_file, + "Create a close_transaction_complete msg instead"); opt_register_noarg("--help|-h", opt_usage_and_exit, " [{+/-}update-protobuf]...\n" "Create the signature needed for the close transaction", "Print this message."); + opt_register_arg("--close-fee=", + opt_set_bits, opt_show_bits, &close_fee, + "100's of satoshi to pay for close tx"); opt_parse(&argc, argv, opt_log_stderr_exit); @@ -57,7 +64,14 @@ int main(int argc, char *argv[]) if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[4]); - gather_updates(o1, o2, a, 0, argv + 5, &our_amount, &their_amount, + if (close_file) { + CloseChannel *c; + c = pkt_from_file(close_file, PKT__PKT_CLOSE)->close; + close_fee = c->close_fee; + } + + gather_updates(o1, o2, a, close_fee, argv + 5, + &our_amount, &their_amount, NULL, NULL, NULL); /* Get pubkeys */ @@ -72,17 +86,16 @@ int main(int argc, char *argv[]) /* This is what the anchor pays to. */ redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); - /* FIXME: Add fee! */ close_tx = create_close_tx(ctx, o1, o2, a, our_amount, their_amount); /* Sign it for them. */ sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript), &privkey, &pubkey1, &sig); - if (complete) + if (close_file) pkt = close_channel_complete_pkt(ctx, &sig); else - pkt = close_channel_pkt(ctx, &sig); + pkt = close_channel_pkt(ctx, close_fee, &sig); if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt))) err(1, "Writing out packet"); diff --git a/test-cli/create-close-tx.c b/test-cli/create-close-tx.c index 894c2b8aa..2189de3e9 100644 --- a/test-cli/create-close-tx.c +++ b/test-cli/create-close-tx.c @@ -56,7 +56,8 @@ int main(int argc, char *argv[]) errx(1, "Invalid o2 commit_key"); /* Get delta by accumulting all the updates. */ - gather_updates(o1, o2, a, 0, argv + 6, &our_amount, &their_amount, + gather_updates(o1, o2, a, close->close_fee, argv + 6, + &our_amount, &their_amount, NULL, NULL, NULL); /* This is what the anchor pays to; figure out which output. */ diff --git a/test-cli/scripts/test.sh b/test-cli/scripts/test.sh index ed8337099..87e88da70 100755 --- a/test-cli/scripts/test.sh +++ b/test-cli/scripts/test.sh @@ -176,7 +176,7 @@ fi # Now close channel by mutual consent. $PREFIX ./close-channel A-open.pb B-open.pb A-anchor.pb $A_TMPKEY $A_UPDATE_PKTS > A-close.pb -$PREFIX ./close-channel --complete B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-close-complete.pb +$PREFIX ./close-channel --complete=A-close.pb B-open.pb A-open.pb A-anchor.pb $B_TMPKEY $B_UPDATE_PKTS > B-close-complete.pb $PREFIX ./create-close-tx A-open.pb B-open.pb A-anchor.pb A-close.pb B-close-complete.pb $A_UPDATE_PKTS > A-close.tx $CLI sendrawtransaction `cut -d: -f1 A-close.tx` > close.txid