From dccbccf8f2b33fede8c2079a20f393be3455396e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 25 Jul 2023 12:44:35 +0930 Subject: [PATCH] lightningd: migrate (and delete) old commando runes. If they have invalid runes, we bail, but if they have runes which used a different master secret (old commando.py allowed you to override secret), we just complain and delete them. Note that this requires more mocks in wallet/test/run-db.c... Signed-off-by: Rusty Russell --- lightningd/channel.h | 6 +- tests/data/commando_listrunes.sqlite3.xz | Bin 0 -> 4352 bytes tests/test_runes.py | 28 ++++ wallet/db.c | 1 + wallet/db.h | 2 + wallet/test/run-db.c | 185 +++++++++++++++++++++++ wallet/test/run-wallet.c | 3 + wallet/wallet.c | 36 +++++ 8 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 tests/data/commando_listrunes.sqlite3.xz diff --git a/lightningd/channel.h b/lightningd/channel.h index 4f2ada33d..a34de93e0 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -352,8 +352,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, bool ignore_fee_limits); /* new_inflight - Create a new channel_inflight for a channel */ -struct channel_inflight * -new_inflight(struct channel *channel, +struct channel_inflight *new_inflight(struct channel *channel, const struct bitcoin_outpoint *funding_outpoint, u32 funding_feerate, struct amount_sat funding_sat, @@ -517,8 +516,7 @@ static inline bool channel_has(const struct channel *channel, int f) * don't have a scid yet, e.g., for `zeroconf` channels, so we resort * to referencing it by the local alias, which we have in that case. */ -const struct short_channel_id * -channel_scid_or_local_alias(const struct channel *chan); +const struct short_channel_id *channel_scid_or_local_alias(const struct channel *chan); void get_channel_basepoints(struct lightningd *ld, const struct node_id *peer_id, diff --git a/tests/data/commando_listrunes.sqlite3.xz b/tests/data/commando_listrunes.sqlite3.xz new file mode 100644 index 0000000000000000000000000000000000000000..e5f2d831d93aa6318f82081aa4d46d084c212cbd GIT binary patch literal 4352 zcmV+b5&!P}H+ooF000E$*0e?f03iV!0000G&sfak-~SN6T>vSRMV(;C8Tck-h>j-y zF_rzthkyo`yX=3c34ZX>%1gIBF|?;1-AZA*0ivb`Hjmn-82l}Bzs*bd2J^g)$8weo z(YWViB(^QDvzb`;D6P-~BA7G2Pgg)Q{WJ~j44{u?k;(Z4ZU3Xcr44>Sm_kL)Mlva? zGj~6|O~W;$5_;>gGeNHj*1MR2YPHj<@e9g+l`AjYTa{RDF4U0F+YG-IUTUXk#lkvm z*Ls)>m~t6S;AqML7=>qBM`qG>rB}bG8#Ts=2Qt(a4^3C{!OrW*p8hNOQOTrwaxZU= zV4bzy5!EXTC8dv>T#+8ExW)?HIu7V}(2c3|_HzNDq9h9TD$RWAP;UbJ=-quMFwnB-j>@_)J3;ZA2@$v|H zZWl*|$)nCX;&`MGueWH~;mjJ@te6#j5RKUq>`{Yu7o8k}EspGhfG7_I8jZ!5?}Rb2 z^ORx*87j_7BLR~6C*SiDZ#4u3#eckh7?$2(AdYu|M2rdAK?9;!nMAWG&8)pqK>Tq< zbGMcae~P9NZkL_$DPgIt@yn?S(P<4MJ4W9hsL|hSpHG<*VyN)e&JL?;tw+RZFa8!t z78pY^qN>{|CV1-+lS%I#Y_gRHKpz+!XE@@l8=qtx;i-O=;G@SrxzTyL`?pD2pU1&Z zuQOYu)Gz(d%`eB=bu9f|jr|c?%5~x|DK-!k=9gOdE1T{ce{Pp;k5ablkgECaE~qvM z)xKwt1WPx+L8t<`3g25{u?}Xf++FU4%y+p}l4IOru&r}GHvxBV2a0$Tdcbdo*)S>? zGz)@o4u*;eol(0#2eKv0o1SY8>y@u@T_}zZ>_hO0OqpG$SMsEqQSwcvHgNtqX>OTE zmv@BX2iB(?+Q4k2cDLcN-!VQOhqhwq01`Ett1=CoD_Wk1*B_iO=yTQY2 za{ch8_9BvuO}bEXZRT0LhScMsBhN-8V?-#&}6NX|>nuQ(wFGN*ypax+@{4H@BUuwe3b#Q_uRKCM3NKT1(0bF>x-wFcO>A~rEr z^+&Ui62E}b(mH>B_B)(iyrYjBIiSgr}o%IFGm7$HFdlh)%N}l4;`orR4hp+bqzQS?68ah`2jmI`*kk{ z4-426F_!Taa_b8S2(~)rYd?JOfgghi|IqJz6-w02MbO%Kcr4g3z)ItNW`9+bf@{kuGa`0oF*fO-G; zJ1Cdix4$DZeoD;!?1>>}Hf*>FDK__SKpL5!MC~T&-jK+9E2WE` zEx}vW7x-?@%24i2ikAERJhY#1jjHDdnh@}s{Da6b3YJ6`3Y1`OEO9Pz1D4CV z7nwp?|8|0qN&;tj#w|Pr?Dqn@iW+~dh|B51esgsXnXPFJFNsUCAQ(~)XeYW!r4{Zp zF>;la5#3GPr$T zLagRY)oB3%g`AoMN>!aHc1ub$8Wn&1ndX>(+X@7SX-yu;c-!>87NoH2I8OnPsZGt} zov!GZ$}1PdNaLf*uk8hmRsW*}j*_L80W=z7-jy<{eH)JXsH;b;n-YEl&GS#mG=QqW zCJ-dY8)w)555s_w_Xta?beB;`y2oUg$YO>JaoVNhreWX~o>6;D#!WCKLfJ}JQ%oKW zWpX|IRx~wKBFuJ*1+B)4xu?{42eVS}rzYUt)HB^dLMd=D#2s7;VWA6L%HDpEaIGKN zsS~H%WN@4>`@zR*u7%RwK^2*Q z)b6zlec0C&EA?WbIaLHd7432+;%q#06NcG}iyqYgBl(nb!sy?t%u+d%geZarD_Z}! zigBy$($opd%Ma;YIz#deOlDAV4=*+m*>1T{Ktd}3d0eqJ03k_FN@(8)6 zb}dd!F;7H1H%7+37s;5I;bFqiW#B7uCXMIkYjz4hC){gn_+`Ag%UWfXMhZOk^azv< z(|FG`b#d#yL35@`cCCE)0U~#x}Nd%C7k=mG7M9oJj;>$BsZ#1&3?;!od*)W1yj?7m;Oi;2$uFZY@7K|mco74o*g(=DnG3_Y~K;29B!J&B2hj%te8bUC9H zuVx*OU&YQ>SILedC$^d6Di#>o=nIh>>w|Uy(6F?snQ+ZuAm~=~=-ZR?Fzjk=xIAAW z*r6CGH?Uv$y}PP?er9wBs?6W4T` zBt)_3H!X*O>|_@v+NTrbtDvo)E{vLBLLJu6Z~*v4)oBDAg9|7Ksa3Dk8au2dq`d!C zeL}m;7tfo1%0HPC=^slKUug8FJ`|l1%H$y)#(n-fQLUeI6LFUSZV}#I?)NEx*hBue zdt@6E?{?&!fClNNHl5s-7OZ?-RFmX$D5~-mgB*8PT|&F)Yn|xTrQinedVOGPEJzh8 zczd4xc)_0^GY2-aRl9QE!K`F~_zpK|Baxp;mf6UIa(3+(|i;FV`2i!;BCB z6js2UD@CHW$EOrHs(%GrgF=m*R6vYA8GSdwDW6#q&>N3wb>Wg2+OQNv7b_=rsfOed z<3bA>XL@I0BF*$+TSmCm8~Q=q+~-1~T;vQmfTn?i#7NL4Zm%lI5u-2zB=eXz=7d&Z z+kz=pZ_y||!Npi5U5@50HDh%9#5_7{{7^7@KMfDc<_Jki0Nhq8&!>Hd$Uv$9Ea!cx z*JJYDQF>9Y@{L^`@teg=i@=D@2H}uQ`;P@vGy6^9(g{$T12AErtX~tUi>i^F*zAdw zovyTqvr>*~Iu0AXWv_gqjfkiBo!SX4%EijE)(CJts@?kRERv&JB5ENS8qDPwcsC%VAUffy zJ}uQIhZIdgto(jr+Q2wEMbXfY$QHM3rPsMRX&)&GL$9=u-I(@Ma}Zp=e*s#z5=?-=fj<&rW4& zj{n~4%3kh6ro!MQ*z|nfTy~lv5*GMg1<&~o5goN zRWEuroO$F>0c9`Er53^W8RJcJtk6;EFpTMS@Hh{ngz$T!MzK+lN>Ra-m#`absNg1^ zRg7Ouq~<|;pgb3e%wzbG<=&^(y{+-zGToyi5#WGbn$&~&6A5v-qF(5KCdlK z;KKis04;kIEE5(ElH)El+~Q!LjyAbS=puX9&D@vO@m6+k>xRYPV^R`fEU3yHX6{jUqb5szVtbtjrZz4}jMIp52h-)cd ztk7z>#kD<+Z@x}tEwziKgNn+ZPm=P=A(>r4L8StDpd(PPSY{YFd`)9rv9EP;6==&k zP7}>d5xCQ1Ub(W$DAq%O`VSm@A3)A!kEGW8Zz{6 za@YCrOk(IX8`876)S;#bB;`~twd>vl?TMnixZCi*zg$YGKq|T`qa4>E+v-3%q2iaX z1Rrt8p!=Yl@A`YF_I<{bWPcRDZ7OEQO|8C8_{2z+s@m?^bj?cs*Xpp@CAd?0^5MoZ^`$x zZjOTPPF~ylDgxr?<%D_1MuhcXJ>kWIIu^?YC)9=QdLu}QC8Rt^Xm#W=*w1;7%EWk{ zH_B4+Q6!fvt`WoB7^jLTLOWN1Cw3>x-Oe`m&BH-)JsLHesm-VV%piJn?dZBmIlbty uv6Egc?S-koZQ1}nw+{7ulQHxF0o);gzz+b4GG?K%#Ao{g000001X)_!IDd%% literal 0 HcmV?d00001 diff --git a/tests/test_runes.py b/tests/test_runes.py index 5f79ed372..785153c2f 100644 --- a/tests/test_runes.py +++ b/tests/test_runes.py @@ -1,8 +1,11 @@ from fixtures import * # noqa: F401,F403 +from fixtures import TEST_NETWORK from pyln.client import RpcError import base64 +import os import pytest import time +import unittest def test_createrune(node_factory): @@ -421,3 +424,28 @@ def test_rune_pay_amount(node_factory): method='pay', params={'bolt11': inv2, 'amount_msat': 9999}) assert res['valid'] is True + + +@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Depends on canned sqlite3 db") +@unittest.skipIf(TEST_NETWORK != 'regtest', 'canned sqlite3 db is regtest') +def test_commando_rune_migration(node_factory): + """Test migration from commando's datastore using db from test_commando_listrunes""" + l1 = node_factory.get_node(dbfile='commando_listrunes.sqlite3.xz', + options={'database-upgrade': True}) + + # This happens really early in logs! + l1.daemon.logsearch_start = 0 + l1.daemon.wait_for_logs(['Transferring commando rune to db: '] * 2) + + # datastore should be empty: + assert l1.rpc.listdatastore(['commando', 'runes']) == {'datastore': []} + + # Should match commando results! + assert l1.rpc.showrunes() == {'runes': [{'rune': + 'OSqc7ixY6F-gjcigBfxtzKUI54uzgFSA6YfBQoWGDV89MA==', + 'unique_id': '0', 'restrictions': + [], 'restrictions_as_english': ''}, + {'rune': + 'geZmO6U7yqpHn-moaX93FVMVWrDRfSNY4AXx9ypLcqg9MQ==', + 'unique_id': '1', 'restrictions': + [], 'restrictions_as_english': ''}]} diff --git a/wallet/db.c b/wallet/db.c index 416171a73..ca8fde1d4 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -965,6 +965,7 @@ static struct migration dbmigrations[] = { {NULL, migrate_initialize_wait_indexes}, {SQL("ALTER TABLE invoices ADD updated_index BIGINT DEFAULT 0"), NULL}, {SQL("CREATE INDEX invoice_update_idx ON invoices (updated_index)"), NULL}, + {NULL, migrate_datastore_commando_runes}, }; /** diff --git a/wallet/db.h b/wallet/db.h index f891d18a6..f662ec104 100644 --- a/wallet/db.h +++ b/wallet/db.h @@ -26,4 +26,6 @@ struct db *db_setup(const tal_t *ctx, struct lightningd *ld, /* We store last wait indices in our var table. */ void load_indexes(struct db *db, struct indexes *indexes); +/* Migration function for old commando datastore runes. */ +void migrate_datastore_commando_runes(struct lightningd *ld, struct db *db); #endif /* LIGHTNING_WALLET_DB_H */ diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index 2308b1566..e368a7aaa 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -11,11 +11,13 @@ static void db_log_(struct logger *log UNUSED, enum log_level level UNUSED, cons #include "db/exec.c" #include "db/utils.c" #include "wallet/db.c" +#include "wallet/wallet.c" #include "test_utils.h" #include #include +#include #include #include @@ -23,6 +25,20 @@ static void db_log_(struct logger *log UNUSED, enum log_level level UNUSED, cons /* Generated stub for bip32_pubkey */ void bip32_pubkey(struct lightningd *ld UNNEEDED, struct pubkey *pubkey UNNEEDED, u32 index UNNEEDED) { fprintf(stderr, "bip32_pubkey called!\n"); abort(); } +/* Generated stub for channel_scid_or_local_alias */ +const struct short_channel_id *channel_scid_or_local_alias(const struct channel *chan UNNEEDED) +{ fprintf(stderr, "channel_scid_or_local_alias called!\n"); abort(); } +/* Generated stub for connect_htlc_in */ +void connect_htlc_in(struct htlc_in_map *map UNNEEDED, struct htlc_in *hin UNNEEDED) +{ fprintf(stderr, "connect_htlc_in called!\n"); abort(); } +/* Generated stub for connect_htlc_out */ +void connect_htlc_out(struct htlc_out_map *map UNNEEDED, struct htlc_out *hout UNNEEDED) +{ fprintf(stderr, "connect_htlc_out 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) @@ -33,6 +49,9 @@ void fatal(const char *fmt UNNEEDED, ...) /* Generated stub for fatal_vfmt */ void fatal_vfmt(const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "fatal_vfmt called!\n"); abort(); } +/* Generated stub for find_peer_by_dbid */ +struct peer *find_peer_by_dbid(struct lightningd *ld UNNEEDED, u64 dbid UNNEEDED) +{ fprintf(stderr, "find_peer_by_dbid called!\n"); abort(); } /* Generated stub for fromwire_hsmd_get_channel_basepoints_reply */ bool fromwire_hsmd_get_channel_basepoints_reply(const void *p UNNEEDED, struct basepoints *basepoints UNNEEDED, struct pubkey *funding_pubkey UNNEEDED) { fprintf(stderr, "fromwire_hsmd_get_channel_basepoints_reply called!\n"); abort(); } @@ -46,13 +65,173 @@ void get_channel_basepoints(struct lightningd *ld UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED) { fprintf(stderr, "get_channel_basepoints called!\n"); abort(); } +/* Generated stub for htlc_in_check */ +struct htlc_in *htlc_in_check(const struct htlc_in *hin UNNEEDED, const char *abortstr UNNEEDED) +{ fprintf(stderr, "htlc_in_check called!\n"); abort(); } +/* Generated stub for htlc_out_connect_htlc_in */ +void htlc_out_connect_htlc_in(struct htlc_out *hout UNNEEDED, struct htlc_in *hin UNNEEDED) +{ fprintf(stderr, "htlc_out_connect_htlc_in called!\n"); abort(); } +/* Generated stub for invoices_new */ +struct invoices *invoices_new(const tal_t *ctx UNNEEDED, + struct wallet *wallet UNNEEDED, + struct timers *timers UNNEEDED) +{ fprintf(stderr, "invoices_new called!\n"); abort(); } /* Generated stub for logv */ void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const struct node_id *node_id UNNEEDED, bool call_notifier UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED) { fprintf(stderr, "logv called!\n"); abort(); } +/* Generated stub for new_channel */ +struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED, + /* NULL or stolen */ + struct wallet_shachain *their_shachain STEALS UNNEEDED, + enum channel_state state UNNEEDED, + enum side opener UNNEEDED, + /* NULL or stolen */ + struct logger *log STEALS UNNEEDED, + const char *transient_billboard TAKES UNNEEDED, + u8 channel_flags UNNEEDED, + bool req_confirmed_ins_local UNNEEDED, + bool req_confirmed_ins_remote UNNEEDED, + const struct channel_config *our_config UNNEEDED, + u32 minimum_depth UNNEEDED, + u64 next_index_local UNNEEDED, + u64 next_index_remote UNNEEDED, + u64 next_htlc_id UNNEEDED, + const struct bitcoin_outpoint *funding UNNEEDED, + struct amount_sat funding_sats UNNEEDED, + struct amount_msat push UNNEEDED, + struct amount_sat our_funds UNNEEDED, + bool remote_channel_ready UNNEEDED, + /* NULL or stolen */ + struct short_channel_id *scid STEALS UNNEEDED, + struct short_channel_id *alias_local STEALS UNNEEDED, + struct short_channel_id *alias_remote STEALS UNNEEDED, + struct channel_id *cid UNNEEDED, + struct amount_msat our_msatoshi UNNEEDED, + struct amount_msat msatoshi_to_us_min UNNEEDED, + struct amount_msat msatoshi_to_us_max UNNEEDED, + struct bitcoin_tx *last_tx STEALS UNNEEDED, + const struct bitcoin_signature *last_sig UNNEEDED, + /* NULL or stolen */ + const struct bitcoin_signature *last_htlc_sigs STEALS UNNEEDED, + const struct channel_info *channel_info UNNEEDED, + const struct fee_states *fee_states TAKES UNNEEDED, + /* NULL or stolen */ + u8 *remote_shutdown_scriptpubkey STEALS UNNEEDED, + const u8 *local_shutdown_scriptpubkey UNNEEDED, + u64 final_key_idx UNNEEDED, + bool last_was_revoke UNNEEDED, + /* NULL or stolen */ + struct changed_htlc *last_sent_commit STEALS UNNEEDED, + u32 first_blocknum UNNEEDED, + u32 min_possible_feerate UNNEEDED, + u32 max_possible_feerate UNNEEDED, + const struct basepoints *local_basepoints UNNEEDED, + const struct pubkey *local_funding_pubkey UNNEEDED, + const struct pubkey *future_per_commitment_point UNNEEDED, + u32 feerate_base UNNEEDED, + u32 feerate_ppm UNNEEDED, + /* NULL or stolen */ + const u8 *remote_upfront_shutdown_script STEALS UNNEEDED, + u64 local_static_remotekey_start UNNEEDED, + u64 remote_static_remotekey_start UNNEEDED, + const struct channel_type *type STEALS UNNEEDED, + enum side closer UNNEEDED, + enum state_change reason UNNEEDED, + /* NULL or stolen */ + const struct bitcoin_outpoint *shutdown_wrong_funding STEALS UNNEEDED, + const struct height_states *height_states TAKES UNNEEDED, + u32 lease_expiry UNNEEDED, + secp256k1_ecdsa_signature *lease_commit_sig STEALS UNNEEDED, + u32 lease_chan_max_msat UNNEEDED, + u16 lease_chan_max_ppt UNNEEDED, + struct amount_msat htlc_minimum_msat UNNEEDED, + struct amount_msat htlc_maximum_msat UNNEEDED, + bool ignore_fee_limits UNNEEDED) +{ fprintf(stderr, "new_channel 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_inflight */ +struct channel_inflight *new_inflight(struct channel *channel UNNEEDED, + const struct bitcoin_outpoint *funding_outpoint UNNEEDED, + u32 funding_feerate UNNEEDED, + struct amount_sat funding_sat UNNEEDED, + struct amount_sat our_funds UNNEEDED, + struct wally_psbt *funding_psbt STEALS UNNEEDED, + struct bitcoin_tx *last_tx STEALS UNNEEDED, + const struct bitcoin_signature last_sig UNNEEDED, + const u32 lease_expiry UNNEEDED, + const secp256k1_ecdsa_signature *lease_commit_sig UNNEEDED, + const u32 lease_chan_max_msat UNNEEDED, + const u16 lease_chan_max_ppt UNNEEDED, + const u32 lease_blockheight_start UNNEEDED, + const struct amount_msat lease_fee UNNEEDED, + const struct amount_sat lease_amt UNNEEDED) +{ fprintf(stderr, "new_inflight called!\n"); abort(); } +/* Generated stub for new_logger */ +struct logger *new_logger(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, + const struct node_id *default_node_id UNNEEDED, + const char *fmt UNNEEDED, ...) +{ fprintf(stderr, "new_logger called!\n"); abort(); } +/* Generated stub for new_peer */ +struct peer *new_peer(struct lightningd *ld UNNEEDED, u64 dbid UNNEEDED, + const struct node_id *id UNNEEDED, + const struct wireaddr_internal *addr UNNEEDED, + const u8 *their_features TAKES UNNEEDED, + bool connected_incoming UNNEEDED) +{ fprintf(stderr, "new_peer 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_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 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 peer_set_dbid */ +void peer_set_dbid(struct peer *peer UNNEEDED, u64 dbid UNNEEDED) +{ fprintf(stderr, "peer_set_dbid called!\n"); abort(); } /* Generated stub for psbt_fixup */ const u8 *psbt_fixup(const tal_t *ctx UNNEEDED, const u8 *psbtblob UNNEEDED) { fprintf(stderr, "psbt_fixup called!\n"); abort(); } +/* Generated stub for remove_htlc_in_by_dbid */ +struct htlc_in *remove_htlc_in_by_dbid(struct htlc_in_map *remaining_htlcs_in UNNEEDED, + u64 dbid UNNEEDED) +{ fprintf(stderr, "remove_htlc_in_by_dbid called!\n"); abort(); } +/* Generated stub for rune_is_ours */ +const char *rune_is_ours(struct lightningd *ld UNNEEDED, const struct rune *rune UNNEEDED) +{ fprintf(stderr, "rune_is_ours called!\n"); abort(); } /* Generated stub for to_canonical_invstr */ const char *to_canonical_invstr(const tal_t *ctx UNNEEDED, const char *invstring UNNEEDED) { fprintf(stderr, "to_canonical_invstr called!\n"); abort(); } @@ -62,6 +241,12 @@ u8 *towire_hsmd_get_channel_basepoints(const tal_t *ctx UNNEEDED, const struct n /* 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_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 txfilter_add_scriptpubkey */ +void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, const u8 *script TAKES UNNEEDED) +{ fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); } /* Generated stub for wait_index_name */ const char *wait_index_name(enum wait_index index UNNEEDED) { fprintf(stderr, "wait_index_name called!\n"); abort(); } diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index d84c92b51..9bd8ee481 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -674,6 +674,9 @@ 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 rune_is_ours */ +const char *rune_is_ours(struct lightningd *ld UNNEEDED, const struct rune *rune UNNEEDED) +{ fprintf(stderr, "rune_is_ours called!\n"); abort(); } /* Generated stub for serialize_onionpacket */ u8 *serialize_onionpacket( const tal_t *ctx UNNEEDED, diff --git a/wallet/wallet.c b/wallet/wallet.c index 17b38bb67..e729d6d9e 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -5666,3 +5666,39 @@ void wallet_delete_blacklist(struct wallet *wallet, const struct rune_blacklist } tal_free(stmt); } + +void migrate_datastore_commando_runes(struct lightningd *ld, struct db *db) +{ + struct db_stmt *stmt; + const char **startkey, **k; + const u8 *data; + + /* datastore routines expect a tal_arr */ + startkey = tal_arr(tmpctx, const char *, 2); + startkey[0] = "commando"; + startkey[1] = "runes"; + + for (stmt = db_datastore_first(tmpctx, db, startkey, &k, &data, NULL); + stmt; + stmt = db_datastore_next(tmpctx, stmt, startkey, &k, &data, NULL)) { + const char *err, *str; + struct rune *r; + + str = db_col_strdup(tmpctx, stmt, "data"); + r = rune_from_base64(tmpctx, str); + if (!r) + db_fatal(db, "Invalid commando rune %s", str); + err = rune_is_ours(ld, r); + if (err) { + log_unusual(ld->log, + "Warning: removing commando" + " rune %s (uid %s): %s", + str, r->unique_id, err); + } else { + log_debug(ld->log, "Transferring commando rune to db: %s", + str); + db_rune_insert(db, r); + } + db_datastore_remove(db, k); + } +}