core-lightning/wallet/test/run-wallet.c
Rusty Russell 2da5244e83 jsonrpc: make error codes an enum.
This allows GDB to print values, but also allows us to use them in
'case' statements.  This wasn't allowed before because they're not
constant terms.

This also made it clear there's a clash between two error codes,
so move one.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: JSON-RPC: Error code from bcli plugin changed from 400 to 500.
2022-09-19 10:18:55 +09:30

1940 lines
86 KiB
C

#include "config.h"
#include <lightningd/log.h>
#include "test_utils.h"
#include <ccan/tal/str/str.h>
#include <db/common.h>
static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const struct node_id *node_id UNUSED, bool call_notifier UNUSED, const char *fmt UNUSED, ...)
{
}
#define log_ db_log_
#ifndef DB_FATAL
#define DB_FATAL
static char *wallet_err;
void db_fatal(const char *fmt, ...)
{
va_list ap;
/* Fail hard if we're complaining about not being in transaction */
assert(!strstarts(fmt, "No longer in transaction"));
/* Fail hard if we're complaining about not being in transaction */
assert(!strstarts(fmt, "No longer in transaction"));
va_start(ap, fmt);
wallet_err = tal_vfmt(NULL, fmt, ap);
va_end(ap);
}
#endif /* DB_FATAL */
#include "wallet/wallet.c"
#include "lightningd/htlc_end.c"
#include "lightningd/peer_control.c"
#include "lightningd/peer_htlcs.c"
#include "lightningd/channel.c"
#include "db/bindings.c"
#include "db/db_sqlite3.c"
#include "db/exec.c"
#include "db/utils.c"
#include "wallet/db.c"
#include <common/setup.h>
#include <common/utils.h>
#include <stdio.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for bigsize_put */
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED)
{ fprintf(stderr, "bigsize_put called!\n"); abort(); }
/* Generated stub for bitcoind_getutxout_ */
void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
void (*cb)(struct bitcoind * UNNEEDED,
const struct bitcoin_tx_output * UNNEEDED,
void *) UNNEEDED,
void *arg UNNEEDED)
{ fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); }
/* Generated stub for blinding_hash_e_and_ss */
void blinding_hash_e_and_ss(const struct pubkey *e UNNEEDED,
const struct secret *ss UNNEEDED,
struct sha256 *sha UNNEEDED)
{ fprintf(stderr, "blinding_hash_e_and_ss called!\n"); abort(); }
/* Generated stub for blinding_next_pubkey */
bool blinding_next_pubkey(const struct pubkey *pk UNNEEDED,
const struct sha256 *h UNNEEDED,
struct pubkey *next UNNEEDED)
{ fprintf(stderr, "blinding_next_pubkey called!\n"); abort(); }
/* Generated stub for broadcast_tx */
void broadcast_tx(struct chain_topology *topo UNNEEDED,
struct channel *channel UNNEEDED, const struct bitcoin_tx *tx UNNEEDED,
const char *cmd_id UNNEEDED, bool allowhighfees UNNEEDED,
void (*failed)(struct channel * UNNEEDED,
bool success UNNEEDED,
const char *err))
{ fprintf(stderr, "broadcast_tx called!\n"); abort(); }
/* Generated stub for channel_tell_depth */
bool channel_tell_depth(struct lightningd *ld UNNEEDED,
struct channel *channel UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
u32 depth UNNEEDED)
{ fprintf(stderr, "channel_tell_depth called!\n"); abort(); }
/* Generated stub for channel_unsaved_close_conn */
void channel_unsaved_close_conn(struct channel *channel UNNEEDED, const char *why UNNEEDED)
{ fprintf(stderr, "channel_unsaved_close_conn called!\n"); abort(); }
/* Generated stub for channel_update_reserve */
void channel_update_reserve(struct channel *channel UNNEEDED,
struct channel_config *their_config UNNEEDED,
struct amount_sat funding_total UNNEEDED)
{ fprintf(stderr, "channel_update_reserve called!\n"); abort(); }
/* Generated stub for command_fail */
struct command_result *command_fail(struct command *cmd UNNEEDED, enum jsonrpc_errcode code UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "command_fail called!\n"); abort(); }
/* Generated stub for command_param_failed */
struct command_result *command_param_failed(void)
{ fprintf(stderr, "command_param_failed called!\n"); abort(); }
/* Generated stub for command_still_pending */
struct command_result *command_still_pending(struct command *cmd)
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
/* Generated stub for command_success */
struct command_result *command_success(struct command *cmd UNNEEDED,
struct json_stream *response)
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_any_cmd_id */
const char *connect_any_cmd_id(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED)
{ fprintf(stderr, "connect_any_cmd_id called!\n"); abort(); }
/* Generated stub for connect_failed_disconnect */
void connect_failed_disconnect(struct lightningd *ld UNNEEDED,
const struct node_id *id UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "connect_failed_disconnect called!\n"); abort(); }
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for create_onionreply */
struct onionreply *create_onionreply(const tal_t *ctx UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const u8 *failure_msg UNNEEDED)
{ fprintf(stderr, "create_onionreply called!\n"); abort(); }
/* Generated stub for deprecated_apis */
bool deprecated_apis;
/* Generated stub for derive_channel_id */
void derive_channel_id(struct channel_id *channel_id UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED)
{ fprintf(stderr, "derive_channel_id called!\n"); abort(); }
/* Generated stub for ecdh */
void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
{ fprintf(stderr, "ecdh called!\n"); abort(); }
/* Generated stub for encode_scriptpubkey_to_addr */
char *encode_scriptpubkey_to_addr(const tal_t *ctx UNNEEDED,
const struct chainparams *chainparams UNNEEDED,
const u8 *scriptPubkey UNNEEDED)
{ fprintf(stderr, "encode_scriptpubkey_to_addr called!\n"); abort(); }
/* Generated stub for fatal */
void fatal(const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "fatal called!\n"); abort(); }
/* Generated stub for fromwire_channeld_dev_memleak_reply */
bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_channeld_got_commitsig */
bool fromwire_channeld_got_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct fee_states **fee_states UNNEEDED, struct height_states **blockheight_states UNNEEDED, struct bitcoin_signature *signature UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, struct added_htlc **added UNNEEDED, struct fulfilled_htlc **fulfilled UNNEEDED, struct failed_htlc ***failed UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_tx **tx UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_got_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_channeld_got_revoke */
bool fromwire_channeld_got_revoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *revokenum UNNEEDED, struct secret *per_commitment_secret UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED, struct fee_states **fee_states UNNEEDED, struct height_states **blockheight_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct penalty_base **pbase UNNEEDED, struct bitcoin_tx **penalty_tx UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_got_revoke called!\n"); abort(); }
/* Generated stub for fromwire_channeld_offer_htlc_reply */
bool fromwire_channeld_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *id UNNEEDED, u8 **failuremsg UNNEEDED, wirestring **failurestr UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_offer_htlc_reply called!\n"); abort(); }
/* Generated stub for fromwire_channeld_sending_commitsig */
bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct penalty_base **pbase UNNEEDED, struct fee_states **fee_states UNNEEDED, struct height_states **blockheight_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, struct bitcoin_signature **htlc_sigs UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_sending_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_connected */
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_disconnect_done */
bool fromwire_connectd_peer_disconnect_done(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_disconnect_done called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_spoke */
bool fromwire_connectd_peer_spoke(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_spoke called!\n"); abort(); }
/* Generated stub for fromwire_dualopend_dev_memleak_reply */
bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_dualopend_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsmd_get_output_scriptpubkey_reply */
bool fromwire_hsmd_get_output_scriptpubkey_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **script UNNEEDED)
{ fprintf(stderr, "fromwire_hsmd_get_output_scriptpubkey_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsmd_new_channel_reply */
bool fromwire_hsmd_new_channel_reply(const void *p UNNEEDED)
{ fprintf(stderr, "fromwire_hsmd_new_channel_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsmd_sign_commitment_tx_reply */
bool fromwire_hsmd_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsmd_sign_commitment_tx_reply called!\n"); abort(); }
/* Generated stub for fromwire_onchaind_dev_memleak_reply */
bool fromwire_onchaind_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_onchaind_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_openingd_dev_memleak_reply */
bool fromwire_openingd_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_openingd_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for get_block_height */
u32 get_block_height(const struct chain_topology *topo UNNEEDED)
{ fprintf(stderr, "get_block_height called!\n"); abort(); }
/* Generated stub for get_channel_update */
const u8 *get_channel_update(struct channel *channel UNNEEDED)
{ fprintf(stderr, "get_channel_update called!\n"); abort(); }
/* Generated stub for htlc_is_trimmed */
bool htlc_is_trimmed(enum side htlc_owner UNNEEDED,
struct amount_msat htlc_amount UNNEEDED,
u32 feerate_per_kw UNNEEDED,
struct amount_sat dust_limit UNNEEDED,
enum side side UNNEEDED,
bool option_anchor_outputs UNNEEDED)
{ fprintf(stderr, "htlc_is_trimmed called!\n"); abort(); }
/* Generated stub for htlc_set_add */
void htlc_set_add(struct lightningd *ld UNNEEDED,
struct htlc_in *hin UNNEEDED,
struct amount_msat total_msat UNNEEDED,
const struct secret *payment_secret UNNEEDED)
{ fprintf(stderr, "htlc_set_add called!\n"); abort(); }
/* Generated stub for invoices_create */
bool invoices_create(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escape *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,
const char *description UNNEEDED,
const u8 *features UNNEEDED,
const struct preimage *r UNNEEDED,
const struct sha256 *rhash UNNEEDED,
const struct sha256 *local_offer_id UNNEEDED)
{ fprintf(stderr, "invoices_create called!\n"); abort(); }
/* Generated stub for invoices_delete */
bool invoices_delete(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_delete called!\n"); abort(); }
/* Generated stub for invoices_delete_description */
bool invoices_delete_description(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_delete_description called!\n"); abort(); }
/* Generated stub for invoices_delete_expired */
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
u64 max_expiry_time UNNEEDED)
{ fprintf(stderr, "invoices_delete_expired called!\n"); abort(); }
/* Generated stub for invoices_find_by_label */
bool invoices_find_by_label(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct json_escape *label UNNEEDED)
{ fprintf(stderr, "invoices_find_by_label called!\n"); abort(); }
/* Generated stub for invoices_find_by_rhash */
bool invoices_find_by_rhash(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_by_rhash called!\n"); abort(); }
/* Generated stub for invoices_find_unpaid */
bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
/* Generated stub for invoices_get_details */
struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED)
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
/* Generated stub for invoices_iterate */
bool invoices_iterate(struct invoices *invoices UNNEEDED,
struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterate called!\n"); abort(); }
/* Generated stub for invoices_iterator_deref */
const struct invoice_details *invoices_iterator_deref(
const tal_t *ctx UNNEEDED, struct invoices *invoices UNNEEDED,
const struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterator_deref called!\n"); abort(); }
/* Generated stub for invoices_new */
struct invoices *invoices_new(const tal_t *ctx UNNEEDED,
struct db *db UNNEEDED,
struct timers *timers UNNEEDED)
{ fprintf(stderr, "invoices_new called!\n"); abort(); }
/* Generated stub for invoices_resolve */
bool invoices_resolve(struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED,
struct amount_msat received UNNEEDED)
{ fprintf(stderr, "invoices_resolve called!\n"); abort(); }
/* Generated stub for invoices_waitany */
void invoices_waitany(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 lastpay_index UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitany called!\n"); abort(); }
/* Generated stub for invoices_waitone */
void invoices_waitone(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
struct invoice invoice UNNEEDED,
void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED,
void *cbarg UNNEEDED)
{ fprintf(stderr, "invoices_waitone called!\n"); abort(); }
/* Generated stub for json_add_address */
void json_add_address(struct json_stream *response UNNEEDED, const char *fieldname UNNEEDED,
const struct wireaddr *addr UNNEEDED)
{ fprintf(stderr, "json_add_address called!\n"); abort(); }
/* Generated stub for json_add_address_internal */
void json_add_address_internal(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "json_add_address_internal called!\n"); abort(); }
/* Generated stub for json_add_amount_msat_compat */
void json_add_amount_msat_compat(struct json_stream *result UNNEEDED,
struct amount_msat msat UNNEEDED,
const char *rawfieldname UNNEEDED,
const char *msatfieldname)
{ fprintf(stderr, "json_add_amount_msat_compat called!\n"); abort(); }
/* Generated stub for json_add_amount_msat_only */
void json_add_amount_msat_only(struct json_stream *result UNNEEDED,
const char *msatfieldname UNNEEDED,
struct amount_msat msat)
{ fprintf(stderr, "json_add_amount_msat_only called!\n"); abort(); }
/* Generated stub for json_add_amount_sat_compat */
void json_add_amount_sat_compat(struct json_stream *result UNNEEDED,
struct amount_sat sat UNNEEDED,
const char *rawfieldname UNNEEDED,
const char *msatfieldname)
{ fprintf(stderr, "json_add_amount_sat_compat called!\n"); abort(); }
/* Generated stub for json_add_amount_sat_msat */
void json_add_amount_sat_msat(struct json_stream *result UNNEEDED,
const char *msatfieldname UNNEEDED,
struct amount_sat sat)
{ fprintf(stderr, "json_add_amount_sat_msat called!\n"); abort(); }
/* Generated stub for json_add_bool */
void json_add_bool(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
bool value UNNEEDED)
{ fprintf(stderr, "json_add_bool called!\n"); abort(); }
/* Generated stub for json_add_channel_id */
void json_add_channel_id(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct channel_id *cid UNNEEDED)
{ fprintf(stderr, "json_add_channel_id called!\n"); abort(); }
/* Generated stub for json_add_hex_talarr */
void json_add_hex_talarr(struct json_stream *result UNNEEDED,
const char *fieldname UNNEEDED,
const tal_t *data UNNEEDED)
{ fprintf(stderr, "json_add_hex_talarr called!\n"); abort(); }
/* Generated stub for json_add_log */
void json_add_log(struct json_stream *result UNNEEDED,
const struct log_book *lr UNNEEDED,
const struct node_id *node_id UNNEEDED,
enum log_level minlevel UNNEEDED)
{ fprintf(stderr, "json_add_log called!\n"); abort(); }
/* Generated stub for json_add_node_id */
void json_add_node_id(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct node_id *id UNNEEDED)
{ fprintf(stderr, "json_add_node_id called!\n"); abort(); }
/* Generated stub for json_add_num */
void json_add_num(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
unsigned int value UNNEEDED)
{ fprintf(stderr, "json_add_num called!\n"); abort(); }
/* Generated stub for json_add_s32 */
void json_add_s32(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
int32_t value UNNEEDED)
{ fprintf(stderr, "json_add_s32 called!\n"); abort(); }
/* Generated stub for json_add_secret */
void json_add_secret(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct secret *secret UNNEEDED)
{ fprintf(stderr, "json_add_secret called!\n"); abort(); }
/* Generated stub for json_add_sha256 */
void json_add_sha256(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
const struct sha256 *hash UNNEEDED)
{ fprintf(stderr, "json_add_sha256 called!\n"); abort(); }
/* Generated stub for json_add_short_channel_id */
void json_add_short_channel_id(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct short_channel_id *id UNNEEDED)
{ fprintf(stderr, "json_add_short_channel_id called!\n"); abort(); }
/* Generated stub for json_add_string */
void json_add_string(struct json_stream *js UNNEEDED,
const char *fieldname UNNEEDED,
const char *str TAKES UNNEEDED)
{ fprintf(stderr, "json_add_string called!\n"); abort(); }
/* Generated stub for json_add_timeabs */
void json_add_timeabs(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
struct timeabs t UNNEEDED)
{ fprintf(stderr, "json_add_timeabs called!\n"); abort(); }
/* Generated stub for json_add_timeiso */
void json_add_timeiso(struct json_stream *result UNNEEDED,
const char *fieldname UNNEEDED,
struct timeabs *time UNNEEDED)
{ fprintf(stderr, "json_add_timeiso called!\n"); abort(); }
/* Generated stub for json_add_tx */
void json_add_tx(struct json_stream *result UNNEEDED,
const char *fieldname UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED)
{ fprintf(stderr, "json_add_tx called!\n"); abort(); }
/* Generated stub for json_add_txid */
void json_add_txid(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "json_add_txid called!\n"); abort(); }
/* Generated stub for json_add_u32 */
void json_add_u32(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
uint32_t value UNNEEDED)
{ fprintf(stderr, "json_add_u32 called!\n"); abort(); }
/* Generated stub for json_add_u64 */
void json_add_u64(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
uint64_t value UNNEEDED)
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
/* Generated stub for json_add_uncommitted_channel */
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED)
{ fprintf(stderr, "json_add_uncommitted_channel called!\n"); abort(); }
/* Generated stub for json_add_unsaved_channel */
void json_add_unsaved_channel(struct json_stream *response UNNEEDED,
const struct channel *channel UNNEEDED)
{ fprintf(stderr, "json_add_unsaved_channel called!\n"); abort(); }
/* Generated stub for json_array_end */
void json_array_end(struct json_stream *js UNNEEDED)
{ fprintf(stderr, "json_array_end called!\n"); abort(); }
/* Generated stub for json_array_start */
void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_array_start called!\n"); abort(); }
/* Generated stub for json_get_member */
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
const char *label UNNEEDED)
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
/* Generated stub for json_object_end */
void json_object_end(struct json_stream *js UNNEEDED)
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
/* Generated stub for json_object_start */
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
/* Generated stub for json_strdup */
char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_strdup called!\n"); abort(); }
/* Generated stub for json_stream_success */
struct json_stream *json_stream_success(struct command *cmd UNNEEDED)
{ fprintf(stderr, "json_stream_success called!\n"); abort(); }
/* Generated stub for json_to_node_id */
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct node_id *id UNNEEDED)
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
/* Generated stub for json_to_number */
bool json_to_number(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
unsigned int *num UNNEEDED)
{ fprintf(stderr, "json_to_number called!\n"); abort(); }
/* Generated stub for json_to_preimage */
bool json_to_preimage(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, struct preimage *preimage UNNEEDED)
{ fprintf(stderr, "json_to_preimage called!\n"); abort(); }
/* Generated stub for json_to_short_channel_id */
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
/* Generated stub for json_tok_bin_from_hex */
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
/* Generated stub for json_tok_channel_id */
bool json_tok_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct channel_id *cid UNNEEDED)
{ fprintf(stderr, "json_tok_channel_id called!\n"); abort(); }
/* Generated stub for json_tok_full */
const char *json_tok_full(const char *buffer UNNEEDED, const jsmntok_t *t UNNEEDED)
{ fprintf(stderr, "json_tok_full called!\n"); abort(); }
/* Generated stub for json_tok_full_len */
int json_tok_full_len(const jsmntok_t *t UNNEEDED)
{ fprintf(stderr, "json_tok_full_len called!\n"); abort(); }
/* Generated stub for json_tok_streq */
bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char *str UNNEEDED)
{ fprintf(stderr, "json_tok_streq called!\n"); abort(); }
/* Generated stub for kill_uncommitted_channel */
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
const char *why UNNEEDED)
{ fprintf(stderr, "kill_uncommitted_channel called!\n"); abort(); }
/* Generated stub for new_channel_mvt_invoice_hin */
struct channel_coin_mvt *new_channel_mvt_invoice_hin(const tal_t *ctx UNNEEDED,
struct htlc_in *hin UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "new_channel_mvt_invoice_hin called!\n"); abort(); }
/* Generated stub for new_channel_mvt_invoice_hout */
struct channel_coin_mvt *new_channel_mvt_invoice_hout(const tal_t *ctx UNNEEDED,
struct htlc_out *hout UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "new_channel_mvt_invoice_hout called!\n"); abort(); }
/* Generated stub for new_channel_mvt_routed_hin */
struct channel_coin_mvt *new_channel_mvt_routed_hin(const tal_t *ctx UNNEEDED,
struct htlc_in *hin UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "new_channel_mvt_routed_hin called!\n"); abort(); }
/* Generated stub for new_channel_mvt_routed_hout */
struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx UNNEEDED,
struct htlc_out *hout UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "new_channel_mvt_routed_hout called!\n"); abort(); }
/* Generated stub for new_coin_wallet_deposit */
struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
enum mvt_tag tag)
{ fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); }
/* Generated stub for new_peer_fd */
struct peer_fd *new_peer_fd(const tal_t *ctx UNNEEDED, int peer_fd UNNEEDED)
{ fprintf(stderr, "new_peer_fd called!\n"); abort(); }
/* Generated stub for new_uncommitted_channel */
struct uncommitted_channel *new_uncommitted_channel(struct peer *peer UNNEEDED)
{ fprintf(stderr, "new_uncommitted_channel called!\n"); abort(); }
/* Generated stub for notify_chain_mvt */
void notify_chain_mvt(struct lightningd *ld UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED)
{ fprintf(stderr, "notify_chain_mvt called!\n"); abort(); }
/* Generated stub for notify_channel_mvt */
void notify_channel_mvt(struct lightningd *ld UNNEEDED, const struct channel_coin_mvt *mvt UNNEEDED)
{ fprintf(stderr, "notify_channel_mvt called!\n"); abort(); }
/* Generated stub for notify_channel_open_failed */
void notify_channel_open_failed(struct lightningd *ld UNNEEDED,
const struct channel_id *cid UNNEEDED)
{ fprintf(stderr, "notify_channel_open_failed called!\n"); abort(); }
/* Generated stub for notify_channel_state_changed */
void notify_channel_state_changed(struct lightningd *ld UNNEEDED,
struct node_id *peer_id UNNEEDED,
struct channel_id *cid UNNEEDED,
struct short_channel_id *scid UNNEEDED,
struct timeabs *timestamp UNNEEDED,
enum channel_state old_state UNNEEDED,
enum channel_state new_state UNNEEDED,
enum state_change cause UNNEEDED,
char *message UNNEEDED)
{ fprintf(stderr, "notify_channel_state_changed called!\n"); abort(); }
/* Generated stub for notify_connect */
void notify_connect(struct lightningd *ld UNNEEDED,
const struct node_id *nodeid UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "notify_connect called!\n"); abort(); }
/* Generated stub for notify_disconnect */
void notify_disconnect(struct lightningd *ld UNNEEDED, struct node_id *nodeid UNNEEDED)
{ fprintf(stderr, "notify_disconnect called!\n"); abort(); }
/* Generated stub for notify_forward_event */
void notify_forward_event(struct lightningd *ld UNNEEDED,
const struct htlc_in *in UNNEEDED,
/* May be NULL if we don't know. */
const struct short_channel_id *scid_out UNNEEDED,
/* May be NULL. */
const struct amount_msat *amount_out UNNEEDED,
enum forward_status state UNNEEDED,
enum onion_wire failcode UNNEEDED,
struct timeabs *resolved_time UNNEEDED,
enum forward_style forward_style UNNEEDED)
{ fprintf(stderr, "notify_forward_event called!\n"); abort(); }
/* Generated stub for onchaind_funding_spent */
enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED,
u32 blockheight UNNEEDED)
{ fprintf(stderr, "onchaind_funding_spent called!\n"); abort(); }
/* Generated stub for onion_decode */
struct onion_payload *onion_decode(const tal_t *ctx UNNEEDED,
const struct route_step *rs UNNEEDED,
const struct pubkey *blinding UNNEEDED,
const struct secret *blinding_ss UNNEEDED,
const u64 *accepted_extra_tlvs UNNEEDED,
u64 *failtlvtype UNNEEDED,
size_t *failtlvpos UNNEEDED)
{ fprintf(stderr, "onion_decode called!\n"); abort(); }
/* Generated stub for onion_wire_name */
const char *onion_wire_name(int e UNNEEDED)
{ fprintf(stderr, "onion_wire_name called!\n"); abort(); }
/* Generated stub for outpointfilter_add */
void outpointfilter_add(struct outpointfilter *of UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED)
{ fprintf(stderr, "outpointfilter_add called!\n"); abort(); }
/* Generated stub for outpointfilter_matches */
bool outpointfilter_matches(struct outpointfilter *of UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED)
{ fprintf(stderr, "outpointfilter_matches called!\n"); abort(); }
/* Generated stub for outpointfilter_new */
struct outpointfilter *outpointfilter_new(tal_t *ctx UNNEEDED)
{ fprintf(stderr, "outpointfilter_new called!\n"); abort(); }
/* Generated stub for outpointfilter_remove */
void outpointfilter_remove(struct outpointfilter *of UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED)
{ fprintf(stderr, "outpointfilter_remove called!\n"); abort(); }
/* Generated stub for param */
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
const jsmntok_t params[] UNNEEDED, ...)
{ fprintf(stderr, "param called!\n"); abort(); }
/* Generated stub for param_bool */
struct command_result *param_bool(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
bool **b UNNEEDED)
{ fprintf(stderr, "param_bool called!\n"); abort(); }
/* Generated stub for param_channel_id */
struct command_result *param_channel_id(struct command *cmd UNNEEDED,
const char *name UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
struct channel_id **cid UNNEEDED)
{ fprintf(stderr, "param_channel_id called!\n"); abort(); }
/* Generated stub for param_loglevel */
struct command_result *param_loglevel(struct command *cmd UNNEEDED,
const char *name UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
enum log_level **level UNNEEDED)
{ fprintf(stderr, "param_loglevel called!\n"); abort(); }
/* Generated stub for param_msat */
struct command_result *param_msat(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct amount_msat **msat UNNEEDED)
{ fprintf(stderr, "param_msat called!\n"); abort(); }
/* Generated stub for param_node_id */
struct command_result *param_node_id(struct command *cmd UNNEEDED,
const char *name UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
struct node_id **id UNNEEDED)
{ fprintf(stderr, "param_node_id called!\n"); abort(); }
/* Generated stub for param_number */
struct command_result *param_number(struct command *cmd UNNEEDED, const char *name UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
unsigned int **num UNNEEDED)
{ fprintf(stderr, "param_number called!\n"); abort(); }
/* Generated stub for param_short_channel_id */
struct command_result *param_short_channel_id(struct command *cmd UNNEEDED,
const char *name UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
struct short_channel_id **scid UNNEEDED)
{ fprintf(stderr, "param_short_channel_id called!\n"); abort(); }
/* Generated stub for parse_onionpacket */
struct onionpacket *parse_onionpacket(const tal_t *ctx UNNEEDED,
const u8 *src UNNEEDED,
const size_t srclen UNNEEDED,
enum onion_wire *failcode UNNEEDED)
{ fprintf(stderr, "parse_onionpacket called!\n"); abort(); }
/* Generated stub for payment_failed */
void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout UNNEEDED,
const char *localfail UNNEEDED)
{ fprintf(stderr, "payment_failed called!\n"); abort(); }
/* Generated stub for payment_store */
void payment_store(struct lightningd *ld UNNEEDED, struct wallet_payment *payment UNNEEDED)
{ fprintf(stderr, "payment_store called!\n"); abort(); }
/* Generated stub for payment_succeeded */
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
const struct preimage *rval UNNEEDED)
{ fprintf(stderr, "payment_succeeded called!\n"); abort(); }
/* Generated stub for peer_restart_dualopend */
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
struct peer_fd *peer_fd UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "peer_restart_dualopend called!\n"); abort(); }
/* Generated stub for peer_start_channeld */
bool peer_start_channeld(struct channel *channel UNNEEDED,
struct peer_fd *peer_fd UNNEEDED,
const u8 *fwd_msg UNNEEDED,
bool reconnected UNNEEDED,
bool reestablish_only UNNEEDED)
{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); }
/* Generated stub for peer_start_dualopend */
bool peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED,
struct channel *channel UNNEEDED)
{ fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }
/* Generated stub for peer_start_openingd */
bool peer_start_openingd(struct peer *peer UNNEEDED,
struct peer_fd *peer_fd UNNEEDED)
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
/* Generated stub for peer_wire_name */
const char *peer_wire_name(int e UNNEEDED)
{ fprintf(stderr, "peer_wire_name called!\n"); abort(); }
/* Generated stub for plugin_hook_call_ */
bool plugin_hook_call_(struct lightningd *ld UNNEEDED,
const struct plugin_hook *hook UNNEEDED,
const char *cmd_id TAKES UNNEEDED,
tal_t *cb_arg STEALS UNNEEDED)
{ fprintf(stderr, "plugin_hook_call_ called!\n"); abort(); }
/* Generated stub for process_onionpacket */
struct route_step *process_onionpacket(
const tal_t * ctx UNNEEDED,
const struct onionpacket *packet UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const u8 *assocdata UNNEEDED,
const size_t assocdatalen UNNEEDED,
bool has_realm
)
{ fprintf(stderr, "process_onionpacket called!\n"); abort(); }
/* Generated stub for report_subd_memleak */
void report_subd_memleak(struct leak_detect *leak_detect UNNEEDED, struct subd *leaker UNNEEDED)
{ fprintf(stderr, "report_subd_memleak called!\n"); abort(); }
/* Generated stub for resolve_close_command */
const char *resolve_close_command(const tal_t *ctx UNNEEDED,
struct lightningd *ld UNNEEDED, struct channel *channel UNNEEDED,
bool cooperative UNNEEDED)
{ fprintf(stderr, "resolve_close_command called!\n"); abort(); }
/* Generated stub for serialize_onionpacket */
u8 *serialize_onionpacket(
const tal_t *ctx UNNEEDED,
const struct onionpacket *packet UNNEEDED)
{ fprintf(stderr, "serialize_onionpacket called!\n"); abort(); }
/* Generated stub for start_leak_request */
void start_leak_request(const struct subd_req *req UNNEEDED,
struct leak_detect *leak_detect UNNEEDED)
{ fprintf(stderr, "start_leak_request called!\n"); abort(); }
/* Generated stub for subd_release_channel */
void subd_release_channel(struct subd *owner UNNEEDED, const void *channel UNNEEDED)
{ fprintf(stderr, "subd_release_channel called!\n"); abort(); }
/* Generated stub for subd_req_ */
struct subd_req *subd_req_(const tal_t *ctx UNNEEDED,
struct subd *sd UNNEEDED,
const u8 *msg_out UNNEEDED,
int fd_out UNNEEDED, size_t num_fds_in UNNEEDED,
void (*replycb)(struct subd * UNNEEDED, const u8 * UNNEEDED, const int * UNNEEDED, void *) UNNEEDED,
void *replycb_data UNNEEDED)
{ fprintf(stderr, "subd_req_ called!\n"); abort(); }
/* Generated stub for subd_send_fd */
void subd_send_fd(struct subd *sd UNNEEDED, int fd UNNEEDED)
{ fprintf(stderr, "subd_send_fd called!\n"); abort(); }
/* Generated stub for subd_send_msg */
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
/* Generated stub for subkey_from_hmac */
void subkey_from_hmac(const char *prefix UNNEEDED,
const struct secret *base UNNEEDED,
struct secret *key UNNEEDED)
{ fprintf(stderr, "subkey_from_hmac called!\n"); abort(); }
/* Generated stub for topology_add_sync_waiter_ */
void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
void (*cb)(struct chain_topology * UNNEEDED,
void *) UNNEEDED,
void *arg UNNEEDED)
{ fprintf(stderr, "topology_add_sync_waiter_ called!\n"); abort(); }
/* Generated stub for towire_channeld_config_channel */
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_minimum UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
/* Generated stub for towire_channeld_dev_memleak */
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_channeld_dev_reenable_commit */
u8 *towire_channeld_dev_reenable_commit(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_dev_reenable_commit called!\n"); abort(); }
/* Generated stub for towire_channeld_fail_htlc */
u8 *towire_channeld_fail_htlc(const tal_t *ctx UNNEEDED, const struct failed_htlc *failed_htlc UNNEEDED)
{ fprintf(stderr, "towire_channeld_fail_htlc called!\n"); abort(); }
/* Generated stub for towire_channeld_fulfill_htlc */
u8 *towire_channeld_fulfill_htlc(const tal_t *ctx UNNEEDED, const struct fulfilled_htlc *fulfilled_htlc UNNEEDED)
{ fprintf(stderr, "towire_channeld_fulfill_htlc called!\n"); abort(); }
/* Generated stub for towire_channeld_got_commitsig_reply */
u8 *towire_channeld_got_commitsig_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_got_commitsig_reply called!\n"); abort(); }
/* Generated stub for towire_channeld_got_revoke_reply */
u8 *towire_channeld_got_revoke_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_got_revoke_reply called!\n"); abort(); }
/* Generated stub for towire_channeld_offer_htlc */
u8 *towire_channeld_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366] UNNEEDED, const struct pubkey *blinding UNNEEDED)
{ fprintf(stderr, "towire_channeld_offer_htlc called!\n"); abort(); }
/* Generated stub for towire_channeld_sending_commitsig_reply */
u8 *towire_channeld_sending_commitsig_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channeld_sending_commitsig_reply called!\n"); abort(); }
/* Generated stub for towire_connectd_discard_peer */
u8 *towire_connectd_discard_peer(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, u64 counter UNNEEDED)
{ fprintf(stderr, "towire_connectd_discard_peer called!\n"); abort(); }
/* Generated stub for towire_connectd_peer_connect_subd */
u8 *towire_connectd_peer_connect_subd(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, u64 counter UNNEEDED, const struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_connectd_peer_connect_subd called!\n"); abort(); }
/* Generated stub for towire_connectd_peer_final_msg */
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, u64 counter UNNEEDED, const u8 *msg UNNEEDED)
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
/* Generated stub for towire_dualopend_dev_memleak */
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_errorfmt */
u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_expiry_too_far */
u8 *towire_expiry_too_far(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_expiry_too_far called!\n"); abort(); }
/* Generated stub for towire_expiry_too_soon */
u8 *towire_expiry_too_soon(const tal_t *ctx UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_expiry_too_soon called!\n"); abort(); }
/* Generated stub for towire_fee_insufficient */
u8 *towire_fee_insufficient(const tal_t *ctx UNNEEDED, struct amount_msat htlc_msat UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_fee_insufficient called!\n"); abort(); }
/* Generated stub for towire_final_incorrect_cltv_expiry */
u8 *towire_final_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expiry UNNEEDED)
{ fprintf(stderr, "towire_final_incorrect_cltv_expiry called!\n"); abort(); }
/* Generated stub for towire_final_incorrect_htlc_amount */
u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx UNNEEDED, struct amount_msat incoming_htlc_amt UNNEEDED)
{ fprintf(stderr, "towire_final_incorrect_htlc_amount called!\n"); abort(); }
/* Generated stub for towire_gossipd_discovered_ip */
u8 *towire_gossipd_discovered_ip(const tal_t *ctx UNNEEDED, const struct wireaddr *discovered_ip UNNEEDED)
{ fprintf(stderr, "towire_gossipd_discovered_ip called!\n"); abort(); }
/* Generated stub for towire_hsmd_get_output_scriptpubkey */
u8 *towire_hsmd_get_output_scriptpubkey(const tal_t *ctx UNNEEDED, u64 channel_id UNNEEDED, const struct node_id *peer_id UNNEEDED, const struct pubkey *commitment_point UNNEEDED)
{ fprintf(stderr, "towire_hsmd_get_output_scriptpubkey called!\n"); abort(); }
/* Generated stub for towire_hsmd_new_channel */
u8 *towire_hsmd_new_channel(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, u64 dbid UNNEEDED)
{ fprintf(stderr, "towire_hsmd_new_channel called!\n"); abort(); }
/* Generated stub for towire_hsmd_sign_commitment_tx */
u8 *towire_hsmd_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 commit_num UNNEEDED)
{ fprintf(stderr, "towire_hsmd_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for towire_incorrect_cltv_expiry */
u8 *towire_incorrect_cltv_expiry(const tal_t *ctx UNNEEDED, u32 cltv_expiry UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_incorrect_cltv_expiry called!\n"); abort(); }
/* Generated stub for towire_incorrect_or_unknown_payment_details */
u8 *towire_incorrect_or_unknown_payment_details(const tal_t *ctx UNNEEDED, struct amount_msat htlc_msat UNNEEDED, u32 height UNNEEDED)
{ fprintf(stderr, "towire_incorrect_or_unknown_payment_details called!\n"); abort(); }
/* Generated stub for towire_invalid_onion_payload */
u8 *towire_invalid_onion_payload(const tal_t *ctx UNNEEDED, bigsize type UNNEEDED, u16 offset UNNEEDED)
{ fprintf(stderr, "towire_invalid_onion_payload called!\n"); abort(); }
/* Generated stub for towire_invalid_realm */
u8 *towire_invalid_realm(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_invalid_realm called!\n"); abort(); }
/* Generated stub for towire_onchaind_dev_memleak */
u8 *towire_onchaind_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_onchaind_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_onchaind_known_preimage */
u8 *towire_onchaind_known_preimage(const tal_t *ctx UNNEEDED, const struct preimage *preimage UNNEEDED)
{ fprintf(stderr, "towire_onchaind_known_preimage called!\n"); abort(); }
/* Generated stub for towire_openingd_dev_memleak */
u8 *towire_openingd_dev_memleak(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_openingd_dev_memleak called!\n"); abort(); }
/* Generated stub for towire_permanent_channel_failure */
u8 *towire_permanent_channel_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_permanent_channel_failure called!\n"); abort(); }
/* Generated stub for towire_permanent_node_failure */
u8 *towire_permanent_node_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_permanent_node_failure called!\n"); abort(); }
/* Generated stub for towire_required_channel_feature_missing */
u8 *towire_required_channel_feature_missing(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_required_channel_feature_missing called!\n"); abort(); }
/* Generated stub for towire_required_node_feature_missing */
u8 *towire_required_node_feature_missing(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_required_node_feature_missing called!\n"); abort(); }
/* Generated stub for towire_scb_chan */
void towire_scb_chan(u8 **p UNNEEDED, const struct scb_chan *scb_chan UNNEEDED)
{ fprintf(stderr, "towire_scb_chan called!\n"); abort(); }
/* Generated stub for towire_temporary_channel_failure */
u8 *towire_temporary_channel_failure(const tal_t *ctx UNNEEDED, const u8 *channel_update UNNEEDED)
{ fprintf(stderr, "towire_temporary_channel_failure called!\n"); abort(); }
/* Generated stub for towire_temporary_node_failure */
u8 *towire_temporary_node_failure(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_temporary_node_failure called!\n"); abort(); }
/* Generated stub for towire_unknown_next_peer */
u8 *towire_unknown_next_peer(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_unknown_next_peer called!\n"); abort(); }
/* Generated stub for towire_warningfmt */
u8 *towire_warningfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_warningfmt called!\n"); abort(); }
/* Generated stub for try_reconnect */
void try_reconnect(const tal_t *ctx UNNEEDED,
struct peer *peer UNNEEDED,
const struct wireaddr_internal *addrhint UNNEEDED)
{ fprintf(stderr, "try_reconnect called!\n"); abort(); }
/* Generated stub for watch_txid */
struct txwatch *watch_txid(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
struct channel *channel UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
enum watch_result (*cb)(struct lightningd *ld UNNEEDED,
struct channel * UNNEEDED,
const struct bitcoin_txid * UNNEEDED,
const struct bitcoin_tx * UNNEEDED,
unsigned int depth))
{ fprintf(stderr, "watch_txid called!\n"); abort(); }
/* Generated stub for watch_txo */
struct txowatch *watch_txo(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
struct channel *channel UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
enum watch_result (*cb)(struct channel * UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED,
size_t input_num UNNEEDED,
const struct block *block))
{ fprintf(stderr, "watch_txo called!\n"); abort(); }
/* Generated stub for wrap_onionreply */
struct onionreply *wrap_onionreply(const tal_t *ctx UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const struct onionreply *reply UNNEEDED)
{ fprintf(stderr, "wrap_onionreply called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
#if DEVELOPER
bool dev_disconnect_permanent(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "dev_disconnect_permanent called!\n"); abort(); }
#endif
/* Fake stubs to talk to hsm */
u8 *towire_hsmd_get_channel_basepoints(const tal_t *ctx UNNEEDED, const struct node_id *peerid UNNEEDED, u64 dbid UNNEEDED)
{
return NULL;
}
bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED)
{
return true;
}
u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
{
return NULL;
}
void plugin_hook_db_sync(struct db *db UNNEEDED)
{
}
bool fromwire_hsmd_get_channel_basepoints_reply(const void *p UNNEEDED,
struct basepoints *basepoints,
struct pubkey *funding_pubkey)
{
struct pubkey pk;
pubkey_from_der(tal_hexdata(tmpctx,
"02a1633cafcc01ebfb6d78e39f687a1f0995c62fc9"
"5f51ead10a02ee0be551b5dc",
66),
33, &pk);
*funding_pubkey = pk;
basepoints->revocation = pk;
basepoints->payment = pk;
basepoints->htlc = pk;
basepoints->delayed_payment = pk;
return true;
}
#define transaction_wrap(db, ...) \
(db_begin_transaction(db), __VA_ARGS__, db_commit_transaction(db), wallet_err == NULL)
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const struct node_id *default_node_id UNNEEDED, const char *fmt UNNEEDED, ...)
{
return NULL;
}
struct log_book *new_log_book(struct lightningd *ld UNNEEDED, size_t max_mem UNNEEDED)
{
return NULL;
}
void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES)
{
if (taken(script))
tal_free(script);
}
/**
* mempat -- Set the memory to a pattern
*
* Used mainly to check that we don't mix fields while
* serializing/unserializing.
*/
static void mempat(void *dst, size_t len)
{
static int n = 0;
u8 *p = (u8*)dst;
for(int i=0 ; i < len; ++i)
p[i] = n % 251; /* Prime */
}
/* Destructor for the wallet which unlinks the underlying file */
static void cleanup_test_wallet(struct wallet *w, char *filename)
{
unlink(filename);
tal_free(filename);
}
static struct wallet *create_test_wallet(struct lightningd *ld, const tal_t *ctx)
{
char *dsn, *filename;
int fd = tmpdir_mkstemp(ctx, "ldb-XXXXXX", &filename);
struct wallet *w = tal(ctx, struct wallet);
static unsigned char badseed[BIP32_ENTROPY_LEN_128];
const struct ext_key *bip32_base = NULL;
CHECK_MSG(fd != -1, "Unable to generate temp filename");
close(fd);
dsn = tal_fmt(NULL, "sqlite3://%s", filename);
w->db = db_open(w, dsn);
w->db->report_changes_fn = NULL;
tal_free(dsn);
tal_add_destructor2(w, cleanup_test_wallet, filename);
list_head_init(&w->unstored_payments);
w->ld = ld;
ld->wallet = w;
w->bip32_base = tal(w, struct ext_key);
CHECK(bip32_key_from_seed(badseed, sizeof(badseed),
BIP32_VER_TEST_PRIVATE, 0,
w->bip32_base) == WALLY_OK);
CHECK_MSG(w->db, "Failed opening the db");
db_begin_transaction(w->db);
db_migrate(ld, w->db, bip32_base);
w->db->data_version = 0;
db_commit_transaction(w->db);
CHECK_MSG(!wallet_err, wallet_err);
w->max_channel_dbid = 0;
return w;
}
static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
{
struct wallet *w = create_test_wallet(ld, ctx);
struct utxo u;
struct pubkey pk;
struct node_id id;
struct wireaddr_internal addr;
struct block block;
struct channel channel;
struct utxo *one_utxo;
const struct utxo **utxos;
CHECK(w);
memset(&u, 0, sizeof(u));
u.amount = AMOUNT_SAT(1);
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
node_id_from_pubkey(&id, &pk);
db_begin_transaction(w->db);
/* Should work, it's the first time we add it */
CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo failed on first add");
CHECK_MSG(!wallet_err, wallet_err);
/* Should fail, we already have that UTXO */
CHECK_MSG(!wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo succeeded on second add");
CHECK_MSG(!wallet_err, wallet_err);
/* Attempt to save an UTXO with close_info set */
memset(&u.outpoint, 1, sizeof(u.outpoint));
u.close_info = tal(w, struct unilateral_close_info);
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = &pk;
u.close_info->option_anchor_outputs = false;
/* Arbitrarily set scriptpubkey len to 20 */
u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 20);
CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo with close_info");
/* Now select them */
utxos = tal_arr(w, const struct utxo *, 0);
while ((one_utxo = wallet_find_utxo(w, w, 100, NULL, 253,
0 /* no confirmations required */,
utxos)) != NULL) {
tal_arr_expand(&utxos, one_utxo);
}
CHECK(tal_count(utxos) == 2);
if (utxos[0]->close_info)
u = *utxos[0];
else
u = *utxos[1];
CHECK(u.close_info->channel_id == 42 &&
pubkey_eq(u.close_info->commitment_point, &pk) &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == false);
/* Attempt to reserve the utxo */
CHECK_MSG(wallet_update_output_status(w, &u.outpoint,
OUTPUT_STATE_AVAILABLE,
OUTPUT_STATE_RESERVED),
"could not reserve available output");
/* Reserving twice should fail */
CHECK_MSG(!wallet_update_output_status(w, &u.outpoint,
OUTPUT_STATE_AVAILABLE,
OUTPUT_STATE_RESERVED),
"could reserve already reserved output");
/* Un-reserving should work */
CHECK_MSG(wallet_update_output_status(w, &u.outpoint,
OUTPUT_STATE_RESERVED,
OUTPUT_STATE_AVAILABLE),
"could not unreserve reserved output");
/* Switching from any to something else */
CHECK_MSG(wallet_update_output_status(w, &u.outpoint,
OUTPUT_STATE_ANY,
OUTPUT_STATE_SPENT),
"could not change output state ignoring oldstate");
/* Attempt to save an UTXO with close_info set, no commitment_point */
memset(&u.outpoint, 2, sizeof(u.outpoint));
u.amount = AMOUNT_SAT(5);
u.close_info = tal(w, struct unilateral_close_info);
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = NULL;
u.close_info->option_anchor_outputs = true;
/* The blockheight has to be set for an option_anchor_output
* closed UTXO to be spendable */
u32 *blockheight = tal(w, u32);
*blockheight = 100;
/* We gotta add a block to the database though */
memset(&block, 0, sizeof(block));
block.height = 100;
memset(&block.blkid, 2, sizeof(block.blkid));
wallet_block_add(w, &block);
CHECK_MSG(!wallet_err, wallet_err);
u.blockheight = blockheight;
u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 20);
CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh),
"wallet_add_utxo with close_info no commitment_point");
CHECK_MSG(!wallet_err, wallet_err);
/* Add another utxo that's CSV-locked for 5 blocks */
parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false,
NULL);
channel.peer = new_peer(ld, 0, &id, &addr, false);
channel.dbid = 1;
channel.type = channel_type_anchor_outputs(tmpctx);
memset(&u.outpoint, 3, sizeof(u.outpoint));
CHECK_MSG(wallet_add_onchaind_utxo(w, &u.outpoint,
u.scriptPubkey,
*u.blockheight,
AMOUNT_SAT(3),
&channel,
NULL,
5),
"wallet_add_utxo with close_info and csv > 1");
CHECK_MSG(!wallet_err, wallet_err);
/* Normally freed by destroy_channel, but we don't call that */
tal_free(channel.peer);
/* Select everything but 5 csv-locked utxo */
utxos = tal_arr(w, const struct utxo *, 0);
while ((one_utxo = wallet_find_utxo(w, w, 100, NULL, 253,
0 /* no confirmations required */,
utxos)) != NULL) {
tal_arr_expand(&utxos, one_utxo);
}
CHECK(tal_count(utxos) == 2);
if (utxos[0]->close_info)
u = *utxos[0];
else
u = *utxos[1];
CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == true &&
u.close_info->csv == 1);
/* Now un-reserve them */
tal_free(utxos);
/* Select all utxos (5 csv-locked included) */
utxos = tal_arr(w, const struct utxo *, 0);
while ((one_utxo = wallet_find_utxo(w, w, 104, NULL, 253,
0 /* no confirmations required */,
utxos)) != NULL) {
tal_arr_expand(&utxos, one_utxo);
}
CHECK(tal_count(utxos) == 3);
for (size_t i = 0; i < tal_count(utxos); i++) {
if (!utxos[i]->close_info)
continue;
CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == true &&
u.close_info->csv > 0);
}
/* Now un-reserve them */
tal_free(utxos);
db_commit_transaction(w->db);
return true;
}
static bool test_shachain_crud(struct lightningd *ld, const tal_t *ctx)
{
struct wallet_shachain a, b;
struct wallet *w = create_test_wallet(ld, ctx);
struct sha256 seed, hash;
struct secret secret;
uint64_t index = UINT64_MAX >> (64 - SHACHAIN_BITS);
memset(&seed, 'A', sizeof(seed));
memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));
db_begin_transaction(w->db);
CHECK_MSG(!wallet_err, "db_begin_transaction failed");
wallet_shachain_init(w, &a);
CHECK(!wallet_err);
CHECK(a.id == 1);
CHECK(a.chain.num_valid == 0);
CHECK(shachain_next_index(&a.chain) == index);
for (int i=0; i<100; i++) {
shachain_from_seed(&seed, index, &hash);
memcpy(&secret, &hash, sizeof(secret));
CHECK(wallet_shachain_add_hash(w, &a, index, &secret));
index--;
}
CHECK(wallet_shachain_load(w, a.id, &b));
CHECK_MSG(memcmp(&a, &b, sizeof(a)) == 0, "Loading from database doesn't match");
db_commit_transaction(w->db);
CHECK(!wallet_err);
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_count(lin1), lin2, tal_count(lin2));
tal_free(lin1);
return eq;
}
static bool channel_inflightseq(struct channel_inflight *i1,
struct channel_inflight *i2)
{
CHECK(memeq(&i1->funding->outpoint.txid,
sizeof(struct sha256_double),
&i2->funding->outpoint.txid,
sizeof(struct sha256_double)));
CHECK(i1->funding->outpoint.n == i2->funding->outpoint.n);
CHECK(i1->funding->feerate == i2->funding->feerate);
CHECK(amount_sat_eq(i1->funding->total_funds,
i2->funding->total_funds));
CHECK(amount_sat_eq(i1->funding->our_funds, i2->funding->our_funds));
CHECK(memeq(&i1->last_sig, sizeof(i1->last_sig),
&i2->last_sig, sizeof(i2->last_sig)));
CHECK(bitcoin_tx_eq(i1->last_tx, i2->last_tx));
CHECK(!i1->lease_commit_sig == !i2->lease_commit_sig);
if (i1->lease_commit_sig)
CHECK(memeq(i1->lease_commit_sig, sizeof(*i1->lease_commit_sig),
i2->lease_commit_sig, sizeof(*i2->lease_commit_sig)));
CHECK(i1->lease_expiry == i2->lease_expiry);
CHECK(i1->lease_chan_max_msat == i2->lease_chan_max_msat);
CHECK(i1->lease_chan_max_ppt == i2->lease_chan_max_ppt);
CHECK(i1->lease_blockheight_start == i2->lease_blockheight_start);
return true;
}
static bool channelseq(struct channel *c1, struct channel *c2)
{
struct peer *p1 = c1->peer, *p2 = c2->peer;
struct channel_info *ci1 = &c1->channel_info, *ci2 = &c2->channel_info;
struct changed_htlc *lc1 = c1->last_sent_commit, *lc2 = c2->last_sent_commit;
struct channel_inflight *i1, *i2;
CHECK(c1->dbid == c2->dbid);
CHECK(c1->first_blocknum == c2->first_blocknum);
CHECK(c1->peer->dbid == c2->peer->dbid);
CHECK(c1->peer == c2->peer);
CHECK(c1->their_shachain.id == c2->their_shachain.id);
CHECK_MSG(node_id_eq(&p1->id, &p2->id), "NodeIDs do not match");
CHECK((c1->scid == NULL && c2->scid == NULL)
|| short_channel_id_eq(c1->scid, c2->scid));
CHECK(amount_msat_eq(c1->our_msat, c2->our_msat));
CHECK((c1->shutdown_scriptpubkey[REMOTE] == NULL && c2->shutdown_scriptpubkey[REMOTE] == NULL) || memeq(
c1->shutdown_scriptpubkey[REMOTE],
tal_count(c1->shutdown_scriptpubkey[REMOTE]),
c2->shutdown_scriptpubkey[REMOTE],
tal_count(c2->shutdown_scriptpubkey[REMOTE])));
CHECK(bitcoin_outpoint_eq(&c1->funding, &c2->funding));
CHECK(pubkey_eq(&ci1->remote_fundingkey, &ci2->remote_fundingkey));
CHECK(pubkey_eq(&ci1->theirbase.revocation, &ci2->theirbase.revocation));
CHECK(pubkey_eq(&ci1->theirbase.payment, &ci2->theirbase.payment));
CHECK(pubkey_eq(&ci1->theirbase.delayed_payment, &ci2->theirbase.delayed_payment));
CHECK(pubkey_eq(&ci1->remote_per_commit, &ci2->remote_per_commit));
CHECK(pubkey_eq(&ci1->old_remote_per_commit, &ci2->old_remote_per_commit));
CHECK(ci1->their_config.id != 0 && ci1->their_config.id == ci2->their_config.id);
CHECK(fee_states_valid(c1->fee_states, c1->opener));
CHECK(fee_states_valid(c2->fee_states, c2->opener));
for (enum htlc_state i = 0; i < ARRAY_SIZE(c1->fee_states->feerate);
i++) {
if (c1->fee_states->feerate[i] == NULL) {
CHECK(c2->fee_states->feerate[i] == NULL);
} else {
CHECK(*c1->fee_states->feerate[i]
== *c2->fee_states->feerate[i]);
}
}
CHECK(c1->our_config.id != 0 && c1->our_config.id == c2->our_config.id);
CHECK((lc1 != NULL) == (lc2 != NULL));
CHECK(tal_count(lc1) == tal_count(lc2));
for (size_t i = 0; i < tal_count(lc1); i++) {
CHECK(lc1[i].newstate == lc2[i].newstate);
CHECK(lc1[i].id == lc2[i].id);
}
CHECK((c1->last_tx != NULL) == (c2->last_tx != NULL));
if (c1->last_tx) {
CHECK(bitcoin_tx_eq(c1->last_tx, c2->last_tx));
}
CHECK(memeq(&c1->last_sig, sizeof(c1->last_sig),
&c2->last_sig, sizeof(c2->last_sig)));
CHECK(c1->final_key_idx == c2->final_key_idx);
CHECK(memeq(c1->shutdown_scriptpubkey[REMOTE],
tal_count(c1->shutdown_scriptpubkey[REMOTE]),
c2->shutdown_scriptpubkey[REMOTE],
tal_count(c2->shutdown_scriptpubkey[REMOTE])));
CHECK(c1->last_was_revoke == c2->last_was_revoke);
CHECK(!c1->lease_commit_sig == !c2->lease_commit_sig);
if (c1->lease_commit_sig)
CHECK(memeq(c1->lease_commit_sig, sizeof(*c1->lease_commit_sig),
c2->lease_commit_sig, sizeof(*c2->lease_commit_sig)));
CHECK(c1->lease_chan_max_msat == c2->lease_chan_max_msat);
CHECK(c1->lease_chan_max_ppt == c2->lease_chan_max_ppt);
CHECK(c1->lease_expiry == c2->lease_expiry);
CHECK(height_states_valid(c1->blockheight_states, c1->opener));
CHECK(height_states_valid(c2->blockheight_states, c2->opener));
for (enum htlc_state i = 0; i < ARRAY_SIZE(c1->blockheight_states->height);
i++) {
if (c1->blockheight_states->height[i] == NULL) {
CHECK(c2->blockheight_states->height[i] == NULL);
} else {
CHECK(*c1->blockheight_states->height[i]
== *c2->blockheight_states->height[i]);
}
}
i1 = list_top(&c1->inflights, struct channel_inflight, list);
i2 = list_top(&c2->inflights, struct channel_inflight, list);
CHECK((i1 != NULL) == (i2 != NULL));
if (!i1 && !i2)
return true;
while ((i1 = list_next(&c1->inflights, i1, list))) {
i2 = list_next(&c2->inflights, i2, list);
CHECK(i2 != NULL);
CHECK(channel_inflightseq(i1, i2));
}
/* c2 should also be out of inflights */
CHECK(list_next(&c2->inflights, i2, list) == NULL);
CHECK(channel_type_eq(c1->type, c2->type));
return true;
}
static struct channel *wallet_channel_load(struct wallet *w, const u64 dbid)
{
struct peer *peer;
struct channel *channel;
/* We expect only one peer, but reuse same code */
if (!wallet_init_channels(w))
return NULL;
peer = list_top(&w->ld->peers, struct peer, list);
CHECK(peer);
/* We load lots of identical dbid channels: use last one */
channel = list_tail(&peer->channels, struct channel, list);
assert(channel->dbid == dbid);
return channel;
}
static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx)
{
struct wallet *w = create_test_wallet(ld, ctx);
struct channel c1, *c2 = tal(w, struct channel);
struct wireaddr_internal addr;
struct peer *p;
struct channel_info *ci = &c1.channel_info;
struct bitcoin_txid *hash = tal(w, struct bitcoin_txid);
struct pubkey pk;
struct node_id id;
struct changed_htlc *last_commit;
secp256k1_ecdsa_signature *sig = tal(w, secp256k1_ecdsa_signature);
u8 *scriptpubkey = tal_arr(ctx, u8, 100);
secp256k1_ecdsa_signature *node_sig1 = tal(w, secp256k1_ecdsa_signature);
secp256k1_ecdsa_signature *bitcoin_sig1 = tal(w, secp256k1_ecdsa_signature);
secp256k1_ecdsa_signature *node_sig2, *bitcoin_sig2;
u32 feerate, blockheight;
bool load;
const struct channel_type *type = channel_type_static_remotekey(w);
memset(&c1, 0, sizeof(c1));
memset(c2, 0, sizeof(*c2));
memset(ci, 3, sizeof(*ci));
mempat(hash, sizeof(*hash));
mempat(sig, sizeof(*sig));
mempat(node_sig1, sizeof(*node_sig1));
mempat(bitcoin_sig1, sizeof(*bitcoin_sig1));
last_commit = tal_arr(w, struct changed_htlc, 2);
mempat(last_commit, tal_bytelen(last_commit));
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
node_id_from_pubkey(&id, &pk);
feerate = 31337;
c1.fee_states = new_fee_states(w, c1.opener, &feerate);
blockheight = 10010;
c1.blockheight_states = new_height_states(w, c1.opener, &blockheight);
mempat(scriptpubkey, tal_count(scriptpubkey));
c1.first_blocknum = 1;
parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false,
NULL);
c1.final_key_idx = 1337;
p = new_peer(ld, 0, &id, &addr, false);
c1.peer = p;
c1.dbid = wallet_get_channel_dbid(w);
c1.state = CHANNELD_NORMAL;
memset(&ci->their_config, 0, sizeof(struct channel_config));
ci->remote_fundingkey = pk;
ci->theirbase.revocation = pk;
ci->theirbase.payment = pk;
ci->theirbase.htlc = pk;
ci->theirbase.delayed_payment = pk;
c1.local_basepoints.revocation = pk;
c1.local_basepoints.payment = pk;
c1.local_basepoints.htlc = pk;
c1.local_basepoints.delayed_payment = pk;
c1.local_funding_pubkey = pk;
ci->remote_per_commit = pk;
ci->old_remote_per_commit = pk;
/* last_tx taken from BOLT #3 */
c1.last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"));
c1.last_sig.s = *sig;
c1.last_sig.sighash_type = SIGHASH_ALL;
c1.last_tx->chainparams = chainparams_for_network("bitcoin");
c1.unsaved_dbid = 0;
/* Init channel inflights */
list_head_init(&c1.inflights);
c1.type = type;
db_begin_transaction(w->db);
CHECK(!wallet_err);
wallet_channel_insert(w, &c1);
/* Variant 1: insert with null for scid, last_sent_commit */
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Load from DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v1)");
tal_free(c2);
/* We just inserted them into an empty DB so this must be 1 */
CHECK(c1.dbid == 1);
CHECK(c1.peer->dbid == 1);
CHECK(c1.their_shachain.id == 1);
/* Variant 2: update with scid set */
c1.scid = talz(w, struct short_channel_id);
c1.last_was_revoke = !c1.last_was_revoke;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Load from DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v2)");
tal_free(c2);
/* Updates should not result in new ids */
CHECK(c1.dbid == 1);
CHECK(c1.peer->dbid == 1);
CHECK(c1.their_shachain.id == 1);
/* Variant 3: update with last_commit_sent */
c1.last_sent_commit = last_commit;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Load from DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v3)");
tal_free(c2);
/* Updates should not result in new ids */
CHECK(c1.dbid == 1);
CHECK(c1.peer->dbid == 1);
CHECK(c1.their_shachain.id == 1);
/* Variant 4: update and add shutdown_scriptpubkey[REMOTE] */
c1.shutdown_scriptpubkey[REMOTE] = scriptpubkey;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err, tal_fmt(w, "Insert into DB: %s", wallet_err));
CHECK_MSG(c2 = wallet_channel_load(w, c1.dbid), tal_fmt(w, "Load from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Load from DB: %s", wallet_err));
CHECK_MSG(channelseq(&c1, c2), "Compare loaded with saved (v4)");
tal_free(c2);
/* Updates should not result in new ids */
CHECK(c1.dbid == 1);
CHECK(c1.peer->dbid == 1);
CHECK(c1.their_shachain.id == 1);
/* Variant 5: update with remote_ann sigs */
/* set flag of CHANNEL_FLAGS_ANNOUNCE_CHANNEL */
c1.channel_flags |= 1;
wallet_channel_save(w, &c1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert into DB: %s", wallet_err));
wallet_announcement_save(w, c1.dbid, node_sig1, bitcoin_sig1);
CHECK_MSG(!wallet_err,
tal_fmt(w, "Insert ann sigs into DB: %s", wallet_err));
CHECK_MSG(load = wallet_remote_ann_sigs_load(w, w, c1.dbid, &node_sig2, &bitcoin_sig2), tal_fmt(w, "Load ann sigs from DB"));
CHECK_MSG(!wallet_err,
tal_fmt(w, "Load ann sigs from DB: %s", wallet_err));
CHECK(load == true);
CHECK_MSG(!memcmp(node_sig1, node_sig2, sizeof(*node_sig1)), "Compare ann sigs loaded with saved (v5)");
CHECK_MSG(!memcmp(bitcoin_sig1, bitcoin_sig2, sizeof(*node_sig1)), "Compare ann sigs loaded with saved (v5)");
db_commit_transaction(w->db);
CHECK(!wallet_err);
/* Normally freed by destroy_channel, but we don't call that */
tal_free(p);
return true;
}
static int count_inflights(struct wallet *w, u64 channel_dbid)
{
struct db_stmt *stmt;
int count;
stmt = db_prepare_v2(w->db, SQL("SELECT COUNT(1)"
" FROM channel_funding_inflights"
" WHERE channel_id = ?;"));
db_bind_u64(stmt, 0, channel_dbid);
db_query_prepared(stmt);
if (!db_step(stmt))
abort();
count = db_col_int(stmt, "COUNT(1)");
tal_free(stmt);
return count;
}
static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx)
{
struct wallet *w = create_test_wallet(ld, ctx);
struct channel *chan, *c2;
struct channel_inflight *inflight;
struct bitcoin_outpoint outpoint;
struct bitcoin_signature sig;
struct amount_sat funding_sats, our_sats;
struct node_id id;
struct pubkey pk;
struct wireaddr_internal addr;
struct peer *p;
struct channel_config our_config;
struct channel_id cid;
struct bitcoin_tx *last_tx;
struct wally_psbt *funding_psbt;
struct channel_info *channel_info = tal(w, struct channel_info);
struct basepoints basepoints;
secp256k1_ecdsa_signature *lease_commit_sig;
u32 feerate, lease_blockheight_start;
u64 dbid;
pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk);
node_id_from_pubkey(&id, &pk);
parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false,
NULL);
/* new channel! */
p = new_peer(ld, 0, &id, &addr, false);
funding_sats = AMOUNT_SAT(4444444);
our_sats = AMOUNT_SAT(3333333);
mempat(&sig.s, sizeof(sig.s));
mempat(&cid, sizeof(struct channel_id));
lease_commit_sig = tal(w, secp256k1_ecdsa_signature);
mempat(lease_commit_sig, sizeof(*lease_commit_sig));
sig.sighash_type = SIGHASH_ALL;
/* last_tx taken from BOLT #3 */
last_tx = bitcoin_tx_from_hex(w, "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", strlen("02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8003a00f0000000000002200208c48d15160397c9731df9bc3b236656efb6665fbfe92b4a6878e88a499f741c4c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de843110ae8f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e040047304402206a2679efa3c7aaffd2a447fd0df7aba8792858b589750f6a1203f9259173198a022008d52a0e77a99ab533c36206cb15ad7aeb2aa72b93d4b571e728cb5ec2f6fe260147304402206d6cb93969d39177a09d5d45b583f34966195b77c7e585cf47ac5cce0c90cefb022031d71ae4e33a4e80df7f981d696fbdee517337806a3c7138b7491e2cbb077a0e01475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220"));
funding_psbt = psbt_from_b64(w, "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA", strlen("cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA"));
feerate = 192838;
lease_blockheight_start = 101010;
memset(&our_config, 1, sizeof(struct channel_config));
our_config.id = 0;
memset(&outpoint, 1, sizeof(outpoint));
basepoints.revocation = pk;
basepoints.payment = pk;
basepoints.htlc = pk;
basepoints.delayed_payment = pk;
memset(channel_info, 3, sizeof(*channel_info));
channel_info->their_config.id = 0;
channel_info->remote_fundingkey = pk;
channel_info->theirbase = basepoints;
channel_info->remote_per_commit = pk;
channel_info->old_remote_per_commit = pk;
chan = new_channel(p, wallet_get_channel_dbid(w),
NULL,
DUALOPEND_AWAITING_LOCKIN,
LOCAL, NULL, "billboard",
8, &our_config,
101, 1, 1, 1,
&outpoint,
funding_sats, AMOUNT_MSAT(0),
our_sats,
0, false,
NULL, /* alias[LOCAL] */
NULL, /* alias[REMOTE] */
&cid,
AMOUNT_MSAT(3333333000),
AMOUNT_MSAT(33333),
AMOUNT_MSAT(3333333333),
last_tx, &sig,
NULL,
channel_info,
new_fee_states(w, LOCAL, &feerate),
NULL, NULL,
1, false,
NULL,
100, /* first_blocknum */
100, /* min_possible_feerate */
10000, /* max_possible_feerate */
&basepoints,
&pk, NULL,
1000, 100,
NULL, 0, 0, channel_type_static_remotekey(NULL),
LOCAL, REASON_UNKNOWN,
NULL,
new_height_states(w, LOCAL,
&lease_blockheight_start),
100,
lease_commit_sig,
7777, 22,
AMOUNT_MSAT(0),
AMOUNT_MSAT(-1ULL));
db_begin_transaction(w->db);
CHECK(!wallet_err);
wallet_channel_insert(w, chan);
/* info for the inflight */
funding_sats = AMOUNT_SAT(222222);
our_sats = AMOUNT_SAT(111111);
memset(&outpoint, 1, sizeof(outpoint));
mempat(&sig.s, sizeof(sig.s));
inflight = new_inflight(chan, &outpoint, 253,
funding_sats,
our_sats,
funding_psbt,
last_tx,
sig,
1, lease_commit_sig, 2, 4, 22,
AMOUNT_MSAT(10));
/* do inflights get correctly added to the channel? */
wallet_inflight_add(w, inflight);
/* do inflights get correctly loaded from the database? */
CHECK_MSG(c2 = wallet_channel_load(w, chan->dbid),
tal_fmt(w, "Load from DB"));
CHECK_MSG(channelseq(chan, c2), "Compare loaded with saved (v2)");
tal_free(c2);
/* add another inflight, confirm existence */
funding_sats = AMOUNT_SAT(666666);
our_sats = AMOUNT_SAT(555555);
memset(&outpoint, 2, sizeof(outpoint));
mempat(&sig.s, sizeof(sig.s));
inflight = new_inflight(chan, &outpoint, 300,
funding_sats,
our_sats,
funding_psbt,
last_tx,
sig,
0, NULL, 0, 0, 0,
AMOUNT_MSAT(0));
wallet_inflight_add(w, inflight);
CHECK_MSG(c2 = wallet_channel_load(w, chan->dbid),
tal_fmt(w, "Load from DB"));
CHECK_MSG(channelseq(chan, c2), "Compare loaded with saved (v2)");
CHECK_MSG(count_inflights(w, chan->dbid) == 2, "inflights exist");
tal_free(c2);
/* Update the PSBT for both inflights, check that are updated
* correctly on save */
funding_psbt = psbt_from_b64(w, "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA=", strlen("cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA="));
list_for_each(&chan->inflights, inflight, list)
inflight->funding_psbt = funding_psbt;
wallet_channel_save(w, chan);
CHECK_MSG(c2 = wallet_channel_load(w, chan->dbid),
tal_fmt(w, "Load from DB"));
CHECK_MSG(channelseq(chan, c2), "Compare loaded with saved (v2)");
tal_free(c2);
/* do inflights get cleared when the channel is closed?*/
dbid = chan->dbid;
delete_channel(chan); /* Also clears up peer! */
CHECK_MSG(count_inflights(w, dbid) == 0, "inflights cleaned up");
db_commit_transaction(w->db);
CHECK_MSG(!wallet_err, wallet_err);
return true;
}
static bool test_channel_config_crud(struct lightningd *ld, const tal_t *ctx)
{
struct channel_config *cc1 = talz(ctx, struct channel_config),
*cc2 = talz(ctx, struct channel_config);
struct wallet *w = create_test_wallet(ld, ctx);
CHECK(w);
cc1->dust_limit.satoshis = 1;
cc1->max_htlc_value_in_flight.millisatoshis = 2;
cc1->channel_reserve.satoshis = 3;
cc1->htlc_minimum.millisatoshis = 4;
cc1->to_self_delay = 5;
cc1->max_accepted_htlcs = 6;
CHECK(transaction_wrap(w->db, wallet_channel_config_insert(w, cc1)));
CHECK_MSG(
cc1->id == 1,
tal_fmt(ctx, "channel_config->id != 1; got %" PRIu64, cc1->id));
CHECK(transaction_wrap(w->db, wallet_channel_config_save(w, cc1)));
CHECK(transaction_wrap(w->db, wallet_channel_config_load(w, cc1->id, cc2)));
CHECK(memeq(cc1, sizeof(*cc1), cc2, sizeof(*cc2)));
return true;
}
static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
{
struct db_stmt *stmt;
struct htlc_in in, *hin;
struct htlc_out out, *hout;
struct preimage payment_key;
struct channel *chan = tal(ctx, struct channel);
struct peer *peer = talz(ctx, struct peer);
struct wallet *w = create_test_wallet(ld, ctx);
struct htlc_in_map *htlcs_in = tal(ctx, struct htlc_in_map), *rem;
struct htlc_out_map *htlcs_out = tal(ctx, struct htlc_out_map);
struct onionreply *onionreply;
/* Make sure we have our references correct */
db_begin_transaction(w->db);
char *query = SQL("INSERT INTO channels (id) VALUES (1);");
stmt = db_prepare_v2(w->db, query);
db_exec_prepared_v2(stmt);
tal_free(stmt);
db_commit_transaction(w->db);
chan->dbid = 1;
chan->peer = peer;
chan->next_index[LOCAL] = chan->next_index[REMOTE] = 1;
memset(&in, 0, sizeof(in));
memset(&out, 0, sizeof(out));
memset(&in.payment_hash, 'A', sizeof(struct sha256));
memset(&out.payment_hash, 'A', sizeof(struct sha256));
memset(&payment_key, 'B', sizeof(payment_key));
in.key.id = 42;
in.key.channel = chan;
in.msat = AMOUNT_MSAT(42);
out.in = &in;
out.key.id = 1337;
out.key.channel = chan;
out.msat = AMOUNT_MSAT(41);
/* Store the htlc_in */
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_in(w, chan, &in)),
tal_fmt(ctx, "Save htlc_in failed: %s", wallet_err));
CHECK_MSG(in.dbid != 0, "HTLC DB ID was not set.");
/* Saving again should get us a collision */
CHECK_MSG(!transaction_wrap(w->db, wallet_htlc_save_in(w, chan, &in)),
"Saving two HTLCs with the same data must not succeed.");
CHECK(wallet_err);
wallet_err = tal_free(wallet_err);
/* Update */
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, RCVD_ADD_HTLC, NULL, 0, 0, NULL, NULL, false)),
"Update HTLC with null payment_key failed");
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, &payment_key, 0, 0, NULL, NULL, false)),
"Update HTLC with payment_key failed");
onionreply = new_onionreply(tmpctx, tal_arrz(tmpctx, u8, 100));
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, 0, onionreply, NULL, false)),
"Update HTLC with failonion failed");
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, in.dbid, SENT_REMOVE_HTLC, NULL, 0, WIRE_INVALID_ONION_VERSION, NULL, NULL, false)),
"Update HTLC with failcode failed");
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)),
tal_fmt(ctx, "Save htlc_out failed: %s", wallet_err));
CHECK_MSG(out.dbid != 0, "HTLC DB ID was not set.");
CHECK_MSG(!transaction_wrap(w->db, wallet_htlc_save_out(w, chan, &out)),
"Saving two HTLCs with the same data must not succeed.");
CHECK(wallet_err);
wallet_err = tal_free(wallet_err);
CHECK_MSG(
transaction_wrap(w->db, wallet_htlc_update(w, out.dbid, SENT_ADD_ACK_REVOCATION, NULL, 0, 0, NULL, tal_arrz(tmpctx, u8, 100), false)),
"Update outgoing HTLC with failmsg failed");
/* Attempt to load them from the DB again */
htlc_in_map_init(htlcs_in);
htlc_out_map_init(htlcs_out);
db_begin_transaction(w->db);
CHECK(!wallet_err);
CHECK_MSG(wallet_htlcs_load_in_for_channel(w, chan, htlcs_in),
"Failed loading in HTLCs");
/* Freed by htlcs_resubmit */
rem = tal(NULL, struct htlc_in_map);
htlc_in_map_copy(rem, htlcs_in);
CHECK_MSG(wallet_htlcs_load_out_for_channel(w, chan, htlcs_out, rem),
"Failed loading out HTLCs");
db_commit_transaction(w->db);
htlcs_resubmit(w->ld, rem);
CHECK(!wallet_err);
hin = htlc_in_map_get(htlcs_in, &in.key);
hout = htlc_out_map_get(htlcs_out, &out.key);
CHECK(hin != NULL);
CHECK(hout != NULL);
/* Have to free manually, otherwise we get our dependencies
* twisted */
tal_free(hin);
tal_free(hout);
htlc_in_map_clear(htlcs_in);
htlc_out_map_clear(htlcs_out);
return true;
}
static bool test_payment_crud(struct lightningd *ld, const tal_t *ctx)
{
struct wallet_payment *t = tal(ctx, struct wallet_payment), *t2;
struct wallet *w = create_test_wallet(ld, ctx);
mempat(t, sizeof(*t));
t->destination = tal(t, struct node_id);
memset(t->destination, 2, sizeof(struct node_id));
t->id = 0;
t->msatoshi = AMOUNT_MSAT(100);
t->msatoshi_sent = AMOUNT_MSAT(101);
t->total_msat = t->msatoshi;
t->status = PAYMENT_PENDING;
t->payment_preimage = NULL;
memset(&t->payment_hash, 1, sizeof(t->payment_hash));
t->partid = 0;
t->groupid = 12345;
db_begin_transaction(w->db);
t2 = tal_dup(NULL, struct wallet_payment, t);
wallet_payment_setup(w, t2);
wallet_payment_store(w, take(t2));
t2 = wallet_payment_by_hash(ctx, w, &t->payment_hash, 0, t->groupid);
CHECK(t2 != NULL);
CHECK(t2->status == t->status);
CHECK(sha256_eq(&t2->payment_hash, &t->payment_hash));
CHECK(t2->partid == t->partid);
CHECK(node_id_cmp(t2->destination, t->destination) == 0);
CHECK(amount_msat_eq(t2->msatoshi, t->msatoshi));
CHECK(amount_msat_eq(t2->msatoshi_sent, t->msatoshi_sent));
CHECK(amount_msat_eq(t2->total_msat, t->total_msat));
CHECK(!t2->payment_preimage);
t->status = PAYMENT_COMPLETE;
t->payment_preimage = tal(w, struct preimage);
memset(t->payment_preimage, 2, sizeof(*t->payment_preimage));
wallet_payment_set_status(w, &t->payment_hash, t->partid, t->groupid,
t->status, t->payment_preimage);
t2 = wallet_payment_by_hash(ctx, w, &t->payment_hash, t->partid, t->groupid);
CHECK(t2 != NULL);
CHECK(t2->status == t->status);
CHECK(sha256_eq(&t2->payment_hash, &t->payment_hash));
CHECK(t2->partid == t->partid);
CHECK(node_id_eq(t2->destination, t->destination));
CHECK(amount_msat_eq(t2->msatoshi, t->msatoshi));
CHECK(amount_msat_eq(t2->msatoshi_sent, t->msatoshi_sent));
CHECK(preimage_eq(t->payment_preimage, t2->payment_preimage));
db_commit_transaction(w->db);
return true;
}
static bool test_wallet_payment_status_enum(void)
{
CHECK(PAYMENT_PENDING == 0);
CHECK(PAYMENT_COMPLETE == 1);
CHECK(PAYMENT_FAILED == 2);
return true;
}
int main(int argc, const char *argv[])
{
common_setup(argv[0]);
chainparams = chainparams_for_network("bitcoin");
bool ok = true;
struct lightningd *ld;
ld = tal(tmpctx, struct lightningd);
ld->config = test_config;
/* Only elements in ld we should access */
list_head_init(&ld->peers);
ld->rr_counter = 0;
node_id_from_hexstr("02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66, &ld->id);
/* Accessed in peer destructor sanity check */
htlc_in_map_init(&ld->htlcs_in);
htlc_out_map_init(&ld->htlcs_out);
/* We do a runtime test here, so we still check compile! */
if (HAVE_SQLITE3) {
ok &= test_shachain_crud(ld, tmpctx);
ok &= test_channel_crud(ld, tmpctx);
ok &= test_channel_inflight_crud(ld, tmpctx);
ok &= test_channel_config_crud(ld, tmpctx);
ok &= test_channel_inflight_crud(ld, tmpctx);
ok &= test_wallet_outputs(ld, tmpctx);
ok &= test_htlc_crud(ld, tmpctx);
ok &= test_payment_crud(ld, tmpctx);
ok &= test_wallet_payment_status_enum();
}
/* Do not clean up in the case of an error, we might want to debug the
* database. */
if (ok) {
common_shutdown();
}
return !ok;
}