db: Added short_channel_id, tx, pubkey and signature primitives

We use these quite often and it is cumbersome having to do these
simple conversions inline, so just expose pseudo-sqlite3 methods to
bind and extract from/to a stmt.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2017-10-30 19:21:41 +01:00 committed by Rusty Russell
parent b267b24c08
commit 33da7f50c7
3 changed files with 125 additions and 24 deletions

View File

@ -419,3 +419,104 @@ bool sqlite3_column_hexval(sqlite3_stmt *s, int col, void *dest, size_t destlen)
return false;
return hex_decode(source, sourcelen, dest, destlen);
}
bool sqlite3_bind_short_channel_id(sqlite3_stmt *stmt, int col,
const struct short_channel_id *id)
{
char *ser = short_channel_id_to_str(id, id);
sqlite3_bind_blob(stmt, col, ser, strlen(ser), SQLITE_TRANSIENT);
tal_free(ser);
return true;
}
bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col,
struct short_channel_id *dest)
{
const char *source = sqlite3_column_blob(stmt, col);
size_t sourcelen = sqlite3_column_bytes(stmt, col);
return short_channel_id_from_str(source, sourcelen, dest);
}
bool sqlite3_bind_tx(sqlite3_stmt *stmt, int col, const struct bitcoin_tx *tx)
{
u8 *ser = linearize_tx(NULL, tx);
sqlite3_bind_blob(stmt, col, tal_hex(ser, ser), 2*tal_len(ser), SQLITE_TRANSIENT);
tal_free(ser);
return true;
}
struct bitcoin_tx *sqlite3_column_tx(const tal_t *ctx, sqlite3_stmt *stmt,
int col)
{
return bitcoin_tx_from_hex(
ctx,
sqlite3_column_blob(stmt, col),
sqlite3_column_bytes(stmt, col));
}
bool sqlite3_bind_signature(sqlite3_stmt *stmt, int col,
const secp256k1_ecdsa_signature *sig)
{
bool ok;
u8 buf[64];
ok = secp256k1_ecdsa_signature_serialize_compact(secp256k1_ctx, buf,
sig) == 1;
sqlite3_bind_blob(stmt, col, buf, sizeof(buf), SQLITE_TRANSIENT);
return ok;
}
bool sqlite3_column_signature(sqlite3_stmt *stmt, int col,
secp256k1_ecdsa_signature *sig)
{
assert(sqlite3_column_bytes(stmt, col) == 64);
return secp256k1_ecdsa_signature_parse_compact(
secp256k1_ctx, sig, sqlite3_column_blob(stmt, col)) == 1;
}
bool sqlite3_column_pubkey(sqlite3_stmt *stmt, int col, struct pubkey *dest)
{
u8 buf[PUBKEY_DER_LEN];
if (sqlite3_column_bytes(stmt, col) == 2*PUBKEY_DER_LEN) {
/* FIXME: Remove the legacy path for hex-values */
if (!sqlite3_column_hexval(stmt, col, buf, sizeof(buf)))
return false;
} else {
assert(sqlite3_column_bytes(stmt, col) == PUBKEY_DER_LEN);
memcpy(buf, sqlite3_column_blob(stmt, col), PUBKEY_DER_LEN);
}
return pubkey_from_der(buf, sizeof(buf), dest);
}
bool sqlite3_bind_pubkey(sqlite3_stmt *stmt, int col, const struct pubkey *pk)
{
u8 der[PUBKEY_DER_LEN];
pubkey_to_der(der, pk);
sqlite3_bind_blob(stmt, col, der, sizeof(der), SQLITE_TRANSIENT);
return true;
}
bool sqlite3_column_preimage(sqlite3_stmt *stmt, int col, struct preimage *dest)
{
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct preimage));
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct preimage));
}
bool sqlite3_bind_preimage(sqlite3_stmt *stmt, int col, const struct preimage *p)
{
sqlite3_bind_blob(stmt, col, p, sizeof(struct preimage), SQLITE_TRANSIENT);
return true;
}
bool sqlite3_column_sha256(sqlite3_stmt *stmt, int col, struct sha256 *dest)
{
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct sha256));
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct sha256));
}
bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p)
{
sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256), SQLITE_TRANSIENT);
return true;
}

View File

@ -2,9 +2,14 @@
#define WALLET_DB_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <bitcoin/preimage.h>
#include <bitcoin/short_channel_id.h>
#include <bitcoin/tx.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <secp256k1_ecdh.h>
#include <sqlite3.h>
#include <stdbool.h>
@ -111,4 +116,23 @@ sqlite3_stmt *db_prepare_(const char *caller, struct db *db, const char *query);
#define db_exec_prepared(db,stmt) db_exec_prepared_(__func__,db,stmt)
bool db_exec_prepared_(const char *caller, struct db *db, sqlite3_stmt *stmt);
bool sqlite3_bind_short_channel_id(sqlite3_stmt *stmt, int col,
const struct short_channel_id *id);
bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col,
struct short_channel_id *dest);
bool sqlite3_bind_tx(sqlite3_stmt *stmt, int col, const struct bitcoin_tx *tx);
struct bitcoin_tx *sqlite3_column_tx(const tal_t *ctx, sqlite3_stmt *stmt,
int col);
bool sqlite3_bind_signature(sqlite3_stmt *stmt, int col, const secp256k1_ecdsa_signature *sig);
bool sqlite3_column_signature(sqlite3_stmt *stmt, int col, secp256k1_ecdsa_signature *sig);
bool sqlite3_column_pubkey(sqlite3_stmt *stmt, int col, struct pubkey *dest);
bool sqlite3_bind_pubkey(sqlite3_stmt *stmt, int col, const struct pubkey *pk);
bool sqlite3_column_preimage(sqlite3_stmt *stmt, int col, struct preimage *dest);
bool sqlite3_bind_preimage(sqlite3_stmt *stmt, int col, const struct preimage *p);
bool sqlite3_column_sha256(sqlite3_stmt *stmt, int col, struct sha256 *dest);
bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p);
#endif /* WALLET_DB_H */

View File

@ -351,14 +351,6 @@ bool wallet_shachain_load(struct wallet *wallet, u64 id,
return true;
}
static bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col,
struct short_channel_id *dest)
{
const char *source = sqlite3_column_blob(stmt, col);
size_t sourcelen = sqlite3_column_bytes(stmt, col);
return short_channel_id_from_str(source, sourcelen, dest);
}
static bool sqlite3_column_sig(sqlite3_stmt *stmt, int col, secp256k1_ecdsa_signature *sig)
{
u8 buf[64];
@ -367,14 +359,6 @@ static bool sqlite3_column_sig(sqlite3_stmt *stmt, int col, secp256k1_ecdsa_sign
return secp256k1_ecdsa_signature_parse_compact(secp256k1_ctx, sig, buf) == 1;
}
static bool sqlite3_column_pubkey(sqlite3_stmt *stmt, int col, struct pubkey *dest)
{
u8 buf[PUBKEY_DER_LEN];
if (!sqlite3_column_hexval(stmt, col, buf, sizeof(buf)))
return false;
return pubkey_from_der(buf, sizeof(buf), dest);
}
static u8 *sqlite3_column_varhexblob(tal_t *ctx, sqlite3_stmt *stmt, int col)
{
const u8 *source = sqlite3_column_blob(stmt, col);
@ -382,14 +366,6 @@ static u8 *sqlite3_column_varhexblob(tal_t *ctx, sqlite3_stmt *stmt, int col)
return tal_hexdata(ctx, source, sourcelen);
}
static struct bitcoin_tx *sqlite3_column_tx(const tal_t *ctx,
sqlite3_stmt *stmt, int col)
{
return bitcoin_tx_from_hex(ctx,
sqlite3_column_blob(stmt, col),
sqlite3_column_bytes(stmt, col));
}
static bool wallet_peer_load(struct wallet *w, const u64 id, struct peer *peer)
{
bool ok = true;