Browse Source

anchor: change is not an arbitrary output, but a pubkey we p2sh to.

Gets rid of the last pubkey user; they're generally deprecated.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 10 years ago
parent
commit
d30c470c7d
  1. 20
      anchor.c
  2. 174
      lightning.pb-c.c
  3. 78
      lightning.pb-c.h
  4. 14
      lightning.proto
  5. 27
      open-channel.c
  6. 13
      pubkey.c
  7. 3
      pubkey.h

20
anchor.c

@ -66,15 +66,27 @@ struct bitcoin_tx *anchor_tx_create(const tal_t *ctx,
n_out = 1;
if (o1->anchor->change) {
struct bitcoin_tx_output *out = &tx->output[n_out++];
struct pubkey key;
if (!proto_to_pubkey(o1->anchor->change->pubkey, &key))
return tal_free(tx);
out->amount = o1->anchor->change->amount;
out->script_length = o1->anchor->change->script.len;
out->script = o1->anchor->change->script.data;
out->script = scriptpubkey_p2sh(tx,
bitcoin_redeem_single(tx, &key));
out->script_length = tal_count(out->script);
}
if (o2->anchor->change) {
struct bitcoin_tx_output *out = &tx->output[n_out++];
struct pubkey key;
if (!proto_to_pubkey(o2->anchor->change->pubkey, &key))
return tal_free(tx);
out->amount = o2->anchor->change->amount;
out->script_length = o2->anchor->change->script.len;
out->script = o2->anchor->change->script.data;
out->script = scriptpubkey_p2sh(tx,
bitcoin_redeem_single(tx, &key));
out->script_length = tal_count(out->script);
}
assert(n_out == tx->output_count);

174
lightning.pb-c.c

@ -136,90 +136,90 @@ void bitcoin_input__free_unpacked
assert(message->base.descriptor == &bitcoin_input__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void bitcoin_output__init
(BitcoinOutput *message)
void bitcoin_pubkey__init
(BitcoinPubkey *message)
{
static BitcoinOutput init_value = BITCOIN_OUTPUT__INIT;
static BitcoinPubkey init_value = BITCOIN_PUBKEY__INIT;
*message = init_value;
}
size_t bitcoin_output__get_packed_size
(const BitcoinOutput *message)
size_t bitcoin_pubkey__get_packed_size
(const BitcoinPubkey *message)
{
assert(message->base.descriptor == &bitcoin_output__descriptor);
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t bitcoin_output__pack
(const BitcoinOutput *message,
size_t bitcoin_pubkey__pack
(const BitcoinPubkey *message,
uint8_t *out)
{
assert(message->base.descriptor == &bitcoin_output__descriptor);
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t bitcoin_output__pack_to_buffer
(const BitcoinOutput *message,
size_t bitcoin_pubkey__pack_to_buffer
(const BitcoinPubkey *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &bitcoin_output__descriptor);
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
BitcoinOutput *
bitcoin_output__unpack
BitcoinPubkey *
bitcoin_pubkey__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (BitcoinOutput *)
protobuf_c_message_unpack (&bitcoin_output__descriptor,
return (BitcoinPubkey *)
protobuf_c_message_unpack (&bitcoin_pubkey__descriptor,
allocator, len, data);
}
void bitcoin_output__free_unpacked
(BitcoinOutput *message,
void bitcoin_pubkey__free_unpacked
(BitcoinPubkey *message,
ProtobufCAllocator *allocator)
{
assert(message->base.descriptor == &bitcoin_output__descriptor);
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void bitcoin_pubkey__init
(BitcoinPubkey *message)
void change__init
(Change *message)
{
static BitcoinPubkey init_value = BITCOIN_PUBKEY__INIT;
static Change init_value = CHANGE__INIT;
*message = init_value;
}
size_t bitcoin_pubkey__get_packed_size
(const BitcoinPubkey *message)
size_t change__get_packed_size
(const Change *message)
{
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
assert(message->base.descriptor == &change__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t bitcoin_pubkey__pack
(const BitcoinPubkey *message,
size_t change__pack
(const Change *message,
uint8_t *out)
{
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
assert(message->base.descriptor == &change__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t bitcoin_pubkey__pack_to_buffer
(const BitcoinPubkey *message,
size_t change__pack_to_buffer
(const Change *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
assert(message->base.descriptor == &change__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
BitcoinPubkey *
bitcoin_pubkey__unpack
Change *
change__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (BitcoinPubkey *)
protobuf_c_message_unpack (&bitcoin_pubkey__descriptor,
return (Change *)
protobuf_c_message_unpack (&change__descriptor,
allocator, len, data);
}
void bitcoin_pubkey__free_unpacked
(BitcoinPubkey *message,
void change__free_unpacked
(Change *message,
ProtobufCAllocator *allocator)
{
assert(message->base.descriptor == &bitcoin_pubkey__descriptor);
assert(message->base.descriptor == &change__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void anchor__init
@ -1279,93 +1279,93 @@ const ProtobufCMessageDescriptor bitcoin_input__descriptor =
(ProtobufCMessageInit) bitcoin_input__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor bitcoin_output__field_descriptors[2] =
static const ProtobufCFieldDescriptor bitcoin_pubkey__field_descriptors[1] =
{
{
"amount",
"key",
1,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_UINT64,
0, /* quantifier_offset */
offsetof(BitcoinOutput, amount),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"script",
2,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_BYTES,
0, /* quantifier_offset */
offsetof(BitcoinOutput, script),
offsetof(BitcoinPubkey, key),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned bitcoin_output__field_indices_by_name[] = {
0, /* field[0] = amount */
1, /* field[1] = script */
static const unsigned bitcoin_pubkey__field_indices_by_name[] = {
0, /* field[0] = key */
};
static const ProtobufCIntRange bitcoin_output__number_ranges[1 + 1] =
static const ProtobufCIntRange bitcoin_pubkey__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 2 }
{ 0, 1 }
};
const ProtobufCMessageDescriptor bitcoin_output__descriptor =
const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"bitcoin_output",
"BitcoinOutput",
"BitcoinOutput",
"bitcoin_pubkey",
"BitcoinPubkey",
"BitcoinPubkey",
"",
sizeof(BitcoinOutput),
2,
bitcoin_output__field_descriptors,
bitcoin_output__field_indices_by_name,
1, bitcoin_output__number_ranges,
(ProtobufCMessageInit) bitcoin_output__init,
sizeof(BitcoinPubkey),
1,
bitcoin_pubkey__field_descriptors,
bitcoin_pubkey__field_indices_by_name,
1, bitcoin_pubkey__number_ranges,
(ProtobufCMessageInit) bitcoin_pubkey__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor bitcoin_pubkey__field_descriptors[1] =
static const ProtobufCFieldDescriptor change__field_descriptors[2] =
{
{
"key",
"amount",
1,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_BYTES,
PROTOBUF_C_TYPE_UINT64,
0, /* quantifier_offset */
offsetof(BitcoinPubkey, key),
offsetof(Change, amount),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"pubkey",
2,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(Change, pubkey),
&bitcoin_pubkey__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned bitcoin_pubkey__field_indices_by_name[] = {
0, /* field[0] = key */
static const unsigned change__field_indices_by_name[] = {
0, /* field[0] = amount */
1, /* field[1] = pubkey */
};
static const ProtobufCIntRange bitcoin_pubkey__number_ranges[1 + 1] =
static const ProtobufCIntRange change__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 1 }
{ 0, 2 }
};
const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor =
const ProtobufCMessageDescriptor change__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"bitcoin_pubkey",
"BitcoinPubkey",
"BitcoinPubkey",
"change",
"Change",
"Change",
"",
sizeof(BitcoinPubkey),
1,
bitcoin_pubkey__field_descriptors,
bitcoin_pubkey__field_indices_by_name,
1, bitcoin_pubkey__number_ranges,
(ProtobufCMessageInit) bitcoin_pubkey__init,
sizeof(Change),
2,
change__field_descriptors,
change__field_indices_by_name,
1, change__number_ranges,
(ProtobufCMessageInit) change__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor anchor__field_descriptors[6] =
@ -1389,7 +1389,7 @@ static const ProtobufCFieldDescriptor anchor__field_descriptors[6] =
PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(Anchor, change),
&bitcoin_output__descriptor,
&change__descriptor,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */

78
lightning.pb-c.h

@ -18,8 +18,8 @@ PROTOBUF_C__BEGIN_DECLS
typedef struct _Sha256Hash Sha256Hash;
typedef struct _Signature Signature;
typedef struct _BitcoinInput BitcoinInput;
typedef struct _BitcoinOutput BitcoinOutput;
typedef struct _BitcoinPubkey BitcoinPubkey;
typedef struct _Change Change;
typedef struct _Anchor Anchor;
typedef struct _OpenChannel OpenChannel;
typedef struct _OpenCommitSig OpenCommitSig;
@ -106,20 +106,6 @@ struct _BitcoinInput
, NULL, 0, {0,NULL}, 0 }
/*
* A bitcoin output
*/
struct _BitcoinOutput
{
ProtobufCMessage base;
uint64_t amount;
ProtobufCBinaryData script;
};
#define BITCOIN_OUTPUT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&bitcoin_output__descriptor) \
, 0, {0,NULL} }
/*
* Pubkey for commitment transaction input.
*/
@ -136,6 +122,20 @@ struct _BitcoinPubkey
, {0,NULL} }
/*
* Change, if we want any.
*/
struct _Change
{
ProtobufCMessage base;
uint64_t amount;
BitcoinPubkey *pubkey;
};
#define CHANGE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&change__descriptor) \
, 0, NULL }
/*
* All about an anchor transaction.
*/
@ -154,7 +154,7 @@ struct _Anchor
/*
* Any change from anchor (in case we don't want to use them all)
*/
BitcoinOutput *change;
Change *change;
/*
* How much transaction fee we'll pay in the anchor tx.
*/
@ -591,25 +591,6 @@ BitcoinInput *
void bitcoin_input__free_unpacked
(BitcoinInput *message,
ProtobufCAllocator *allocator);
/* BitcoinOutput methods */
void bitcoin_output__init
(BitcoinOutput *message);
size_t bitcoin_output__get_packed_size
(const BitcoinOutput *message);
size_t bitcoin_output__pack
(const BitcoinOutput *message,
uint8_t *out);
size_t bitcoin_output__pack_to_buffer
(const BitcoinOutput *message,
ProtobufCBuffer *buffer);
BitcoinOutput *
bitcoin_output__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void bitcoin_output__free_unpacked
(BitcoinOutput *message,
ProtobufCAllocator *allocator);
/* BitcoinPubkey methods */
void bitcoin_pubkey__init
(BitcoinPubkey *message);
@ -629,6 +610,25 @@ BitcoinPubkey *
void bitcoin_pubkey__free_unpacked
(BitcoinPubkey *message,
ProtobufCAllocator *allocator);
/* Change methods */
void change__init
(Change *message);
size_t change__get_packed_size
(const Change *message);
size_t change__pack
(const Change *message,
uint8_t *out);
size_t change__pack_to_buffer
(const Change *message,
ProtobufCBuffer *buffer);
Change *
change__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void change__free_unpacked
(Change *message,
ProtobufCAllocator *allocator);
/* Anchor methods */
void anchor__init
(Anchor *message);
@ -982,12 +982,12 @@ typedef void (*Signature_Closure)
typedef void (*BitcoinInput_Closure)
(const BitcoinInput *message,
void *closure_data);
typedef void (*BitcoinOutput_Closure)
(const BitcoinOutput *message,
void *closure_data);
typedef void (*BitcoinPubkey_Closure)
(const BitcoinPubkey *message,
void *closure_data);
typedef void (*Change_Closure)
(const Change *message,
void *closure_data);
typedef void (*Anchor_Closure)
(const Anchor *message,
void *closure_data);
@ -1051,8 +1051,8 @@ typedef void (*Pkt_Closure)
extern const ProtobufCMessageDescriptor sha256_hash__descriptor;
extern const ProtobufCMessageDescriptor signature__descriptor;
extern const ProtobufCMessageDescriptor bitcoin_input__descriptor;
extern const ProtobufCMessageDescriptor bitcoin_output__descriptor;
extern const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor;
extern const ProtobufCMessageDescriptor change__descriptor;
extern const ProtobufCMessageDescriptor anchor__descriptor;
extern const ProtobufCMessageDescriptor open_channel__descriptor;
extern const ProtobufCMessageDescriptor open_commit_sig__descriptor;

14
lightning.proto

@ -36,18 +36,18 @@ message bitcoin_input {
required uint64 amount = 4;
}
// A bitcoin output
message bitcoin_output {
required uint64 amount = 1;
required bytes script = 2;
}
// Pubkey for commitment transaction input.
message bitcoin_pubkey {
// Either 65 or 33 bytes.
required bytes key = 1;
};
// Change, if we want any.
message change {
required uint64 amount = 1;
required bitcoin_pubkey pubkey = 2;
}
// All about an anchor transaction.
message anchor {
// 0 or more unspent inputs we want to use for anchor.
@ -55,7 +55,7 @@ message anchor {
// Pubkey for anchor to pay to for commitment tx (p2sh)
required bitcoin_pubkey pubkey = 5;
// Any change from anchor (in case we don't want to use them all)
optional bitcoin_output change = 2;
optional change change = 2;
// How much transaction fee we'll pay in the anchor tx.
required uint64 fee = 8;
// How much we'll be putting into channel (== sum(inputs) - change - fee)

27
open-channel.c

@ -1,6 +1,6 @@
/* My example:
* ./open-channel 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff 50000000000 mzqiPPbjTdcgM6NpNWJLHFt29tWD69bciE cUBCjrdJu8tfvM7FT8So6aqs6G6bZS1Cax6Rc9rFzYL6nYG4XNEC cTuY5gncxDymqe9dfF7R8QFdAsxMZxdViRMjs8Dj7xJJRsQcmPCt 08ffaf638849198f9c8f04aa75d225a5a104d5e7c540770ca55ad08b9a32d10c/1/100000000000/76a9148d2d939aa2aff2d341cde3e61a89bf9c2c21d12388ac > A-open.pb
* ./open-channel 112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00 9795000 mpDyc5kPAJZB7Zz9iW9acq3Jk8yiTJ7HKj cQXhbUnNRsFcdzTQwjbCrud5yVskHTEas7tZPUWoJYNk5htGQrpi cQXhbUnNRsFcdzTQwjbCrud5yVskHTEas7tZPUWoJYNk5htGQrpi 8cb044605f33ca907b966701f49e0bd80b4294696b57f8cf45f22398a1e63a23/0/9800000/76a9143b2aab840afb327a12c8a90fb4ed45b6892eb80988ac > B-open.pb
* ./open-channel 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff 50000000000 030da36b810c0930e5fe8b74014665873f6901d9f46018a5fda743a93dec7f0e4e cUBCjrdJu8tfvM7FT8So6aqs6G6bZS1Cax6Rc9rFzYL6nYG4XNEC cTuY5gncxDymqe9dfF7R8QFdAsxMZxdViRMjs8Dj7xJJRsQcmPCt 08ffaf638849198f9c8f04aa75d225a5a104d5e7c540770ca55ad08b9a32d10c/1/100000000000/76a9148d2d939aa2aff2d341cde3e61a89bf9c2c21d12388ac > A-open.pb
* ./open-channel 112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00 9795000 022e314a8f7a814e0900bf094f704b233dc693349cf55b888b43d902d7be251e95 cQXhbUnNRsFcdzTQwjbCrud5yVskHTEas7tZPUWoJYNk5htGQrpi cQXhbUnNRsFcdzTQwjbCrud5yVskHTEas7tZPUWoJYNk5htGQrpi 8cb044605f33ca907b966701f49e0bd80b4294696b57f8cf45f22398a1e63a23/0/9800000/76a9143b2aab840afb327a12c8a90fb4ed45b6892eb80988ac > B-open.pb
*/
#include <ccan/crypto/shachain/shachain.h>
#include <ccan/short_types/short_types.h>
@ -102,7 +102,6 @@ static u64 weak_random64(void)
int main(int argc, char *argv[])
{
struct sha256 seed, revocation_hash;
struct bitcoin_address changeaddr;
struct pkt *pkt;
const tal_t *ctx = tal_arr(NULL, char, 0);
Anchor anchor = ANCHOR__INIT;
@ -110,7 +109,7 @@ int main(int argc, char *argv[])
unsigned int locktime_seconds;
bool testnet;
size_t i;
struct pubkey commitkey, outkey;
struct pubkey commitkey, outkey, changekey;
EC_KEY *commitprivkey, *outprivkey;
err_set_progname(argv[0]);
@ -125,7 +124,7 @@ int main(int argc, char *argv[])
locktime_seconds = LOCKTIME_MIN + 24 * 60 * 60;
opt_register_noarg("--help|-h", opt_usage_and_exit,
"<seed> <amount> <changeaddr> <commitprivkey> <outpubkey> <txid>/<outnum>/<satoshis>/<script-in-hex>...\n"
"<seed> <amount> <changepubkey> <commitprivkey> <outpubkey> <txid>/<outnum>/<satoshis>/<script-in-hex>...\n"
"A test program to output openchannel on stdout.",
"Print this message.");
opt_register_arg("--min-anchor-confirms",
@ -153,10 +152,8 @@ int main(int argc, char *argv[])
if (!anchor.total)
errx(1, "Invalid total: must be > 0");
if (!bitcoin_from_base58(&testnet, &changeaddr, argv[3], strlen(argv[3])))
errx(1, "Invalid bitcoin address '%s'", argv[3]);
if (!testnet)
errx(1, "Bitcoin address '%s' not on testnet!", argv[3]);
if (!pubkey_from_hexstr(argv[3], &changekey))
errx(1, "Invalid bitcoin pubkey '%s'", argv[3]);
/* We don't really need the privkey here, but it's the most
* convenient way to get the pubkey from bitcoind. */
@ -192,15 +189,11 @@ int main(int argc, char *argv[])
/* If there's change, say where to send it. */
if (total_in != anchor.total + anchor.fee) {
anchor.change = tal(ctx, BitcoinOutput);
bitcoin_output__init(anchor.change);
anchor.change = tal(ctx, Change);
change__init(anchor.change);
anchor.change->pubkey = pubkey_to_proto(anchor.change,
&changekey);
anchor.change->amount = total_in - (anchor.total + anchor.fee);
/* FIXME: Use p2sh? */
anchor.change->script.data
= scriptpubkey_pay_to_pubkeyhash(anchor.change,
&changeaddr);
anchor.change->script.len
= tal_count(anchor.change->script.data);
}
/* Get first revocation hash. */

13
pubkey.c

@ -1,5 +1,6 @@
#include "pubkey.h"
#include <openssl/ecdsa.h>
#include <ccan/str/hex/hex.h>
/* Must agree on key validity with bitcoin! Stolen from bitcoin/src/pubkey.h's
* GetLen:
@ -52,3 +53,15 @@ bool proto_to_pubkey(const BitcoinPubkey *pb, struct pubkey *key)
memcpy(key->key, pb->key.data, pb->key.len);
return true;
}
bool pubkey_from_hexstr(const char *str, struct pubkey *key)
{
size_t slen = strlen(str), dlen;
dlen = hex_data_size(slen);
if (dlen != 33 && dlen != 65)
return false;
if (!hex_decode(str, slen, key->key, dlen))
return false;
return GetLen(key->key[0]) == dlen;
}

3
pubkey.h

@ -15,4 +15,7 @@ bool proto_to_pubkey(const BitcoinPubkey *pb, struct pubkey *key);
/* 33 or 65 bytes? */
size_t pubkey_len(const struct pubkey *key);
/* Convert from hex string (scriptPubKey from validateaddress) */
bool pubkey_from_hexstr(const char *str, struct pubkey *key);
#endif /* LIGHTNING_PUBKEY_H */

Loading…
Cancel
Save