#include "config.h" #include #include "test_utils.h" #include #include 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 #include #include bool deprecated_apis = true; /* 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 *bitcoind UNNEEDED, const struct bitcoin_tx_output *txout UNNEEDED, void *arg) 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, void (*failed)(struct channel *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, errcode_t 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_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 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_active */ bool fromwire_connectd_peer_active(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u16 **msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "fromwire_connectd_peer_active 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, 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) { fprintf(stderr, "fromwire_connectd_peer_disconnect_done 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_only */ void json_add_amount_sat_only(struct json_stream *result UNNEEDED, const char *msatfieldname UNNEEDED, struct amount_sat sat) { fprintf(stderr, "json_add_amount_sat_only 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_null */ void json_add_null(struct json_stream *stream UNNEEDED, const char *fieldname UNNEEDED) { fprintf(stderr, "json_add_null 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 *result UNNEEDED, const char *fieldname UNNEEDED, const char *value 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 maybe_disconnect_peer */ void maybe_disconnect_peer(struct lightningd *ld UNNEEDED, struct peer *peer UNNEEDED) { fprintf(stderr, "maybe_disconnect_peer 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 param_string */ struct command_result *param_string(struct command *cmd UNNEEDED, const char *name UNNEEDED, const char * buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char **str UNNEEDED) { fprintf(stderr, "param_string 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 */ void 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 */ void 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, 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 */ void resolve_close_command(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_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 *topo UNNEEDED, void *arg) 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_peer_final_msg */ u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); } /* Generated stub for towire_connectd_peer_make_active */ u8 *towire_connectd_peer_make_active(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_connectd_peer_make_active 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_remote_addr */ u8 *towire_gossipd_remote_addr(const tal_t *ctx UNNEEDED, const struct wireaddr *remote_addr UNNEEDED) { fprintf(stderr, "towire_gossipd_remote_addr 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_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, u32 seconds_delay 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 *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 *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, true, 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, true, 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, true, 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, &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 */ false, &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 = ∈ 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; }