mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
lightningd: keep last valid tx, and its signature.
This avoids us having to reconstruct it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -489,6 +489,8 @@ void add_peer(struct lightningd *ld, u64 unique_id,
|
||||
peer->our_msatoshi = NULL;
|
||||
peer->state = UNINITIALIZED;
|
||||
peer->channel_info = NULL;
|
||||
peer->last_tx = NULL;
|
||||
peer->last_sig = NULL;
|
||||
peer->last_was_revoke = false;
|
||||
peer->last_sent_commit = NULL;
|
||||
peer->remote_shutdown_scriptpubkey = NULL;
|
||||
|
||||
@@ -76,6 +76,10 @@ struct peer {
|
||||
/* Amount going to us, not counting unfinished HTLCs; if we have one. */
|
||||
u64 *our_msatoshi;
|
||||
|
||||
/* Last tx they gave us (if any). */
|
||||
struct bitcoin_tx *last_tx;
|
||||
secp256k1_ecdsa_signature *last_sig;
|
||||
|
||||
/* Keys for channel. */
|
||||
struct channel_info *channel_info;
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ char *dbmigrations[] = {
|
||||
" shutdown_keyidx_local INTEGER,"
|
||||
" last_sent_commit_state INTEGER,"
|
||||
" last_sent_commit_id INTEGER,"
|
||||
" last_tx BLOB,"
|
||||
" last_sig BLOB,"
|
||||
" closing_fee_received INTEGER,"
|
||||
" closing_sig_received BLOB,"
|
||||
" PRIMARY KEY (id)"
|
||||
|
||||
@@ -377,6 +377,14 @@ 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;
|
||||
@@ -506,6 +514,17 @@ static bool wallet_stmt2channel(struct wallet *w, sqlite3_stmt *stmt,
|
||||
col += 2;
|
||||
}
|
||||
|
||||
/* Do we have last_tx? If so, populate. */
|
||||
if (sqlite3_column_type(stmt, col) != SQLITE_NULL) {
|
||||
chan->peer->last_tx = sqlite3_column_tx(chan->peer, stmt, col++);
|
||||
chan->peer->last_sig = tal(chan->peer, secp256k1_ecdsa_signature);
|
||||
sqlite3_column_sig(stmt, col++, chan->peer->last_sig);
|
||||
} else {
|
||||
chan->peer->last_tx = tal_free(chan->peer->last_tx);
|
||||
chan->peer->last_sig = tal_free(chan->peer->last_sig);
|
||||
col += 2;
|
||||
}
|
||||
|
||||
chan->peer->closing_fee_received = sqlite3_column_int64(stmt, col++);
|
||||
if (sqlite3_column_type(stmt, col) != SQLITE_NULL) {
|
||||
if (!chan->peer->closing_sig_received) {
|
||||
@@ -515,7 +534,7 @@ static bool wallet_stmt2channel(struct wallet *w, sqlite3_stmt *stmt,
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
assert(col == 34);
|
||||
assert(col == 36);
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -540,6 +559,7 @@ bool wallet_channel_load(struct wallet *w, const u64 id,
|
||||
"old_per_commit_remote, feerate_per_kw, shachain_remote_id, "
|
||||
"shutdown_scriptpubkey_remote, shutdown_keyidx_local, "
|
||||
"last_sent_commit_state, last_sent_commit_id, "
|
||||
"last_tx, last_sig, "
|
||||
"closing_fee_received, closing_sig_received FROM channels WHERE "
|
||||
"id=%" PRIu64 ";";
|
||||
|
||||
@@ -573,6 +593,14 @@ static char* db_serialize_pubkey(const tal_t *ctx, struct pubkey *pk)
|
||||
return tal_hex(ctx, der);
|
||||
}
|
||||
|
||||
static char* db_serialize_tx(const tal_t *ctx, const struct bitcoin_tx *tx)
|
||||
{
|
||||
if (!tx)
|
||||
return "NULL";
|
||||
|
||||
return tal_fmt(ctx, "'%s'", tal_hex(ctx, linearize_tx(ctx, tx)));
|
||||
}
|
||||
|
||||
bool wallet_channel_config_save(struct wallet *w, struct channel_config *cc)
|
||||
{
|
||||
bool ok = true;
|
||||
@@ -674,6 +702,7 @@ bool wallet_channel_save(struct wallet *w, struct wallet_channel *chan){
|
||||
" shutdown_scriptpubkey_remote='%s',"
|
||||
" shutdown_keyidx_local=%"PRIu64","
|
||||
" channel_config_local=%"PRIu64","
|
||||
" last_tx=%s, last_sig=%s, "
|
||||
" closing_fee_received=%"PRIu64","
|
||||
" closing_sig_received=%s"
|
||||
" WHERE id=%"PRIu64,
|
||||
@@ -696,6 +725,8 @@ bool wallet_channel_save(struct wallet *w, struct wallet_channel *chan){
|
||||
p->remote_shutdown_scriptpubkey?tal_hex(tmpctx, p->remote_shutdown_scriptpubkey):"",
|
||||
p->local_shutdown_idx,
|
||||
p->our_config.id,
|
||||
db_serialize_tx(tmpctx, p->last_tx),
|
||||
db_serialize_signature(tmpctx, p->last_sig),
|
||||
p->closing_fee_received,
|
||||
db_serialize_signature(tmpctx, p->closing_sig_received),
|
||||
chan->id);
|
||||
|
||||
@@ -113,6 +113,18 @@ static bool test_shachain_crud(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bitcoin_tx_eq(const struct bitcoin_tx *tx1,
|
||||
const struct bitcoin_tx *tx2)
|
||||
{
|
||||
u8 *lin1, *lin2;
|
||||
bool eq;
|
||||
lin1 = linearize_tx(NULL, tx1);
|
||||
lin2 = linearize_tx(lin1, tx2);
|
||||
eq = memeq(lin1, tal_len(lin1), lin2, tal_len(lin2));
|
||||
tal_free(lin1);
|
||||
return eq;
|
||||
}
|
||||
|
||||
static bool channelseq(struct wallet_channel *c1, struct wallet_channel *c2)
|
||||
{
|
||||
struct peer *p1 = c1->peer, *p2 = c2->peer;
|
||||
@@ -154,6 +166,16 @@ static bool channelseq(struct wallet_channel *c1, struct wallet_channel *c2)
|
||||
CHECK(lc1->id == lc2->id);
|
||||
}
|
||||
|
||||
CHECK((p1->last_tx != NULL) == (p2->last_tx != NULL));
|
||||
if(p1->last_tx) {
|
||||
CHECK(bitcoin_tx_eq(p1->last_tx, p2->last_tx));
|
||||
}
|
||||
CHECK((p1->last_sig != NULL) == (p2->last_sig != NULL));
|
||||
if(p1->last_sig) {
|
||||
CHECK(memeq(p1->last_sig, sizeof(*p1->last_sig),
|
||||
p2->last_sig, sizeof(*p2->last_sig)));
|
||||
}
|
||||
|
||||
CHECK((p1->closing_sig_received != NULL) == (p2->closing_sig_received != NULL));
|
||||
if(p1->closing_sig_received) {
|
||||
CHECK(memeq(p1->closing_sig_received,
|
||||
@@ -192,6 +214,7 @@ static bool test_channel_crud(const tal_t *ctx)
|
||||
p.id = pk;
|
||||
p.unique_id = 42;
|
||||
p.our_msatoshi = NULL;
|
||||
p.last_tx = NULL;
|
||||
memset(&ci.their_config, 0, sizeof(struct channel_config));
|
||||
ci.remote_fundingkey = pk;
|
||||
ci.theirbase.revocation = pk;
|
||||
@@ -200,7 +223,7 @@ static bool test_channel_crud(const tal_t *ctx)
|
||||
ci.remote_per_commit = pk;
|
||||
ci.old_remote_per_commit = pk;
|
||||
|
||||
/* Variant 1: insert with null for scid, funding_tx_id, and channel_info */
|
||||
/* Variant 1: insert with null for scid, funding_tx_id, channel_info, last_tx */
|
||||
CHECK_MSG(wallet_channel_save(w, &c1), tal_fmt(w, "Insert into DB: %s", w->db->err));
|
||||
CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err));
|
||||
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v1)");
|
||||
@@ -245,12 +268,19 @@ static bool test_channel_crud(const tal_t *ctx)
|
||||
CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err));
|
||||
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v6)");
|
||||
|
||||
/* Variant 7: update with closing_sig */
|
||||
p.closing_sig_received = sig;
|
||||
/* Variant 7: update with last_tx (taken from BOLT #3) */
|
||||
p.last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"));
|
||||
p.last_sig = sig;
|
||||
CHECK_MSG(wallet_channel_save(w, &c1), tal_fmt(w, "Insert into DB: %s", w->db->err));
|
||||
CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err));
|
||||
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v7)");
|
||||
|
||||
/* Variant 8: update with closing_sig */
|
||||
p.closing_sig_received = sig;
|
||||
CHECK_MSG(wallet_channel_save(w, &c1), tal_fmt(w, "Insert into DB: %s", w->db->err));
|
||||
CHECK_MSG(wallet_channel_load(w, c1.id, c2), tal_fmt(w, "Load from DB: %s", w->db->err));
|
||||
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v8)");
|
||||
|
||||
tal_free(w);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user