wallet: Add check that wallet matches the network on startup

Adds a simple check that compares genesis-blockhashes from the
chainparams against the blockhash that the wallet was created
with. The wallet is network specific, so mixing is always a bad idea.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2018-02-16 17:55:33 +01:00 committed by Rusty Russell
parent 8787766d44
commit b2819f9f97
4 changed files with 50 additions and 0 deletions

View File

@ -304,6 +304,9 @@ int main(int argc, char *argv[])
/* Everything is within a transaction. */ /* Everything is within a transaction. */
db_begin_transaction(ld->wallet->db); db_begin_transaction(ld->wallet->db);
if (!wallet_network_check(ld->wallet, get_chainparams(ld)))
errx(1, "Wallet network check failed.");
/* Initialize the transaction filter with our pubkeys. */ /* Initialize the transaction filter with our pubkeys. */
init_txfilter(ld->wallet, ld->owned_txfilter); init_txfilter(ld->wallet, ld->owned_txfilter);

View File

@ -107,6 +107,10 @@ bool wallet_htlcs_reconnect(struct wallet *wallet UNNEEDED,
/* Generated stub for wallet_invoice_load */ /* Generated stub for wallet_invoice_load */
bool wallet_invoice_load(struct wallet *wallet UNNEEDED) bool wallet_invoice_load(struct wallet *wallet UNNEEDED)
{ fprintf(stderr, "wallet_invoice_load called!\n"); abort(); } { fprintf(stderr, "wallet_invoice_load called!\n"); abort(); }
/* Generated stub for wallet_network_check */
bool wallet_network_check(struct wallet *w UNNEEDED,
const struct chainparams *chainparams UNNEEDED)
{ fprintf(stderr, "wallet_network_check called!\n"); abort(); }
/* Generated stub for wallet_new */ /* Generated stub for wallet_new */
struct wallet *wallet_new(struct lightningd *ld UNNEEDED, struct wallet *wallet_new(struct lightningd *ld UNNEEDED,
struct log *log UNNEEDED, struct timers *timers UNNEEDED) struct log *log UNNEEDED, struct timers *timers UNNEEDED)

View File

@ -1618,3 +1618,34 @@ void wallet_htlc_sigs_save(struct wallet *w, u64 channel_id,
db_exec_prepared(w->db, stmt); db_exec_prepared(w->db, stmt);
} }
} }
bool wallet_network_check(struct wallet *w,
const struct chainparams *chainparams)
{
sqlite3_stmt *stmt = db_query(__func__, w->db,
"SELECT val FROM vars WHERE name='genesis_hash'");
struct bitcoin_blkid chainhash;
if (stmt && sqlite3_step(stmt) == SQLITE_ROW) {
sqlite3_column_sha256_double(stmt, 0, &chainhash.shad);
sqlite3_finalize(stmt);
if (!structeq(&chainhash, &chainparams->genesis_blockhash)) {
log_broken(w->log, "Wallet blockchain hash does not "
"match network blockchain hash: %s "
"!= %s",
type_to_string(w, struct bitcoin_blkid,
&chainhash),
type_to_string(w, struct bitcoin_blkid,
&chainparams->genesis_blockhash));
return false;
}
} else {
/* Still a pristine wallet, claim it for the chain
* that we are running */
sqlite3_finalize(stmt);
stmt = db_prepare(w->db, "INSERT INTO vars (name, val) VALUES ('genesis_hash', ?);");
sqlite3_bind_sha256_double(stmt, 1, &chainparams->genesis_blockhash.shad);
db_exec_prepared(w->db, stmt);
}
return true;
}

View File

@ -3,6 +3,7 @@
#include "config.h" #include "config.h"
#include "db.h" #include "db.h"
#include <bitcoin/chainparams.h>
#include <bitcoin/tx.h> #include <bitcoin/tx.h>
#include <ccan/crypto/shachain/shachain.h> #include <ccan/crypto/shachain/shachain.h>
#include <ccan/list/list.h> #include <ccan/list/list.h>
@ -618,4 +619,15 @@ const struct wallet_payment **wallet_payment_list(const tal_t *ctx,
*/ */
void wallet_htlc_sigs_save(struct wallet *w, u64 channel_id, void wallet_htlc_sigs_save(struct wallet *w, u64 channel_id,
secp256k1_ecdsa_signature *htlc_sigs); secp256k1_ecdsa_signature *htlc_sigs);
/**
* wallet_network_check - Check that the wallet is setup for this chain
*
* Ensure that the genesis_hash from the chainparams matches the
* genesis_hash with which the DB was initialized. Returns false if
* the check failed, i.e., if the genesis hashes do not match.
*/
bool wallet_network_check(struct wallet *w,
const struct chainparams *chainparams);
#endif /* WALLET_WALLET_H */ #endif /* WALLET_WALLET_H */