bitcoind: getrawblock helper.
It turns out using the verbose=false parameter, you can get the raw block from getblock. Do that. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3d9cb81215
commit
e7b9a913a6
2
Makefile
2
Makefile
|
@ -22,6 +22,7 @@ TEST_PROGRAMS := \
|
||||||
|
|
||||||
BITCOIN_SRC := \
|
BITCOIN_SRC := \
|
||||||
bitcoin/base58.c \
|
bitcoin/base58.c \
|
||||||
|
bitcoin/block.c \
|
||||||
bitcoin/locktime.c \
|
bitcoin/locktime.c \
|
||||||
bitcoin/pubkey.c \
|
bitcoin/pubkey.c \
|
||||||
bitcoin/script.c \
|
bitcoin/script.c \
|
||||||
|
@ -129,6 +130,7 @@ CCAN_HEADERS := \
|
||||||
|
|
||||||
BITCOIN_HEADERS := bitcoin/address.h \
|
BITCOIN_HEADERS := bitcoin/address.h \
|
||||||
bitcoin/base58.h \
|
bitcoin/base58.h \
|
||||||
|
bitcoin/block.h \
|
||||||
bitcoin/locktime.h \
|
bitcoin/locktime.h \
|
||||||
bitcoin/privkey.h \
|
bitcoin/privkey.h \
|
||||||
bitcoin/pubkey.h \
|
bitcoin/pubkey.h \
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "bitcoin/block.h"
|
||||||
|
#include "bitcoin/tx.h"
|
||||||
|
#include <ccan/str/hex/hex.h>
|
||||||
|
|
||||||
|
/* Encoding is <blockhdr> <varint-num-txs> <tx>... */
|
||||||
|
struct bitcoin_block *bitcoin_block_from_hex(const tal_t *ctx,
|
||||||
|
const char *hex, size_t hexlen)
|
||||||
|
{
|
||||||
|
struct bitcoin_block *b;
|
||||||
|
u8 *linear_tx;
|
||||||
|
const u8 *p;
|
||||||
|
size_t len, i, num;
|
||||||
|
|
||||||
|
if (hexlen && hex[hexlen-1] == '\n')
|
||||||
|
hexlen--;
|
||||||
|
|
||||||
|
/* Set up the block for success. */
|
||||||
|
b = tal(ctx, struct bitcoin_block);
|
||||||
|
|
||||||
|
/* De-hex the array. */
|
||||||
|
len = hex_data_size(hexlen);
|
||||||
|
p = linear_tx = tal_arr(ctx, u8, len);
|
||||||
|
if (!hex_decode(hex, hexlen, linear_tx, len))
|
||||||
|
return tal_free(b);
|
||||||
|
|
||||||
|
pull(&p, &len, &b->hdr, sizeof(b->hdr));
|
||||||
|
num = pull_varint(&p, &len);
|
||||||
|
b->tx = tal_arr(b, struct bitcoin_tx *, num);
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
b->tx[i] = pull_bitcoin_tx(b->tx, &p, &len);
|
||||||
|
|
||||||
|
/* We should end up not overrunning, nor have extra */
|
||||||
|
if (!p || len)
|
||||||
|
return tal_free(b);
|
||||||
|
|
||||||
|
tal_free(linear_tx);
|
||||||
|
return b;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef LIGHTNING_BITCOIN_BLOCK_H
|
||||||
|
#define LIGHTNING_BITCOIN_BLOCK_H
|
||||||
|
#include "config.h"
|
||||||
|
#include "bitcoin/shadouble.h"
|
||||||
|
#include <ccan/endian/endian.h>
|
||||||
|
#include <ccan/short_types/short_types.h>
|
||||||
|
#include <ccan/tal/tal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct bitcoin_block_hdr {
|
||||||
|
le32 version;
|
||||||
|
struct sha256_double prev_hash;
|
||||||
|
struct sha256_double merkle_hash;
|
||||||
|
le32 timestamp;
|
||||||
|
le32 target;
|
||||||
|
le32 nonce;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bitcoin_block {
|
||||||
|
struct bitcoin_block_hdr hdr;
|
||||||
|
/* tal_count shows now many */
|
||||||
|
struct bitcoin_tx **tx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bitcoin_block *bitcoin_block_from_hex(const tal_t *ctx,
|
||||||
|
const char *hex, size_t hexlen);
|
||||||
|
|
||||||
|
#endif /* LIGHTNING_BITCOIN_BLOCK_H */
|
16
bitcoin/tx.c
16
bitcoin/tx.c
|
@ -1,3 +1,4 @@
|
||||||
|
#include "bitcoin/block.h"
|
||||||
#include "tx.h"
|
#include "tx.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ccan/cast/cast.h>
|
#include <ccan/cast/cast.h>
|
||||||
|
@ -343,7 +344,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets *cursor to NULL and returns NULL when a pull fails. */
|
/* Sets *cursor to NULL and returns NULL when a pull fails. */
|
||||||
static const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
|
const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
|
||||||
{
|
{
|
||||||
const u8 *p = *cursor;
|
const u8 *p = *cursor;
|
||||||
|
|
||||||
|
@ -362,7 +363,7 @@ static const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
|
||||||
return memcheck(p, n);
|
return memcheck(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 pull_varint(const u8 **cursor, size_t *max)
|
u64 pull_varint(const u8 **cursor, size_t *max)
|
||||||
{
|
{
|
||||||
u64 ret;
|
u64 ret;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -470,8 +471,8 @@ static void pull_witness(struct bitcoin_tx_input *inputs, size_t i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
||||||
const u8 **cursor, size_t *max)
|
const u8 **cursor, size_t *max)
|
||||||
{
|
{
|
||||||
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
struct bitcoin_tx *tx = tal(ctx, struct bitcoin_tx);
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -505,8 +506,8 @@ static struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
||||||
}
|
}
|
||||||
tx->lock_time = pull_le32(cursor, max);
|
tx->lock_time = pull_le32(cursor, max);
|
||||||
|
|
||||||
/* If we ran short, or have bytes left over, fail. */
|
/* If we ran short, fail. */
|
||||||
if (!*cursor || *max != 0)
|
if (!*cursor)
|
||||||
tx = tal_free(tx);
|
tx = tal_free(tx);
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
@ -533,6 +534,9 @@ struct bitcoin_tx *bitcoin_tx_from_hex(const tal_t *ctx, const char *hex,
|
||||||
if (!tx)
|
if (!tx)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
goto fail_free_tx;
|
||||||
|
|
||||||
if (end != hex + hexlen && *end != '\n')
|
if (end != hex + hexlen && *end != '\n')
|
||||||
goto fail_free_tx;
|
goto fail_free_tx;
|
||||||
|
|
||||||
|
|
|
@ -73,4 +73,11 @@ bool bitcoin_txid_from_hex(const char *hexstr, size_t hexstr_len,
|
||||||
bool bitcoin_txid_to_hex(const struct sha256_double *txid,
|
bool bitcoin_txid_to_hex(const struct sha256_double *txid,
|
||||||
char *hexstr, size_t hexstr_len);
|
char *hexstr, size_t hexstr_len);
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal de-linearization functions. */
|
||||||
|
struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx,
|
||||||
|
const u8 **cursor, size_t *max);
|
||||||
|
u64 pull_varint(const u8 **cursor, size_t *max);
|
||||||
|
const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n);
|
||||||
|
|
||||||
#endif /* LIGHTNING_BITCOIN_TX_H */
|
#endif /* LIGHTNING_BITCOIN_TX_H */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* Code for talking to bitcoind. We use bitcoin-cli. */
|
/* Code for talking to bitcoind. We use bitcoin-cli. */
|
||||||
#include "bitcoin/base58.h"
|
#include "bitcoin/base58.h"
|
||||||
|
#include "bitcoin/block.h"
|
||||||
#include "bitcoin/shadouble.h"
|
#include "bitcoin/shadouble.h"
|
||||||
#include "bitcoin/tx.h"
|
#include "bitcoin/tx.h"
|
||||||
#include "bitcoind.h"
|
#include "bitcoind.h"
|
||||||
|
@ -724,6 +725,40 @@ void bitcoind_getblock_(struct lightningd_state *dstate,
|
||||||
"getblock", hex, NULL);
|
"getblock", hex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void process_rawblock(struct bitcoin_cli *bcli)
|
||||||
|
{
|
||||||
|
struct bitcoin_block *blk;
|
||||||
|
void (*cb)(struct lightningd_state *dstate,
|
||||||
|
struct bitcoin_block *blk,
|
||||||
|
void *arg) = bcli->cb;
|
||||||
|
|
||||||
|
/* FIXME: Just get header if we can't get full block. */
|
||||||
|
if (!bcli->output)
|
||||||
|
fatal("%s: unknown block?", bcli_args(bcli));
|
||||||
|
|
||||||
|
blk = bitcoin_block_from_hex(bcli, bcli->output, bcli->output_bytes);
|
||||||
|
if (!blk)
|
||||||
|
fatal("%s: bad block '%.*s'?",
|
||||||
|
bcli_args(bcli),
|
||||||
|
(int)bcli->output_bytes, (char *)bcli->output);
|
||||||
|
|
||||||
|
cb(bcli->dstate, blk, bcli->cb_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitcoind_getrawblock_(struct lightningd_state *dstate,
|
||||||
|
const struct sha256_double *blockid,
|
||||||
|
void (*cb)(struct lightningd_state *dstate,
|
||||||
|
struct bitcoin_block *blk,
|
||||||
|
void *arg),
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
char hex[hex_str_size(sizeof(*blockid))];
|
||||||
|
|
||||||
|
hex_encode(blockid, sizeof(*blockid), hex, sizeof(hex));
|
||||||
|
start_bitcoin_cli(dstate, process_rawblock, cb, arg,
|
||||||
|
"getblock", hex, "false", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void process_getblockcount(struct bitcoin_cli *bcli)
|
static void process_getblockcount(struct bitcoin_cli *bcli)
|
||||||
{
|
{
|
||||||
u32 blockcount;
|
u32 blockcount;
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct lightningd_state;
|
||||||
struct ripemd160;
|
struct ripemd160;
|
||||||
struct bitcoin_tx;
|
struct bitcoin_tx;
|
||||||
struct peer;
|
struct peer;
|
||||||
|
struct bitcoin_block;
|
||||||
/* -datadir arg for bitcoin-cli. */
|
/* -datadir arg for bitcoin-cli. */
|
||||||
extern char *bitcoin_datadir;
|
extern char *bitcoin_datadir;
|
||||||
|
|
||||||
|
@ -121,6 +122,20 @@ void bitcoind_getblockhash_(struct lightningd_state *dstate,
|
||||||
const struct sha256_double *), \
|
const struct sha256_double *), \
|
||||||
(arg))
|
(arg))
|
||||||
|
|
||||||
|
void bitcoind_getrawblock_(struct lightningd_state *dstate,
|
||||||
|
const struct sha256_double *blockid,
|
||||||
|
void (*cb)(struct lightningd_state *dstate,
|
||||||
|
struct bitcoin_block *blk,
|
||||||
|
void *arg),
|
||||||
|
void *arg);
|
||||||
|
#define bitcoind_getrawblock(dstate, blkid, cb, arg) \
|
||||||
|
bitcoind_getrawblock_((dstate), (blkid), \
|
||||||
|
typesafe_cb_preargs(void, void *, \
|
||||||
|
(cb), (arg), \
|
||||||
|
struct lightningd_state *, \
|
||||||
|
struct bitcoin_block *), \
|
||||||
|
(arg))
|
||||||
|
|
||||||
void normalized_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
|
void normalized_txid(const struct bitcoin_tx *tx, struct sha256_double *txid);
|
||||||
|
|
||||||
void check_bitcoind_config(struct lightningd_state *dstate);
|
void check_bitcoind_config(struct lightningd_state *dstate);
|
||||||
|
|
Loading…
Reference in New Issue