2015-05-26 06:38:12 +02:00
|
|
|
#include <ccan/crypto/sha256/sha256.h>
|
2015-05-28 23:38:27 +02:00
|
|
|
#include <ccan/tal/grab_file/grab_file.h>
|
|
|
|
#include <ccan/err/err.h>
|
2015-05-26 06:38:12 +02:00
|
|
|
#include "pkt.h"
|
2015-05-28 23:38:27 +02:00
|
|
|
#include "bitcoin_tx.h"
|
|
|
|
#include "bitcoin_address.h"
|
2015-06-05 04:07:27 +02:00
|
|
|
#include "pubkey.h"
|
2015-06-01 04:26:09 +02:00
|
|
|
#include "signature.h"
|
2015-05-26 06:38:12 +02:00
|
|
|
|
2015-05-28 23:38:27 +02:00
|
|
|
#include <stdio.h>
|
2015-05-26 06:38:12 +02:00
|
|
|
static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, void *msg)
|
|
|
|
{
|
|
|
|
struct pkt *ret;
|
|
|
|
size_t len;
|
|
|
|
Pkt p = PKT__INIT;
|
|
|
|
|
|
|
|
p.pkt_case = type;
|
|
|
|
/* This is a union, so doesn't matter which we assign. */
|
|
|
|
p.error = msg;
|
|
|
|
|
|
|
|
len = pkt__get_packed_size(&p);
|
|
|
|
ret = (struct pkt *)tal_arr(ctx, u8, sizeof(ret->len) + len);
|
|
|
|
ret->len = cpu_to_le32(len);
|
2015-05-28 23:38:27 +02:00
|
|
|
|
2015-05-26 06:38:12 +02:00
|
|
|
pkt__pack(&p, ret->data);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-05-28 23:38:27 +02:00
|
|
|
Sha256Hash *sha256_to_proto(const tal_t *ctx, const struct sha256 *hash)
|
2015-05-26 06:38:12 +02:00
|
|
|
{
|
|
|
|
Sha256Hash *h = tal(ctx, Sha256Hash);
|
|
|
|
sha256_hash__init(h);
|
|
|
|
|
|
|
|
/* Kill me now... */
|
|
|
|
memcpy(&h->a, hash->u.u8, 8);
|
|
|
|
memcpy(&h->b, hash->u.u8 + 8, 8);
|
|
|
|
memcpy(&h->c, hash->u.u8 + 16, 8);
|
|
|
|
memcpy(&h->d, hash->u.u8 + 24, 8);
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
2015-05-28 23:38:27 +02:00
|
|
|
void proto_to_sha256(const Sha256Hash *pb, struct sha256 *hash)
|
|
|
|
{
|
|
|
|
/* Kill me again. */
|
|
|
|
memcpy(hash->u.u8, &pb->a, 8);
|
|
|
|
memcpy(hash->u.u8 + 8, &pb->b, 8);
|
|
|
|
memcpy(hash->u.u8 + 16, &pb->c, 8);
|
|
|
|
memcpy(hash->u.u8 + 24, &pb->d, 8);
|
|
|
|
}
|
|
|
|
|
2015-05-26 06:38:12 +02:00
|
|
|
struct pkt *openchannel_pkt(const tal_t *ctx,
|
|
|
|
u64 seed,
|
|
|
|
const struct sha256 *revocation_hash,
|
2015-06-05 04:07:27 +02:00
|
|
|
const struct pubkey *to_me,
|
2015-05-26 06:38:12 +02:00
|
|
|
u64 commitment_fee,
|
|
|
|
u32 rel_locktime_seconds,
|
|
|
|
Anchor *anchor)
|
|
|
|
{
|
|
|
|
OpenChannel o = OPEN_CHANNEL__INIT;
|
|
|
|
|
2015-05-28 23:38:27 +02:00
|
|
|
/* Required fields must be set: pack functions don't check! */
|
|
|
|
assert(anchor->inputs);
|
|
|
|
assert(anchor->pubkey);
|
|
|
|
|
2015-05-26 06:38:12 +02:00
|
|
|
o.seed = seed;
|
2015-05-28 23:38:27 +02:00
|
|
|
o.revocation_hash = sha256_to_proto(ctx, revocation_hash);
|
2015-06-07 22:59:15 +02:00
|
|
|
o.final = pubkey_to_proto(ctx, to_me);
|
2015-05-26 06:38:12 +02:00
|
|
|
o.commitment_fee = commitment_fee;
|
|
|
|
o.anchor = anchor;
|
|
|
|
o.locktime_seconds = rel_locktime_seconds;
|
2015-05-28 23:38:27 +02:00
|
|
|
o.tx_version = BITCOIN_TX_VERSION;
|
|
|
|
|
|
|
|
{
|
|
|
|
size_t len = open_channel__get_packed_size(&o);
|
|
|
|
unsigned char *pb = malloc(len);
|
|
|
|
open_channel__pack(&o, pb);
|
|
|
|
assert(open_channel__unpack(NULL, len, pb));
|
|
|
|
}
|
|
|
|
|
2015-05-26 06:38:12 +02:00
|
|
|
return to_pkt(ctx, PKT__PKT_OPEN, &o);
|
|
|
|
}
|
2015-05-28 23:38:27 +02:00
|
|
|
|
2015-06-09 06:07:30 +02:00
|
|
|
Pkt *any_pkt_from_file(const char *filename)
|
2015-05-28 23:38:27 +02:00
|
|
|
{
|
|
|
|
struct pkt *pkt;
|
|
|
|
Pkt *ret;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
pkt = grab_file(NULL, filename);
|
|
|
|
if (!pkt)
|
|
|
|
err(1, "Opening %s", filename);
|
|
|
|
|
|
|
|
len = tal_count(pkt) - 1;
|
|
|
|
if (len < sizeof(pkt->len)
|
|
|
|
|| len != sizeof(pkt->len) + le32_to_cpu(pkt->len))
|
|
|
|
errx(1, "%s length is wrong", filename);
|
|
|
|
len -= sizeof(pkt->len);
|
|
|
|
|
|
|
|
ret = pkt__unpack(NULL, len, pkt->data);
|
|
|
|
if (!ret)
|
|
|
|
errx(1, "Unpack failed for %s", filename);
|
2015-06-09 06:07:30 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
Pkt *pkt_from_file(const char *filename, Pkt__PktCase expect)
|
|
|
|
{
|
|
|
|
Pkt *ret = any_pkt_from_file(filename);
|
2015-05-28 23:38:27 +02:00
|
|
|
|
|
|
|
if (ret->pkt_case != expect)
|
|
|
|
errx(1, "Unexpected type %i in %s", ret->pkt_case, filename);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct pkt *open_anchor_sig_pkt(const tal_t *ctx, u8 **sigs, size_t num_sigs)
|
|
|
|
{
|
2015-06-04 03:36:57 +02:00
|
|
|
OpenAnchorScriptsigs o = OPEN_ANCHOR_SCRIPTSIGS__INIT;
|
2015-05-28 23:38:27 +02:00
|
|
|
size_t i;
|
|
|
|
|
|
|
|
o.n_script = num_sigs;
|
|
|
|
o.script = tal_arr(ctx, ProtobufCBinaryData, num_sigs);
|
|
|
|
for (i = 0; i < num_sigs; i++) {
|
|
|
|
o.script[i].data = sigs[i];
|
|
|
|
o.script[i].len = tal_count(sigs[i]);
|
|
|
|
}
|
|
|
|
|
2015-06-04 03:36:57 +02:00
|
|
|
return to_pkt(ctx, PKT__PKT_OPEN_ANCHOR_SCRIPTSIGS, &o);
|
2015-05-28 23:38:27 +02:00
|
|
|
}
|
2015-05-29 03:22:18 +02:00
|
|
|
|
|
|
|
struct pkt *leak_anchor_sigs_and_pretend_we_didnt_pkt(const tal_t *ctx,
|
2015-06-04 03:36:57 +02:00
|
|
|
OpenAnchorScriptsigs *s)
|
2015-05-29 03:22:18 +02:00
|
|
|
{
|
|
|
|
LeakAnchorSigsAndPretendWeDidnt omg_fail
|
|
|
|
= LEAK_ANCHOR_SIGS_AND_PRETEND_WE_DIDNT__INIT;
|
|
|
|
|
2015-05-30 12:41:10 +02:00
|
|
|
omg_fail.sigs = s;
|
2015-05-29 03:22:18 +02:00
|
|
|
return to_pkt(ctx, PKT__PKT_OMG_FAIL, &omg_fail);
|
|
|
|
}
|
2015-05-30 12:41:10 +02:00
|
|
|
|
2015-06-01 04:26:09 +02:00
|
|
|
struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig)
|
2015-05-30 12:41:10 +02:00
|
|
|
{
|
|
|
|
OpenCommitSig o = OPEN_COMMIT_SIG__INIT;
|
|
|
|
|
2015-06-01 04:26:09 +02:00
|
|
|
o.sig = signature_to_proto(ctx, sig);
|
2015-05-30 12:41:10 +02:00
|
|
|
return to_pkt(ctx, PKT__PKT_OPEN_COMMIT_SIG, &o);
|
|
|
|
}
|
2015-06-08 07:14:47 +02:00
|
|
|
|
|
|
|
struct pkt *close_channel_pkt(const tal_t *ctx, const struct signature *sig)
|
|
|
|
{
|
|
|
|
CloseChannel c = CLOSE_CHANNEL__INIT;
|
|
|
|
c.sig = signature_to_proto(ctx, sig);
|
|
|
|
return to_pkt(ctx, PKT__PKT_CLOSE, &c);
|
|
|
|
}
|
2015-06-08 07:21:29 +02:00
|
|
|
|
|
|
|
struct pkt *close_channel_complete_pkt(const tal_t *ctx,
|
|
|
|
const struct signature *sig)
|
|
|
|
{
|
|
|
|
CloseChannelComplete c = CLOSE_CHANNEL_COMPLETE__INIT;
|
|
|
|
c.sig = signature_to_proto(ctx, sig);
|
|
|
|
return to_pkt(ctx, PKT__PKT_CLOSE_COMPLETE, &c);
|
|
|
|
}
|
2015-06-08 08:44:52 +02:00
|
|
|
|
|
|
|
struct pkt *update_pkt(const tal_t *ctx,
|
|
|
|
const struct sha256 *revocation_hash,
|
|
|
|
s64 delta, struct signature *sig)
|
|
|
|
{
|
|
|
|
Update u = UPDATE__INIT;
|
|
|
|
u.revocation_hash = sha256_to_proto(ctx, revocation_hash);
|
|
|
|
u.delta = delta;
|
|
|
|
u.sig = signature_to_proto(ctx, sig);
|
|
|
|
return to_pkt(ctx, PKT__PKT_UPDATE, &u);
|
|
|
|
}
|
|
|
|
|
2015-06-08 22:29:06 +02:00
|
|
|
struct pkt *update_accept_pkt(const tal_t *ctx,
|
|
|
|
struct signature *sig,
|
|
|
|
const struct sha256 *revocation_hash,
|
|
|
|
const struct sha256 *revocation_preimage)
|
|
|
|
{
|
|
|
|
UpdateAccept ua = UPDATE_ACCEPT__INIT;
|
|
|
|
ua.sig = signature_to_proto(ctx, sig);
|
|
|
|
ua.revocation_hash = sha256_to_proto(ctx, revocation_hash);
|
|
|
|
ua.revocation_preimage = sha256_to_proto(ctx, revocation_preimage);
|
|
|
|
return to_pkt(ctx, PKT__PKT_UPDATE_ACCEPT, &ua);
|
|
|
|
}
|
2015-06-09 06:07:30 +02:00
|
|
|
|
|
|
|
struct pkt *update_complete_pkt(const tal_t *ctx,
|
|
|
|
const struct sha256 *revocation_preimage)
|
|
|
|
{
|
|
|
|
UpdateComplete uc = UPDATE_COMPLETE__INIT;
|
|
|
|
uc.revocation_preimage = sha256_to_proto(ctx, revocation_preimage);
|
|
|
|
return to_pkt(ctx, PKT__PKT_UPDATE_COMPLETE, &uc);
|
|
|
|
}
|