From 81bced330af8ad38f07cb3da946b8b508fa91d5d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 7 Aug 2015 12:45:30 +0930 Subject: [PATCH] protocol: move locktime into its own message type. We're going to want this for HTLC times, too. Signed-off-by: Rusty Russell --- commit_tx.c | 2 +- lightning.pb-c.c | 144 +++++++++++++++++++++++------- lightning.pb-c.h | 61 ++++++++++--- lightning.proto | 12 ++- pkt.c | 6 +- protobuf_convert.c | 12 +-- protobuf_convert.h | 2 +- test-cli/create-commit-spend-tx.c | 2 +- test-cli/create-steal-tx.c | 2 +- 9 files changed, 184 insertions(+), 59 deletions(-) diff --git a/commit_tx.c b/commit_tx.c index e1734b8c5..10013eeff 100644 --- a/commit_tx.c +++ b/commit_tx.c @@ -34,7 +34,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, if (!proto_to_pubkey(theirs->final_key, &theirkey)) return tal_free(tx); - if (!proto_to_locktime(theirs, &locktime)) + if (!proto_to_locktime(theirs->locktime, &locktime)) return tal_free(tx); /* First output is a P2SH to a complex redeem script (usu. for me) */ diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 168fac320..4233929d4 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -93,6 +93,49 @@ void signature__free_unpacked assert(message->base.descriptor == &signature__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } +void locktime__init + (Locktime *message) +{ + static Locktime init_value = LOCKTIME__INIT; + *message = init_value; +} +size_t locktime__get_packed_size + (const Locktime *message) +{ + assert(message->base.descriptor == &locktime__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t locktime__pack + (const Locktime *message, + uint8_t *out) +{ + assert(message->base.descriptor == &locktime__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t locktime__pack_to_buffer + (const Locktime *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &locktime__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Locktime * + locktime__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Locktime *) + protobuf_c_message_unpack (&locktime__descriptor, + allocator, len, data); +} +void locktime__free_unpacked + (Locktime *message, + ProtobufCAllocator *allocator) +{ + assert(message->base.descriptor == &locktime__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} void bitcoin_pubkey__init (BitcoinPubkey *message) { @@ -858,6 +901,57 @@ const ProtobufCMessageDescriptor signature__descriptor = (ProtobufCMessageInit) signature__init, NULL,NULL,NULL /* reserved[123] */ }; +static const ProtobufCFieldDescriptor locktime__field_descriptors[2] = +{ + { + "seconds", + 1, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_UINT32, + offsetof(Locktime, locktime_case), + offsetof(Locktime, seconds), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "blocks", + 2, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_UINT32, + offsetof(Locktime, locktime_case), + offsetof(Locktime, blocks), + NULL, + NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned locktime__field_indices_by_name[] = { + 1, /* field[1] = blocks */ + 0, /* field[0] = seconds */ +}; +static const ProtobufCIntRange locktime__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor locktime__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "locktime", + "Locktime", + "Locktime", + "", + sizeof(Locktime), + 2, + locktime__field_descriptors, + locktime__field_indices_by_name, + 1, locktime__number_ranges, + (ProtobufCMessageInit) locktime__init, + NULL,NULL,NULL /* reserved[123] */ +}; static const ProtobufCFieldDescriptor bitcoin_pubkey__field_descriptors[1] = { { @@ -925,7 +1019,7 @@ const ProtobufCEnumDescriptor open_channel__anchor_offer__descriptor = NULL,NULL,NULL,NULL /* reserved[1234] */ }; static const uint32_t open_channel__min_depth__default_value = 0u; -static const ProtobufCFieldDescriptor open_channel__field_descriptors[8] = +static const ProtobufCFieldDescriptor open_channel__field_descriptors[7] = { { "final_key", @@ -940,27 +1034,15 @@ static const ProtobufCFieldDescriptor open_channel__field_descriptors[8] = 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "locktime_seconds", + "locktime", 2, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT32, - offsetof(OpenChannel, locktime_case), - offsetof(OpenChannel, locktime_seconds), - NULL, - NULL, - 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "locktime_blocks", - 3, - PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_UINT32, - offsetof(OpenChannel, locktime_case), - offsetof(OpenChannel, locktime_blocks), - NULL, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(OpenChannel, locktime), + &locktime__descriptor, NULL, - 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { @@ -1025,19 +1107,19 @@ static const ProtobufCFieldDescriptor open_channel__field_descriptors[8] = }, }; static const unsigned open_channel__field_indices_by_name[] = { - 5, /* field[5] = anch */ - 4, /* field[4] = commit_key */ - 7, /* field[7] = commitment_fee */ + 4, /* field[4] = anch */ + 3, /* field[3] = commit_key */ + 6, /* field[6] = commitment_fee */ 0, /* field[0] = final_key */ - 2, /* field[2] = locktime_blocks */ - 1, /* field[1] = locktime_seconds */ - 6, /* field[6] = min_depth */ - 3, /* field[3] = revocation_hash */ + 1, /* field[1] = locktime */ + 5, /* field[5] = min_depth */ + 2, /* field[2] = revocation_hash */ }; -static const ProtobufCIntRange open_channel__number_ranges[1 + 1] = +static const ProtobufCIntRange open_channel__number_ranges[2 + 1] = { { 1, 0 }, - { 0, 8 } + { 4, 2 }, + { 0, 7 } }; const ProtobufCMessageDescriptor open_channel__descriptor = { @@ -1047,10 +1129,10 @@ const ProtobufCMessageDescriptor open_channel__descriptor = "OpenChannel", "", sizeof(OpenChannel), - 8, + 7, open_channel__field_descriptors, open_channel__field_indices_by_name, - 1, open_channel__number_ranges, + 2, open_channel__number_ranges, (ProtobufCMessageInit) open_channel__init, NULL,NULL,NULL /* reserved[123] */ }; diff --git a/lightning.pb-c.h b/lightning.pb-c.h index e275ad17f..4ddda05a0 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -17,6 +17,7 @@ PROTOBUF_C__BEGIN_DECLS typedef struct _Sha256Hash Sha256Hash; typedef struct _Signature Signature; +typedef struct _Locktime Locktime; typedef struct _BitcoinPubkey BitcoinPubkey; typedef struct _OpenChannel OpenChannel; typedef struct _OpenAnchor OpenAnchor; @@ -81,6 +82,26 @@ struct _Signature , 0, 0, 0, 0, 0, 0, 0, 0 } +typedef enum { + LOCKTIME__LOCKTIME__NOT_SET = 0, + LOCKTIME__LOCKTIME_SECONDS = 1, + LOCKTIME__LOCKTIME_BLOCKS = 2, +} Locktime__LocktimeCase; + +struct _Locktime +{ + ProtobufCMessage base; + Locktime__LocktimeCase locktime_case; + union { + uint32_t seconds; + uint32_t blocks; + }; +}; +#define LOCKTIME__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&locktime__descriptor) \ + , LOCKTIME__LOCKTIME__NOT_SET, {} } + + /* * Pubkey for commitment transaction input. */ @@ -97,18 +118,16 @@ struct _BitcoinPubkey , {0,NULL} } -typedef enum { - OPEN_CHANNEL__LOCKTIME__NOT_SET = 0, - OPEN_CHANNEL__LOCKTIME_LOCKTIME_SECONDS = 2, - OPEN_CHANNEL__LOCKTIME_LOCKTIME_BLOCKS = 3, -} OpenChannel__LocktimeCase; - /* * Set channel params. */ struct _OpenChannel { ProtobufCMessage base; + /* + * Relative locktime for outputs going to us. + */ + Locktime *locktime; /* * Hash for revoking first commitment transaction. */ @@ -131,15 +150,10 @@ struct _OpenChannel * How much fee would I like on commitment tx? */ uint64_t commitment_fee; - OpenChannel__LocktimeCase locktime_case; - union { - uint32_t locktime_seconds; - uint32_t locktime_blocks; - }; }; #define OPEN_CHANNEL__INIT \ { PROTOBUF_C_MESSAGE_INIT (&open_channel__descriptor) \ - , NULL, NULL, NULL, 0, 0,0u, 0, OPEN_CHANNEL__LOCKTIME__NOT_SET, {} } + , NULL, NULL, NULL, NULL, 0, 0,0u, 0 } /* @@ -423,6 +437,25 @@ Signature * void signature__free_unpacked (Signature *message, ProtobufCAllocator *allocator); +/* Locktime methods */ +void locktime__init + (Locktime *message); +size_t locktime__get_packed_size + (const Locktime *message); +size_t locktime__pack + (const Locktime *message, + uint8_t *out); +size_t locktime__pack_to_buffer + (const Locktime *message, + ProtobufCBuffer *buffer); +Locktime * + locktime__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void locktime__free_unpacked + (Locktime *message, + ProtobufCAllocator *allocator); /* BitcoinPubkey methods */ void bitcoin_pubkey__init (BitcoinPubkey *message); @@ -678,6 +711,9 @@ typedef void (*Sha256Hash_Closure) typedef void (*Signature_Closure) (const Signature *message, void *closure_data); +typedef void (*Locktime_Closure) + (const Locktime *message, + void *closure_data); typedef void (*BitcoinPubkey_Closure) (const BitcoinPubkey *message, void *closure_data); @@ -725,6 +761,7 @@ typedef void (*Pkt_Closure) extern const ProtobufCMessageDescriptor sha256_hash__descriptor; extern const ProtobufCMessageDescriptor signature__descriptor; +extern const ProtobufCMessageDescriptor locktime__descriptor; extern const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor; extern const ProtobufCMessageDescriptor open_channel__descriptor; extern const ProtobufCEnumDescriptor open_channel__anchor_offer__descriptor; diff --git a/lightning.proto b/lightning.proto index e9b8f2c93..793181e7c 100644 --- a/lightning.proto +++ b/lightning.proto @@ -24,6 +24,13 @@ message signature { required fixed64 s4 = 8; } +message locktime { + oneof locktime { + uint32 seconds = 1; + uint32 blocks = 2; + } +}; + // Pubkey for commitment transaction input. message bitcoin_pubkey { // Either 65 or 33 bytes. @@ -37,10 +44,7 @@ message bitcoin_pubkey { // Set channel params. message open_channel { // Relative locktime for outputs going to us. - oneof locktime { - uint32 locktime_seconds = 2; - uint32 locktime_blocks = 3; - } + required locktime locktime = 2; // Hash for revoking first commitment transaction. required sha256_hash revocation_hash = 4; // Pubkey for anchor to pay into commitment tx. diff --git a/pkt.c b/pkt.c index 66a99098b..707209d04 100644 --- a/pkt.c +++ b/pkt.c @@ -41,12 +41,14 @@ struct pkt *open_channel_pkt(const tal_t *ctx, u64 commitment_fee) { OpenChannel o = OPEN_CHANNEL__INIT; + Locktime lt = LOCKTIME__INIT; o.revocation_hash = sha256_to_proto(ctx, revocation_hash); o.commit_key = pubkey_to_proto(ctx, commit); o.final_key = pubkey_to_proto(ctx, final); - o.locktime_case = OPEN_CHANNEL__LOCKTIME_LOCKTIME_SECONDS; - o.locktime_seconds = rel_locktime_seconds; + lt.locktime_case = LOCKTIME__LOCKTIME_SECONDS; + lt.seconds = rel_locktime_seconds; + o.locktime = < o.commitment_fee = commitment_fee; if (offer_anchor) o.anch = OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR; diff --git a/protobuf_convert.c b/protobuf_convert.c index 31240bd00..248c07b19 100644 --- a/protobuf_convert.c +++ b/protobuf_convert.c @@ -81,14 +81,14 @@ void proto_to_sha256(const Sha256Hash *pb, struct sha256 *hash) memcpy(hash->u.u8 + 24, &pb->d, 8); } -bool proto_to_locktime(const OpenChannel *o, uint32_t *locktime) +bool proto_to_locktime(const Locktime *l, uint32_t *locktime) { - switch (o->locktime_case) { - case OPEN_CHANNEL__LOCKTIME_LOCKTIME_SECONDS: - *locktime = 500000000 + o->locktime_seconds; + switch (l->locktime_case) { + case LOCKTIME__LOCKTIME_SECONDS: + *locktime = 500000000 + l->seconds; break; - case OPEN_CHANNEL__LOCKTIME_LOCKTIME_BLOCKS: - *locktime = o->locktime_blocks; + case LOCKTIME__LOCKTIME_BLOCKS: + *locktime = l->blocks; break; default: return false; diff --git a/protobuf_convert.h b/protobuf_convert.h index f3f8db81e..f75939680 100644 --- a/protobuf_convert.h +++ b/protobuf_convert.h @@ -19,5 +19,5 @@ struct sha256; Sha256Hash *sha256_to_proto(const tal_t *ctx, const struct sha256 *hash); void proto_to_sha256(const Sha256Hash *pb, struct sha256 *hash); -bool proto_to_locktime(const OpenChannel *o, uint32_t *locktime); +bool proto_to_locktime(const Locktime *l, uint32_t *locktime); #endif /* LIGHTNING_PROTOBUF_CONVERT_H */ diff --git a/test-cli/create-commit-spend-tx.c b/test-cli/create-commit-spend-tx.c index d782b147b..e0237cc8b 100644 --- a/test-cli/create-commit-spend-tx.c +++ b/test-cli/create-commit-spend-tx.c @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open; a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor; - if (!proto_to_locktime(o2, &locktime)) + if (!proto_to_locktime(o2->locktime, &locktime)) errx(1, "Invalid locktime in o2"); /* We need our private key to spend commit output. */ diff --git a/test-cli/create-steal-tx.c b/test-cli/create-steal-tx.c index 98f041f72..3980874d3 100644 --- a/test-cli/create-steal-tx.c +++ b/test-cli/create-steal-tx.c @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) o1 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[5], PKT__PKT_OPEN)->open; - if (!proto_to_locktime(o1, &locktime_seconds)) + if (!proto_to_locktime(o1->locktime, &locktime_seconds)) errx(1, "Invalid locktime in o2"); if (!pubkey_from_hexstr(argv[6], &outpubkey))