From dad00225e07301afbb3977f44a67a46ff9dc1d5a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:43:45 +1030 Subject: [PATCH 01/29] compiler: fix for -O3 errors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI revealed one: ``` cc plugins/libplugin-pay.c plugins/libplugin-pay.c: In function ‘payment_getroute’: plugins/libplugin-pay.c:888:17: error: ‘errstr’ may be used uninitialized [-Werror=maybe-uninitialized] 888 | payment_fail(p, "%s", errstr); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ plugins/libplugin-pay.c:851:21: note: ‘errstr’ was declared here 851 | const char *errstr; | ^~~~~~ cc1: all warnings being treated as errors ``` My local compiler gave another: ``` channeld/channeld.c: In function ‘resume_splice_negotiation’: channeld/channeld.c:3734:23: error: ‘final_tx’ may be used uninitialized [-Werror=maybe-uninitialized] 3734 | msg = towire_channeld_splice_confirmed_signed(tmpctx, final_tx, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3735 | chan_output_index); | ~~~~~~~~~~~~~~~~~~ channeld/channeld.c:3461:28: note: ‘final_tx’ was declared here 3461 | struct bitcoin_tx *final_tx; | ^~~~~~~~ cc1: all warnings being treated as errors make: *** [Makefile:298: channeld/channeld.o] Error 1 ``` So fix both. Signed-off-by: Rusty Russell --- channeld/channeld.c | 2 +- plugins/libplugin-pay.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index a4ea9219c744..e5cd80779c28 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -3458,7 +3458,7 @@ static void resume_splice_negotiation(struct peer *peer, u32 chan_output_index; struct bitcoin_signature their_sig; struct pubkey *their_pubkey; - struct bitcoin_tx *final_tx; + struct bitcoin_tx *final_tx COMPILER_WANTS_INIT("12.3.0 -O3"); struct bitcoin_txid final_txid; u8 **wit_stack; struct tlv_txsigs_tlvs *txsig_tlvs, *their_txsigs_tlvs; diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index e6e1023edb49..68c7ea05e73f 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -817,6 +817,7 @@ static struct route_hop *route(const tal_t *ctx, } } + *errmsg = NULL; return r; } From 522295ac0f7b36cc22318b06f638168df8104fb6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:04 +1030 Subject: [PATCH 02/29] common: prepare unit tests for lack of private channels. Created a new canned gossmap without private channels, updated tests. Signed-off-by: Rusty Russell --- common/test/run-gossmap_canned.c | 261 ++++++++++++++--- common/test/run-gossmap_local.c | 463 +++++++++++++++++-------------- plugins/renepay/test/run-mcf.c | 454 ++++++++++++++++-------------- 3 files changed, 722 insertions(+), 456 deletions(-) diff --git a/common/test/run-gossmap_canned.c b/common/test/run-gossmap_canned.c index c9d083f8af90..2bd9f6cc2e28 100644 --- a/common/test/run-gossmap_canned.c +++ b/common/test/run-gossmap_canned.c @@ -27,11 +27,11 @@ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id U { fprintf(stderr, "towire_channel_id called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ -/* Canned gossmap, taken from tests/test_gossip.py - * $> od -tx1 -Anone -v < /tmp/ltests-rtchpzh1/test_peers_1/lightning-2/regtest/gossip_store | sed 's/ / 0x/g'| cut -c2- | sed -e 's/ /, /g' -e 's/$/,/' +/* Canned gossmap, taken from tests/test_gossip.py, with channels mined. + * $> od -tx1 -Anone -v < /tmp/ltests-rtchpzh1/test_gossip_store_compact_noappend_1/lightning-2/regtest/gossip_store | sed 's/ / 0x/g'| cut -c2- | sed -e 's/ /,/g' -e 's/$/,/' */ static u8 canned_map[] = { - 0x0a,0x00,0x00,0x01,0xbc,0x4a,0xe8,0x33,0xa0,0x00,0x00,0x00,0x00,0x10,0x08,0x00, + 0x0c,0x80,0x00,0x01,0xbc,0x09,0x8b,0x67,0xe6,0x00,0x00,0x00,0x00,0x10,0x08,0x00, 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -51,34 +51,227 @@ static u8 canned_map[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e, 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67, - 0x00,0x00,0x01,0x00,0x01,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7, + 0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7, 0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1, - 0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x66,0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57, - 0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7,0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9, - 0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40, + 0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10, + 0xe5,0x40,0x87,0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0, + 0x90,0xb3,0x9c,0x3a,0x5d,0x88,0x5d,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40, 0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff, 0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64, 0x40,0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19, - 0xff,0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x00,0x00,0x00,0x8e,0xf7,0xf5,0x09, - 0x1e,0x00,0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x53,0x0b,0x21,0x64,0xa7, - 0xd8,0x03,0x4f,0x50,0xb8,0x16,0x9e,0xaa,0x73,0x6b,0xe0,0x70,0x36,0x16,0xc5,0xb1, - 0x04,0xd7,0xfd,0xc0,0x8f,0x68,0x72,0xd7,0x3e,0x38,0x72,0x05,0x7c,0x00,0x81,0x44, - 0x96,0xa2,0x22,0x08,0x15,0xdd,0x88,0x86,0xe7,0xb5,0x97,0x45,0x73,0x46,0x35,0xde, - 0xf0,0x62,0x11,0x22,0x1f,0xea,0x62,0xd0,0x40,0x6f,0x60,0x06,0x22,0x6e,0x46,0x11, + 0xff,0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x00,0x00,0x01,0xb0,0x6e,0x30,0x94, + 0x60,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x33,0x57,0x33,0xf5,0x94,0x2d,0xf5,0xd9, + 0x50,0xeb,0x87,0x66,0xde,0xe3,0xa9,0xd6,0x62,0x69,0x22,0x84,0x4e,0xd6,0xae,0x7a, + 0x11,0x0d,0xd7,0xe7,0xed,0xc3,0x2e,0x3f,0x6f,0x3d,0x9a,0xc5,0xcd,0xea,0x23,0xce, + 0x25,0xbb,0x8d,0xbf,0x76,0x1f,0xd3,0xd5,0xfc,0x56,0xc0,0x5b,0x68,0x56,0x31,0x6d, + 0x12,0xe9,0xd3,0x2c,0xa0,0xf0,0x8c,0x69,0xca,0x03,0x06,0xfe,0x71,0x6e,0x7b,0x51, + 0x51,0x31,0x7d,0x64,0x40,0xb7,0x37,0x3d,0x9f,0xbc,0x64,0x6e,0xad,0x48,0xf2,0x16, + 0x3f,0x2b,0x6d,0x51,0x1a,0xfe,0x6a,0x79,0xc7,0x55,0x51,0xc2,0x62,0x0f,0xc8,0x09, + 0x74,0xf2,0xf8,0x64,0x32,0x9d,0x97,0x78,0xa0,0x8c,0xdf,0xbc,0x9f,0x2c,0x9c,0x13, + 0x44,0xc4,0x32,0x70,0x2c,0x66,0x80,0x7c,0xfb,0x4d,0xb6,0x9b,0x80,0xfa,0xe8,0xc3, + 0x3c,0x70,0x14,0x3d,0x94,0x8b,0x36,0x61,0x4d,0x62,0x08,0x91,0xbe,0xe2,0xdf,0x99, + 0xc8,0x6b,0xc6,0x22,0x07,0xc1,0x7e,0x3b,0x91,0x86,0x21,0x4c,0x0c,0xcf,0xf2,0xde, + 0xd5,0x59,0x8a,0xcc,0xc9,0x0e,0xb1,0xd5,0xb2,0xf7,0xa8,0x3c,0xd7,0xf6,0x8d,0x71, + 0x2e,0xa0,0x47,0xd8,0x01,0x9f,0x34,0x30,0x63,0xb0,0xa2,0x36,0x35,0x6a,0x38,0x71, + 0x46,0xf5,0x8f,0xa8,0x32,0xdd,0xc1,0x3c,0x47,0x14,0x52,0x2c,0xbb,0x50,0x3f,0x5f, + 0x3c,0xa8,0xfc,0xec,0x66,0x02,0xbe,0x24,0x38,0xad,0x3f,0x98,0xfa,0x0c,0xee,0xd5, + 0x8f,0xe3,0xa0,0x66,0xd3,0x85,0xfc,0xac,0xd9,0x8c,0x70,0x4b,0x2a,0x8e,0x98,0xa3, + 0xe2,0x0b,0xf7,0x6b,0x35,0xb7,0x36,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85, + 0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3, + 0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87,0x5d, + 0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c,0x3a, + 0x5d,0x88,0x5d,0x02,0x90,0x53,0x52,0x1d,0x6e,0xa7,0xa5,0x2c,0xdd,0x55,0xf7,0x33, + 0xd0,0xfb,0x2d,0x07,0x7c,0x03,0x73,0xb0,0x05,0x3b,0x5b,0x81,0x0d,0x92,0x72,0x44, + 0x06,0x1b,0x75,0x73,0x02,0xd6,0x06,0x3d,0x02,0x26,0x91,0xb2,0x49,0x0a,0xb4,0x54, + 0xde,0xe7,0x3a,0x57,0xc6,0xff,0x5d,0x30,0x83,0x52,0xb4,0x61,0xec,0xe6,0x9f,0x3c, + 0x28,0x4f,0x2c,0x24,0x12,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00, + 0x00,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x80,0x00,0x00,0x8a,0xc5, + 0x33,0xff,0x38,0x65,0x55,0xb3,0x60,0x01,0x02,0x2f,0xd9,0x23,0x60,0x1e,0x1c,0xa0, + 0xac,0xe5,0x06,0x8c,0xe4,0x8e,0x14,0xf3,0xcd,0x31,0x44,0x16,0xc4,0x0d,0x2e,0x14, + 0x8c,0xa1,0xc8,0x4f,0xa6,0xa8,0xe4,0x64,0x9b,0x45,0x79,0xd1,0xb5,0x2f,0x04,0x19, + 0x86,0xe5,0x5c,0x99,0x43,0xf1,0xd0,0xf3,0x6f,0x52,0xd6,0x88,0xf0,0x9b,0x9c,0x58, + 0x98,0x69,0x0d,0x4e,0x76,0x3e,0xbd,0x6e,0x95,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x00,0x00,0x00,0x95,0x97,0xd7,0xa4,0x39,0x65,0x55,0xb3,0x65,0x01,0x01,0x36, + 0x59,0x20,0x77,0x0e,0xf4,0x73,0x10,0xd7,0xb6,0x59,0x5a,0x7c,0xbe,0xd0,0x56,0x51, + 0x3d,0x97,0xbe,0x84,0xb7,0x02,0xb5,0x89,0x72,0xbd,0xb3,0x19,0x2a,0x54,0x5f,0x57, + 0x52,0x09,0x1d,0xff,0x0f,0xe6,0x70,0x1e,0x71,0x23,0xaa,0x3f,0x98,0x89,0x86,0x35, + 0x87,0xc2,0x66,0xd9,0x99,0xbd,0xa2,0x7e,0x16,0x12,0xd9,0x6b,0xc4,0xd3,0x0c,0x00, + 0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x65,0x02,0x2d,0x22,0x36, + 0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5, + 0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x2d,0x22, + 0x53,0x49,0x4c,0x45,0x4e,0x54,0x41,0x52,0x54,0x49,0x53,0x54,0x2d,0x31,0x2d,0x31, + 0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64, + 0x00,0x00,0x80,0x00,0x00,0x8a,0xd0,0xde,0x20,0xc6,0x65,0x55,0xb3,0x60,0x01,0x02, + 0x11,0xd6,0x4b,0xc5,0x88,0x33,0x4b,0x6c,0x1e,0x0c,0x4c,0x5c,0x65,0x69,0x35,0x66, + 0x45,0x80,0xbc,0x4b,0x56,0x3d,0x98,0x2c,0xb3,0x45,0xef,0x22,0x44,0x6e,0xca,0x6c, + 0x1f,0xe9,0x2a,0xf2,0x4a,0xe1,0x26,0xdb,0x15,0x6f,0x7e,0x3b,0xdd,0xd3,0x40,0x54, + 0xb2,0xc7,0x07,0xfe,0x67,0xb0,0xf3,0x35,0x56,0x25,0xc6,0x53,0xfd,0x54,0x56,0x5e, + 0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf, + 0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f, + 0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x60,0x01,0x01,0x00,0x06, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a, + 0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x95,0x87,0xf8,0x92,0xf3, + 0x65,0x55,0xb3,0x65,0x01,0x01,0x32,0x6c,0xde,0x4a,0xc5,0xe8,0xd4,0xa0,0xed,0xbc, + 0x2c,0x13,0x5e,0xb9,0x1e,0xc3,0xc3,0x86,0xcb,0x75,0xeb,0x6f,0xce,0xc5,0xc5,0x57, + 0x01,0x1c,0x9c,0xb7,0x32,0x17,0x01,0x10,0x8c,0xdd,0x04,0x31,0x78,0xae,0xb4,0x88, + 0x8d,0xf8,0xe8,0x35,0x90,0x69,0x91,0x84,0xd0,0x16,0xd8,0x44,0xbc,0xde,0x37,0xe8, + 0x4e,0x1a,0x95,0xb6,0xa6,0x73,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65, + 0x55,0xb3,0x65,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87, + 0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c, + 0x3a,0x5d,0x88,0x5d,0x03,0x5d,0x2b,0x48,0x4f,0x50,0x50,0x49,0x4e,0x47,0x46,0x49, + 0x52,0x45,0x2d,0x63,0x31,0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38, + 0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x8a,0xcb,0xd4,0xc7, + 0xa1,0x65,0x55,0xb3,0x65,0x01,0x02,0x1d,0x3f,0x42,0x7f,0x3d,0xdb,0x58,0x2b,0xcb, + 0x78,0x5d,0x24,0xf1,0x67,0xc6,0xc7,0xd8,0x6e,0x6c,0x5b,0xf8,0xfb,0x27,0x17,0x58, + 0xaa,0x7e,0x46,0x86,0x49,0x66,0x21,0x47,0x76,0xbd,0xf2,0x2d,0xae,0x29,0xf0,0x6f, + 0x17,0x6e,0xf2,0x7f,0x01,0xda,0x16,0xa9,0x1d,0x6a,0x61,0x4c,0x41,0x71,0x19,0x4d, + 0x37,0xac,0x8a,0x28,0xd8,0x62,0xfb,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca, + 0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7, + 0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65, + 0x55,0xb3,0x65,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80, + 0x00,0x01,0xbc,0x39,0xdb,0xc7,0xdf,0x00,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e,0x46,0x11, 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, - 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00, - 0x01,0x00,0x01,0x62,0xc4,0xdb,0x93,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b, - 0x02,0x33,0x80,0x00,0x00,0x00,0x8e,0x6f,0xbe,0x57,0x16,0x00,0x00,0x00,0x00,0x10, - 0x06,0x00,0x8a,0x01,0x02,0x0c,0x6c,0x84,0xfe,0xfd,0x31,0xe5,0x56,0x63,0xce,0xea, - 0x62,0x3c,0x82,0x3c,0xf8,0xb8,0xae,0x6d,0x8a,0xc7,0x60,0x44,0xe5,0x0d,0xaf,0xdd, - 0x76,0xae,0x54,0x08,0xec,0x13,0x45,0xa0,0x69,0x60,0x89,0x74,0x88,0xe1,0xe8,0xcb, - 0xcc,0x03,0xe3,0x1b,0x4a,0x77,0x17,0xfe,0xa1,0xe1,0xa3,0x42,0x39,0x2d,0xda,0x7b, - 0x68,0xf3,0xd5,0x97,0x88,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44, + 0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e, + 0x3c,0xa3,0x1d,0x59,0x02,0x66,0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84, + 0x88,0x83,0x0b,0x60,0xf7,0xe7,0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83, + 0xb3,0x15,0xc0,0x35,0x18,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99,0x5d, + 0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c,0x17, + 0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99, + 0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c, + 0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x80,0x00,0x00,0x8e,0x85,0x67,0x9b,0xcf,0x00, + 0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x27,0x9e,0x4e,0x43,0x39,0xa6,0x92, + 0x19,0x35,0x50,0x19,0xbb,0x51,0x5b,0xf9,0xac,0xdb,0xda,0x9c,0xde,0x81,0x8b,0x56, + 0x2e,0x0a,0x3d,0xd5,0xb0,0x5f,0x10,0x2e,0x6c,0x22,0x55,0x7e,0x07,0xc2,0x5f,0x4b, + 0x9c,0xc1,0x21,0x6e,0x07,0x66,0x41,0x60,0xde,0x3e,0xe2,0x24,0xa5,0x9e,0xec,0xaf, + 0xd7,0xcc,0x3f,0x87,0x7c,0x32,0x29,0xca,0xe7,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6c,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0xca,0xa4,0x8e,0x70,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x4e,0x3f,0x3b,0x6d,0xda,0xcc,0xd3,0xef,0x5f,0xaf,0x26,0x76,0x16, + 0x64,0xa2,0x82,0x97,0xe8,0xb4,0xe4,0xb1,0x2d,0xec,0xa1,0x9e,0x91,0x69,0xd3,0xde, + 0xe9,0x58,0xc7,0x19,0x06,0x90,0x42,0x86,0x97,0xf3,0x88,0xca,0x35,0xd5,0xec,0x79, + 0x5e,0x59,0x33,0x31,0xf4,0x0c,0xdb,0x55,0x5d,0x78,0xd7,0x22,0x59,0xa2,0xe5,0x8d, + 0xeb,0x65,0x41,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x6c,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x8a,0xbf, + 0x0d,0x7a,0xbc,0x65,0x55,0xb3,0x6f,0x01,0x02,0x59,0xc9,0x36,0x84,0xaa,0x13,0x70, + 0x73,0x7d,0xa7,0xe6,0x8a,0x72,0x05,0x15,0xa9,0x06,0x69,0xe0,0xc0,0x0d,0x15,0x6d, + 0x22,0x5c,0xd6,0x1a,0x3e,0x56,0xaa,0x9d,0x98,0x68,0x5a,0x3c,0xdc,0x38,0x71,0xee, + 0x0d,0x02,0x3e,0x2f,0xd0,0x97,0xd7,0xab,0xe2,0x0d,0xdf,0xf5,0xa6,0xd1,0x9c,0xb6, + 0xb9,0x30,0xd6,0xdd,0x10,0xa7,0xa3,0xce,0x5e,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6f,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0x80,0x00,0x75,0xd3,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x26,0x62,0x25,0x68,0x2d,0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93, + 0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d,0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3, + 0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10,0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf, + 0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39,0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7, + 0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00, + 0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80,0x00,0x00,0x8e,0xdc, + 0x5e,0x38,0x7a,0x00,0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x5d,0xf9,0x14, + 0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7,0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b, + 0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc,0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73, + 0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd,0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e, + 0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30,0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e, + 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, + 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e, + 0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00, + 0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x01,0xb0,0xb8,0x17,0x71,0xe9,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x0d,0xef,0xc0,0x12,0x4f,0xd4,0xe4,0x1c,0xce,0xc3,0xf4,0x83,0x17, + 0x21,0x7e,0x33,0x11,0x5a,0x8f,0x8c,0x39,0xae,0xbb,0x06,0x2b,0x4e,0x73,0xa6,0x52, + 0xee,0x0e,0x61,0x03,0xf9,0xf1,0x16,0x7b,0x22,0xbd,0xcb,0x92,0xcf,0x82,0x2d,0x0f, + 0xcc,0x26,0xcb,0x11,0x9f,0x0a,0xf5,0x23,0xf4,0x26,0x97,0x86,0x7e,0x21,0x51,0x85, + 0x16,0x3a,0x0e,0x4b,0x1f,0x64,0xf3,0x62,0xf4,0x2f,0x13,0x54,0x5c,0x9a,0xed,0xd6, + 0x9d,0x5d,0xf5,0x17,0x85,0xcc,0x5d,0x53,0xa4,0x84,0x36,0x9b,0xe9,0xa7,0x4a,0x04, + 0x1f,0x8c,0x1c,0x28,0xc7,0x1e,0xab,0xb3,0xf2,0x53,0x3d,0xf8,0xb6,0xcd,0xd8,0x45, + 0x6e,0xc3,0x77,0xdb,0xb1,0x2b,0xa5,0xdd,0xc9,0xbf,0x69,0xa7,0xdf,0x98,0x2c,0x54, + 0xa7,0xa8,0xf5,0x4f,0xc3,0xd1,0x57,0x81,0x98,0x60,0xa0,0xb6,0x32,0x83,0x08,0x65, + 0x1e,0x79,0x24,0xf4,0xbe,0xfe,0x14,0xa6,0xfd,0x31,0x9b,0xfa,0x15,0x6f,0x1b,0xab, + 0x64,0x8b,0x69,0x48,0xb4,0x2e,0x99,0xca,0xd7,0x46,0x97,0x57,0x17,0x1d,0x5d,0x53, + 0xe5,0xde,0xae,0xbb,0x2d,0x74,0x86,0xa5,0xe5,0x8e,0x02,0x5c,0x2c,0x8d,0x0d,0x78, + 0xdc,0xf1,0xa0,0x05,0xb8,0xbd,0x64,0x7d,0x51,0x47,0x5e,0x39,0xaa,0x08,0x2d,0xf2, + 0xd0,0x1a,0x96,0x59,0xab,0x88,0x94,0xa2,0xf7,0x2e,0x09,0x3b,0xd0,0xed,0xfc,0xb4, + 0x1b,0xaa,0xba,0x34,0xf8,0x7b,0x11,0x51,0x36,0x7b,0x13,0x84,0x6f,0xc9,0x4a,0x58, + 0x92,0x3c,0x0c,0xa2,0x4c,0x8f,0xc5,0x78,0xb4,0x4a,0xad,0x98,0x08,0x4e,0x4a,0xf3, + 0x7a,0x28,0x80,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, - 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x01,0x62,0xc4,0xdb, - 0x93,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22, + 0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d, + 0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x03, + 0xbb,0xee,0x60,0xc3,0x95,0x05,0x6b,0x8a,0x12,0x01,0xe0,0x6e,0xd7,0x9e,0x29,0x14, + 0xc1,0x1a,0x61,0xd7,0xb1,0xaa,0x78,0x18,0x46,0x46,0x8d,0x02,0x48,0x9d,0xba,0x69, + 0x02,0x32,0x42,0x66,0xde,0x84,0x03,0xb3,0xab,0x15,0x7a,0x09,0xf1,0xf7,0x84,0xd5, + 0x87,0xaf,0x61,0x83,0x1c,0x99,0x8c,0x15,0x1b,0xcc,0x21,0xbb,0x74,0xc2,0xb2,0x31, + 0x4b,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00,0x00,0x10,0x05,0x00, + 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x00,0x00,0x00,0x8a,0xe1,0x31,0x6b,0x76,0x65, + 0x55,0xb3,0x71,0x01,0x02,0x5d,0xf9,0x14,0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7, + 0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b,0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc, + 0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73,0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd, + 0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e,0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30, + 0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00, + 0x8a,0xbd,0x6f,0x26,0xdf,0x65,0x55,0xb3,0x71,0x01,0x02,0x26,0x62,0x25,0x68,0x2d, + 0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93,0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d, + 0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3,0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10, + 0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf,0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39, + 0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7,0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11, + 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b, + 0x02,0x33,0x80,0x00,0x00,0x00,0x95,0xf6,0xd7,0x24,0x69,0x65,0x55,0xb3,0x79,0x01, + 0x01,0x42,0x62,0x2b,0xf0,0x0a,0x44,0xc3,0xe0,0x78,0x3c,0xa7,0x08,0x5a,0xa0,0xaa, + 0x9d,0xb2,0xdc,0x2e,0xa7,0x29,0x0a,0x39,0x3d,0x01,0x57,0xbf,0x34,0x23,0x0f,0xb9, + 0x19,0x33,0x6f,0xc2,0xfb,0x9f,0x25,0xac,0xc4,0xc9,0x47,0xb7,0x41,0x92,0xdb,0x2f, + 0xd5,0xf0,0x1f,0x24,0x32,0xdf,0x38,0x30,0x89,0x93,0xeb,0xc9,0xec,0xf1,0x09,0x51, + 0xbb,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x79,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x02, + 0x66,0xe4,0x4a,0x55,0x4e,0x49,0x4f,0x52,0x42,0x45,0x41,0x4d,0x2d,0x72,0x63,0x31, + 0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64, + 0x65,0x64,0x00,0x00, }; static void check_cannounce(const u8 *cannounce, @@ -131,15 +324,15 @@ int main(int argc, char *argv[]) map = gossmap_load(tmpctx, gossfile, NULL); assert(map); - /* There is an unannounced channel 1<->2 (103x1x1) */ + /* There is a channel 1<->2 (103x1x0) */ assert(node_id_from_hexstr("0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518", 66, &l1)); assert(node_id_from_hexstr("022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59", 66, &l2)); assert(gossmap_find_node(map, &l1)); assert(gossmap_find_node(map, &l2)); - assert(short_channel_id_from_str("103x1x1", 7, &scid12)); + assert(short_channel_id_from_str("110x1x0", 7, &scid12)); assert(gossmap_find_chan(map, &scid12)); - assert(gossmap_find_chan(map, &scid12)->private); + assert(!gossmap_find_chan(map, &scid12)->private); assert(gossmap_chan_get_capacity(map, gossmap_find_chan(map, &scid12), &capacity)); assert(amount_sat_eq(capacity, AMOUNT_SAT(1000000))); @@ -153,11 +346,11 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1657068435); + assert(timestamp == 1700115313); assert(message_flags == 1); assert(channel_flags == 0); - assert(fee_base_msat == 1); - assert(fee_proportional_millionths == 10); + assert(fee_base_msat == 20); + assert(fee_proportional_millionths == 1000); assert(amount_msat_eq(htlc_minimum_msat, AMOUNT_MSAT(0))); assert(amount_msat_eq(htlc_maximum_msat, AMOUNT_MSAT(990000000))); @@ -170,11 +363,11 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1657068435); + assert(timestamp == 1700115313); assert(message_flags == 1); assert(channel_flags == 1); - assert(fee_base_msat == 1); - assert(fee_proportional_millionths == 10); + assert(fee_base_msat == 20); + assert(fee_proportional_millionths == 1000); assert(amount_msat_eq(htlc_minimum_msat, AMOUNT_MSAT(0))); assert(amount_msat_eq(htlc_maximum_msat, AMOUNT_MSAT(990000000))); diff --git a/common/test/run-gossmap_local.c b/common/test/run-gossmap_local.c index e98d1e452ac3..b95e6af5f14c 100644 --- a/common/test/run-gossmap_local.c +++ b/common/test/run-gossmap_local.c @@ -27,214 +27,251 @@ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id U { fprintf(stderr, "towire_channel_id called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ -/* Canned gossmap, taken from tests/test_gossip.py::test_gossip_store_compact_noappend - * $> od -v -Anone -tx1 < /tmp/ltests-kaf30pn0/test_gossip_store_compact_noappend_1/lightning-2/regtest/gossip_store | sed 's/ / 0x/g'| cut -c2- | sed -e 's/ /, /g' -e 's/$/,/' +/* Canned gossmap, taken from tests/test_gossip.py, with channels mined. + * $> od -tx1 -Anone -v < /tmp/ltests-rtchpzh1/test_gossip_store_compact_noappend_1/lightning-2/regtest/gossip_store | sed 's/ / 0x/g'| cut -c2- | sed -e 's/ /,/g' -e 's/$/,/' */ static u8 canned_map[] = { - 0x0a, 0x80, 0x00, 0x01, 0xbc, 0x09, 0x8b, 0x67, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x22, 0x6e - , 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f - , 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67 - , 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7 - , 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1 - , 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x03, 0x5d, 0x2b, 0x11, 0x92, 0xdf, 0xba, 0x13, 0x4e, 0x10 - , 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53, 0xd5, 0xaa, 0x76, 0x6b, 0x80, 0xc0 - , 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x03, 0x1b, 0x84, 0xc5, 0x56, 0x7b, 0x12, 0x64, 0x40 - , 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34, 0x60, 0x48, 0x19, 0xff - , 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x03, 0x1b, 0x84, 0xc5, 0x56, 0x7b, 0x12, 0x64 - , 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34, 0x60, 0x48, 0x19 - , 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x80, 0x00, 0x00, 0x8e, 0x33, 0x3b, 0x90 - , 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x14, 0xb8, 0x21, 0x42, 0x7d - , 0x40, 0x89, 0x60, 0x71, 0x05, 0x8d, 0xe4, 0x50, 0x8e, 0xc3, 0x87, 0x6f, 0xa6, 0x4b, 0x19, 0xe4 - , 0x81, 0xc5, 0x5f, 0xb7, 0x04, 0xb8, 0x74, 0x08, 0x0b, 0x40, 0x5a, 0x74, 0x89, 0xbc, 0x63, 0x24 - , 0x27, 0x93, 0x4d, 0xfc, 0x1a, 0x72, 0xe4, 0xc7, 0xf8, 0x9b, 0xc1, 0x6b, 0xad, 0x9b, 0x04, 0x2e - , 0x14, 0xa4, 0xe9, 0xf5, 0x80, 0xf1, 0x02, 0x8f, 0x50, 0xf3, 0x2c, 0x06, 0x22, 0x6e, 0x46, 0x11 - , 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e - , 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x70, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b - , 0x02, 0x33, 0x80, 0x80, 0x00, 0x00, 0x8e, 0x3e, 0xa2, 0x81, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10 - , 0x06, 0x00, 0x8a, 0x01, 0x02, 0x01, 0x0a, 0xb3, 0x54, 0x3f, 0xd2, 0xa9, 0xf5, 0x30, 0x0f, 0x60 - , 0x7d, 0xf9, 0xf1, 0xdd, 0x63, 0x62, 0xd8, 0xde, 0xe2, 0x94, 0xe4, 0x68, 0xc9, 0x5c, 0xe8, 0x32 - , 0x9b, 0x14, 0xd9, 0xf8, 0x6a, 0x23, 0x3a, 0x67, 0x10, 0x09, 0x64, 0x96, 0x40, 0xcb, 0x0b, 0xf5 - , 0xec, 0xe6, 0xba, 0x8e, 0x77, 0xb4, 0x6a, 0xf1, 0x39, 0x94, 0x86, 0xb0, 0x69, 0xd5, 0x17, 0x67 - , 0x83, 0xda, 0xfa, 0x49, 0x63, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12 - , 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7 - , 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53 - , 0x70, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x00 - , 0x0a, 0x01, 0xf0, 0xcb, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x07, 0x00, 0x00, 0x67, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0xb0, 0xd2, 0xfa, 0x8f, 0x8d, 0x60, 0x17, 0x53, 0x70, 0x01 - , 0x00, 0x24, 0xfd, 0xae, 0x1a, 0xc8, 0x40, 0xa7, 0x33, 0x22, 0xe1, 0x45, 0x7e, 0x76, 0xb8, 0x86 - , 0xdd, 0x17, 0x8c, 0xd4, 0x49, 0x4b, 0x14, 0x3f, 0x81, 0xd4, 0xd4, 0xfa, 0xa7, 0x16, 0x17, 0xd2 - , 0x51, 0x33, 0x9e, 0xcb, 0x0e, 0x22, 0x1c, 0xf6, 0x02, 0x3a, 0x2e, 0x3e, 0x94, 0xf8, 0xae, 0xdb - , 0xee, 0x47, 0x23, 0xda, 0x5c, 0x35, 0x51, 0x57, 0xd8, 0xe4, 0x67, 0x2b, 0x46, 0x82, 0x5e, 0xc7 - , 0x98, 0x51, 0xb3, 0xb0, 0x1a, 0x2c, 0x72, 0x3f, 0x9b, 0xf5, 0xdb, 0xa8, 0xe3, 0x5f, 0x8b, 0x47 - , 0x9d, 0x9c, 0xd9, 0x73, 0xae, 0xc5, 0x0c, 0xca, 0x08, 0xfb, 0x97, 0x57, 0xb5, 0x21, 0x92, 0x05 - , 0x18, 0x42, 0x2d, 0x68, 0x19, 0x70, 0x76, 0x30, 0x61, 0x24, 0xff, 0xa5, 0xb6, 0x58, 0xa2, 0xe2 - , 0xb3, 0x68, 0x93, 0x37, 0xda, 0x6c, 0x3c, 0xcc, 0x5e, 0xf7, 0x3b, 0x51, 0x29, 0x64, 0x30, 0xbe - , 0x2a, 0x19, 0x38, 0x88, 0x9d, 0xda, 0x2a, 0xd1, 0xcb, 0x5e, 0x33, 0xdb, 0x75, 0xcf, 0x2e, 0x0e - , 0xfd, 0xbd, 0x38, 0xce, 0x01, 0x54, 0x62, 0x30, 0xb4, 0xdd, 0xdc, 0x7f, 0x67, 0xca, 0xf8, 0x39 - , 0x10, 0x02, 0x8a, 0x05, 0x3b, 0x76, 0x62, 0x72, 0xd2, 0x84, 0x71, 0x19, 0x19, 0x30, 0x92, 0xfa - , 0x2a, 0x1f, 0xdf, 0x71, 0xe3, 0xd8, 0x4a, 0x56, 0xd0, 0xe4, 0x35, 0xfe, 0x5d, 0x4a, 0x5b, 0x5b - , 0x90, 0x05, 0x28, 0xe4, 0x3b, 0x24, 0x13, 0x46, 0x99, 0x45, 0xc4, 0x92, 0x14, 0x7d, 0x43, 0x21 - , 0x06, 0x50, 0x51, 0xf8, 0x5b, 0x92, 0xb5, 0xb0, 0x90, 0xb1, 0xd7, 0x0d, 0x5a, 0xac, 0xfe, 0xf4 - , 0xe2, 0x70, 0x3e, 0x97, 0x42, 0x25, 0xfb, 0x21, 0x15, 0xf6, 0xb9, 0x32, 0xc8, 0xc3, 0x03, 0xbd - , 0x7a, 0xbd, 0x86, 0xf7, 0xcd, 0x64, 0xe6, 0x1a, 0x7f, 0x5a, 0x04, 0x7a, 0x22, 0xad, 0x7c, 0xfc - , 0x6a, 0x00, 0x00, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x2d, 0x22, 0x36, 0x20 - , 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33 - , 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x03, 0x5d, 0x2b, 0x11 - , 0x92, 0xdf, 0xba, 0x13, 0x4e, 0x10, 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53 - , 0xd5, 0xaa, 0x76, 0x6b, 0x80, 0xc0, 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x02, 0xd5, 0x95 - , 0xae, 0x92, 0xb3, 0x54, 0x4c, 0x32, 0x50, 0xfb, 0x77, 0x2f, 0x21, 0x4a, 0xd8, 0xd4, 0xc5, 0x14 - , 0x25, 0x03, 0x37, 0x40, 0xa5, 0xbc, 0xc3, 0x57, 0x19, 0x0a, 0xdd, 0x6d, 0x7e, 0x7a, 0x02, 0xd6 - , 0x06, 0x3d, 0x02, 0x26, 0x91, 0xb2, 0x49, 0x0a, 0xb4, 0x54, 0xde, 0xe7, 0x3a, 0x57, 0xc6, 0xff - , 0x5d, 0x30, 0x83, 0x52, 0xb4, 0x61, 0xec, 0xe6, 0x9f, 0x3c, 0x28, 0x4f, 0x2c, 0x24, 0x12, 0x00 - , 0x00, 0x00, 0x0a, 0x91, 0x11, 0x83, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x0f, 0x42, 0x40, 0xc0, 0x00, 0x00, 0x8a, 0xf3, 0x48, 0xd5, 0xb3, 0x60, 0x17, 0x53 - , 0x70, 0x01, 0x02, 0x14, 0xb8, 0x21, 0x42, 0x7d, 0x40, 0x89, 0x60, 0x71, 0x05, 0x8d, 0xe4, 0x50 - , 0x8e, 0xc3, 0x87, 0x6f, 0xa6, 0x4b, 0x19, 0xe4, 0x81, 0xc5, 0x5f, 0xb7, 0x04, 0xb8, 0x74, 0x08 - , 0x0b, 0x40, 0x5a, 0x74, 0x89, 0xbc, 0x63, 0x24, 0x27, 0x93, 0x4d, 0xfc, 0x1a, 0x72, 0xe4, 0xc7 - , 0xf8, 0x9b, 0xc1, 0x6b, 0xad, 0x9b, 0x04, 0x2e, 0x14, 0xa4, 0xe9, 0xf5, 0x80, 0xf1, 0x02, 0x8f - , 0x50, 0xf3, 0x2c, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x70, 0x01 - , 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 - , 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0xc0, 0x00, 0x00, 0x8a, 0xfe - , 0xd1, 0xc4, 0x47, 0x60, 0x17, 0x53, 0x70, 0x01, 0x02, 0x01, 0x0a, 0xb3, 0x54, 0x3f, 0xd2, 0xa9 - , 0xf5, 0x30, 0x0f, 0x60, 0x7d, 0xf9, 0xf1, 0xdd, 0x63, 0x62, 0xd8, 0xde, 0xe2, 0x94, 0xe4, 0x68 - , 0xc9, 0x5c, 0xe8, 0x32, 0x9b, 0x14, 0xd9, 0xf8, 0x6a, 0x23, 0x3a, 0x67, 0x10, 0x09, 0x64, 0x96 - , 0x40, 0xcb, 0x0b, 0xf5, 0xec, 0xe6, 0xba, 0x8e, 0x77, 0xb4, 0x6a, 0xf1, 0x39, 0x94, 0x86, 0xb0 - , 0x69, 0xd5, 0x17, 0x67, 0x83, 0xda, 0xfa, 0x49, 0x63, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00 - , 0x00, 0x60, 0x17, 0x53, 0x70, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x40, 0x00, 0x00, 0x9b, 0x4f, 0x9d, 0xb7, 0xb9, 0x60, 0x17, 0x53, 0x77, 0x01, 0x01, 0x6e - , 0x99, 0xf5, 0x9c, 0x1f, 0x21, 0x8d, 0x4a, 0x2b, 0x6e, 0x36, 0x9a, 0x95, 0x20, 0x76, 0x2c, 0x27 - , 0xfb, 0xa8, 0xb1, 0x82, 0x1f, 0x64, 0x34, 0x93, 0x91, 0x9c, 0xeb, 0xfa, 0x40, 0x50, 0x73, 0x4d - , 0x00, 0xce, 0x10, 0xbf, 0x3f, 0x42, 0x3e, 0x56, 0x8f, 0xf8, 0xe0, 0x59, 0x58, 0xb5, 0xbd, 0xc5 - , 0x00, 0x82, 0xe3, 0x27, 0x92, 0x5b, 0xf8, 0x4f, 0x2c, 0x39, 0xec, 0x49, 0x3b, 0x07, 0x5e, 0x00 - , 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x22, 0xaa, 0xa2, 0x60, 0x17 - , 0x53, 0x77, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c - , 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c - , 0xa3, 0x1d, 0x59, 0x02, 0x2d, 0x22, 0x53, 0x49, 0x4c, 0x45, 0x4e, 0x54, 0x41, 0x52, 0x54, 0x49 - , 0x53, 0x54, 0x2d, 0x2d, 0x35, 0x36, 0x2d, 0x67, 0x64, 0x64, 0x31, 0x35, 0x33, 0x63, 0x38, 0x2d - , 0x6d, 0x6f, 0x64, 0x64, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x15, 0x33, 0x0c, 0x6b - , 0x60, 0x17, 0x53, 0x77, 0x01, 0x01, 0x0e, 0x07, 0xaf, 0xd2, 0x33, 0x19, 0x0e, 0x06, 0x01, 0x6d - , 0x57, 0x88, 0x4e, 0x66, 0xf8, 0x08, 0xd9, 0x65, 0x8a, 0x73, 0xfb, 0x1d, 0xe0, 0xad, 0xee, 0x47 - , 0xf8, 0x1c, 0xfc, 0xc3, 0xd2, 0xfd, 0x06, 0x3e, 0x5a, 0x05, 0x65, 0x72, 0x18, 0x61, 0xb8, 0x23 - , 0x04, 0x3d, 0x4b, 0x39, 0x79, 0xe0, 0x85, 0x38, 0xd2, 0x92, 0x14, 0x35, 0x32, 0xaa, 0x9f, 0xab - , 0x5f, 0x98, 0x2c, 0x53, 0xfe, 0x0d, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 - , 0x00, 0x00, 0x22, 0xaa, 0xa2, 0x60, 0x17, 0x53, 0x77, 0x03, 0x5d, 0x2b, 0x11, 0x92, 0xdf, 0xba - , 0x13, 0x4e, 0x10, 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53, 0xd5, 0xaa, 0x76 - , 0x6b, 0x80, 0xc0, 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x03, 0x5d, 0x2b, 0x48, 0x4f, 0x50 - , 0x50, 0x49, 0x4e, 0x47, 0x46, 0x49, 0x52, 0x45, 0x2d, 0x33, 0x2d, 0x35, 0x36, 0x2d, 0x67, 0x64 - , 0x64, 0x31, 0x35, 0x33, 0x63, 0x38, 0x2d, 0x6d, 0x6f, 0x64, 0x64, 0x65, 0x64, 0x00, 0x00, 0x40 - , 0x00, 0x00, 0x8a, 0x22, 0x55, 0xdf, 0xb2, 0x60, 0x17, 0x53, 0x79, 0x01, 0x02, 0x3a, 0x2b, 0xe5 - , 0x81, 0x83, 0xa3, 0x1a, 0x49, 0x93, 0x89, 0x8d, 0xac, 0xa7, 0xb2, 0x2e, 0xc3, 0x94, 0x6c, 0xd1 - , 0xd6, 0xd0, 0x82, 0x34, 0xf3, 0x9c, 0x71, 0xa0, 0xd1, 0xdb, 0x3f, 0xcc, 0xfc, 0x53, 0xce, 0x8c - , 0x84, 0x3d, 0x14, 0x2c, 0x81, 0x4a, 0x07, 0xf0, 0x00, 0x03, 0x7a, 0x28, 0x10, 0xf4, 0xb9, 0x50 - , 0xb3, 0x22, 0x00, 0xdf, 0xc2, 0xc7, 0xfb, 0x6f, 0xf3, 0xfb, 0xf6, 0x94, 0x8e, 0x06, 0x22, 0x6e - , 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f - , 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67 - , 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x79, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00 - , 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x01, 0xbc, 0x4d, 0x34, 0xb9, 0xcd, 0x00, 0x00, 0x00 - , 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b - , 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91 - , 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59 - , 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22 - , 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x02, 0x66, 0xe4, 0x59, 0x8d, 0x1d - , 0x3c, 0x41, 0x5f, 0x57, 0x2a, 0x84, 0x88, 0x83, 0x0b, 0x60, 0xf7, 0xe7, 0x44, 0xed, 0x92, 0x35 - , 0xeb, 0x0b, 0x1b, 0xa9, 0x32, 0x83, 0xb3, 0x15, 0xc0, 0x35, 0x18, 0x03, 0x1b, 0x84, 0xc5, 0x56 - , 0x7b, 0x12, 0x64, 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34 - , 0x60, 0x48, 0x19, 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x03, 0x1b, 0x84, 0xc5 - , 0x56, 0x7b, 0x12, 0x64, 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18 - , 0x34, 0x60, 0x48, 0x19, 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x80, 0x00, 0x00 - , 0x8e, 0xf4, 0xbc, 0x2c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x7a - , 0x2a, 0x3b, 0xad, 0x69, 0xf3, 0x8b, 0xba, 0xd2, 0xd3, 0xa2, 0x99, 0x66, 0x5f, 0x2d, 0x14, 0xc2 - , 0xca, 0xc2, 0xf4, 0x84, 0x97, 0x21, 0x93, 0x2f, 0xfd, 0x44, 0x19, 0xf6, 0xfa, 0x7f, 0x21, 0x3c - , 0x61, 0x45, 0x1e, 0x67, 0xfd, 0x5f, 0x9e, 0xee, 0x35, 0x03, 0xda, 0x96, 0xc3, 0x37, 0x2b, 0xfd - , 0x99, 0xb4, 0xdb, 0x0b, 0x6e, 0xa3, 0xdc, 0x8e, 0xad, 0x64, 0xf5, 0x9a, 0x4f, 0x5f, 0xae, 0x06 - , 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28 - , 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00 - , 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x60, 0x17, 0x53, 0x7a, 0x01, 0x00, 0x00, 0x06, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00 - , 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x80, 0x00, 0x00, 0x8e, 0xc3, 0xd8, 0xfd, 0x83, 0x00 - , 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x17, 0xdf, 0xc0, 0xb6, 0x5f, 0x8f, 0x42 - , 0x50, 0xe1, 0x4d, 0x35, 0xe7, 0x57, 0x2a, 0x07, 0x66, 0x8e, 0xa9, 0xe2, 0x61, 0xbf, 0xbc, 0x91 - , 0x5c, 0xa1, 0x80, 0x43, 0xcf, 0xb2, 0xba, 0x40, 0xf6, 0x2f, 0x0d, 0x37, 0x2c, 0xbc, 0x90, 0x96 - , 0x71, 0x00, 0x79, 0x35, 0xe3, 0xe8, 0x94, 0x90, 0x3c, 0x23, 0x8f, 0x5b, 0x8e, 0xcc, 0x39, 0x82 - , 0x2e, 0xdf, 0xbc, 0xcb, 0x66, 0xe9, 0xe4, 0x3e, 0xad, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00 - , 0x01, 0x60, 0x17, 0x53, 0x7a, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x40, 0x00, 0x00, 0x8a, 0x62, 0xdd, 0xe7, 0xfd, 0x60, 0x17, 0x53, 0x7b, 0x01, 0x02, 0x0b - , 0x5d, 0x1b, 0x41, 0x29, 0x50, 0xe7, 0x79, 0x39, 0x76, 0xc2, 0xd0, 0xbd, 0x54, 0x2c, 0x1c, 0x2b - , 0x78, 0x25, 0x8b, 0xd6, 0x2d, 0x70, 0x09, 0x73, 0xb7, 0x1c, 0xe4, 0xa2, 0x88, 0x98, 0xb6, 0x44 - , 0xa5, 0x33, 0x0a, 0x98, 0xdc, 0x63, 0xd1, 0x7b, 0x99, 0x49, 0xf2, 0x29, 0xe6, 0x6f, 0x58, 0xc6 - , 0xcb, 0x5a, 0x74, 0xa0, 0xdf, 0xa7, 0x74, 0x84, 0xd5, 0xe1, 0x0f, 0x03, 0x7d, 0xb6, 0xcd, 0x06 - , 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28 - , 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00 - , 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x7b, 0x01, 0x01, 0x00, 0x06, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00 - , 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x00, 0x8e, 0x76, 0xce, 0x94, 0x8e, 0x00 - , 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x25, 0x9f, 0x23, 0x6a, 0xbd, 0x5b, 0x6a - , 0x6b, 0x0f, 0x77, 0xaa, 0xce, 0xe9, 0xe1, 0x6d, 0xe3, 0xfb, 0xcd, 0x10, 0xa6, 0x2b, 0xb6, 0x15 - , 0x0c, 0xdf, 0xa1, 0xde, 0x79, 0x82, 0x99, 0xb1, 0x83, 0x47, 0x44, 0xf7, 0x20, 0xbc, 0x49, 0x11 - , 0x59, 0x58, 0x25, 0x63, 0x76, 0x01, 0x69, 0x27, 0xdc, 0xb3, 0x6c, 0x68, 0xc8, 0x5f, 0xae, 0x13 - , 0xaa, 0x46, 0xcc, 0xe9, 0x68, 0x03, 0x2a, 0xd3, 0x21, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00 - , 0x01, 0x60, 0x17, 0x53, 0x7f, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x00, 0x00, 0x00, 0x8e, 0x4b, 0x8b, 0x0b, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00 - , 0x8a, 0x01, 0x02, 0x7b, 0xd9, 0xa5, 0xe6, 0xfb, 0x26, 0xe2, 0xe1, 0xcb, 0x9a, 0x68, 0xdf, 0x50 - , 0x6c, 0x14, 0xcb, 0x5a, 0x2d, 0x12, 0x40, 0x94, 0x5e, 0xa4, 0x2d, 0xe9, 0x2a, 0x29, 0x48, 0xd5 - , 0xd0, 0x2e, 0xd9, 0x0c, 0xdc, 0xba, 0xe2, 0x74, 0x6e, 0xfb, 0xca, 0x77, 0xea, 0xe9, 0xa2, 0xce - , 0x9a, 0xa8, 0x42, 0x09, 0xa3, 0xa3, 0xae, 0x0e, 0x0f, 0xcc, 0xd3, 0x93, 0xd5, 0xcc, 0x38, 0x76 - , 0xd3, 0x58, 0xcc, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x60, 0x17, 0x53, 0x7f, 0x01 - , 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00 - , 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80 + 0x0c,0x80,0x00,0x01,0xbc,0x09,0x8b,0x67,0xe6,0x00,0x00,0x00,0x00,0x10,0x08,0x00, + 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e, + 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, + 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67, + 0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7, + 0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1, + 0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10, + 0xe5,0x40,0x87,0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0, + 0x90,0xb3,0x9c,0x3a,0x5d,0x88,0x5d,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40, + 0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff, + 0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64, + 0x40,0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19, + 0xff,0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x00,0x00,0x01,0xb0,0x6e,0x30,0x94, + 0x60,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x33,0x57,0x33,0xf5,0x94,0x2d,0xf5,0xd9, + 0x50,0xeb,0x87,0x66,0xde,0xe3,0xa9,0xd6,0x62,0x69,0x22,0x84,0x4e,0xd6,0xae,0x7a, + 0x11,0x0d,0xd7,0xe7,0xed,0xc3,0x2e,0x3f,0x6f,0x3d,0x9a,0xc5,0xcd,0xea,0x23,0xce, + 0x25,0xbb,0x8d,0xbf,0x76,0x1f,0xd3,0xd5,0xfc,0x56,0xc0,0x5b,0x68,0x56,0x31,0x6d, + 0x12,0xe9,0xd3,0x2c,0xa0,0xf0,0x8c,0x69,0xca,0x03,0x06,0xfe,0x71,0x6e,0x7b,0x51, + 0x51,0x31,0x7d,0x64,0x40,0xb7,0x37,0x3d,0x9f,0xbc,0x64,0x6e,0xad,0x48,0xf2,0x16, + 0x3f,0x2b,0x6d,0x51,0x1a,0xfe,0x6a,0x79,0xc7,0x55,0x51,0xc2,0x62,0x0f,0xc8,0x09, + 0x74,0xf2,0xf8,0x64,0x32,0x9d,0x97,0x78,0xa0,0x8c,0xdf,0xbc,0x9f,0x2c,0x9c,0x13, + 0x44,0xc4,0x32,0x70,0x2c,0x66,0x80,0x7c,0xfb,0x4d,0xb6,0x9b,0x80,0xfa,0xe8,0xc3, + 0x3c,0x70,0x14,0x3d,0x94,0x8b,0x36,0x61,0x4d,0x62,0x08,0x91,0xbe,0xe2,0xdf,0x99, + 0xc8,0x6b,0xc6,0x22,0x07,0xc1,0x7e,0x3b,0x91,0x86,0x21,0x4c,0x0c,0xcf,0xf2,0xde, + 0xd5,0x59,0x8a,0xcc,0xc9,0x0e,0xb1,0xd5,0xb2,0xf7,0xa8,0x3c,0xd7,0xf6,0x8d,0x71, + 0x2e,0xa0,0x47,0xd8,0x01,0x9f,0x34,0x30,0x63,0xb0,0xa2,0x36,0x35,0x6a,0x38,0x71, + 0x46,0xf5,0x8f,0xa8,0x32,0xdd,0xc1,0x3c,0x47,0x14,0x52,0x2c,0xbb,0x50,0x3f,0x5f, + 0x3c,0xa8,0xfc,0xec,0x66,0x02,0xbe,0x24,0x38,0xad,0x3f,0x98,0xfa,0x0c,0xee,0xd5, + 0x8f,0xe3,0xa0,0x66,0xd3,0x85,0xfc,0xac,0xd9,0x8c,0x70,0x4b,0x2a,0x8e,0x98,0xa3, + 0xe2,0x0b,0xf7,0x6b,0x35,0xb7,0x36,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85, + 0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3, + 0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87,0x5d, + 0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c,0x3a, + 0x5d,0x88,0x5d,0x02,0x90,0x53,0x52,0x1d,0x6e,0xa7,0xa5,0x2c,0xdd,0x55,0xf7,0x33, + 0xd0,0xfb,0x2d,0x07,0x7c,0x03,0x73,0xb0,0x05,0x3b,0x5b,0x81,0x0d,0x92,0x72,0x44, + 0x06,0x1b,0x75,0x73,0x02,0xd6,0x06,0x3d,0x02,0x26,0x91,0xb2,0x49,0x0a,0xb4,0x54, + 0xde,0xe7,0x3a,0x57,0xc6,0xff,0x5d,0x30,0x83,0x52,0xb4,0x61,0xec,0xe6,0x9f,0x3c, + 0x28,0x4f,0x2c,0x24,0x12,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00, + 0x00,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x80,0x00,0x00,0x8a,0xc5, + 0x33,0xff,0x38,0x65,0x55,0xb3,0x60,0x01,0x02,0x2f,0xd9,0x23,0x60,0x1e,0x1c,0xa0, + 0xac,0xe5,0x06,0x8c,0xe4,0x8e,0x14,0xf3,0xcd,0x31,0x44,0x16,0xc4,0x0d,0x2e,0x14, + 0x8c,0xa1,0xc8,0x4f,0xa6,0xa8,0xe4,0x64,0x9b,0x45,0x79,0xd1,0xb5,0x2f,0x04,0x19, + 0x86,0xe5,0x5c,0x99,0x43,0xf1,0xd0,0xf3,0x6f,0x52,0xd6,0x88,0xf0,0x9b,0x9c,0x58, + 0x98,0x69,0x0d,0x4e,0x76,0x3e,0xbd,0x6e,0x95,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x00,0x00,0x00,0x95,0x97,0xd7,0xa4,0x39,0x65,0x55,0xb3,0x65,0x01,0x01,0x36, + 0x59,0x20,0x77,0x0e,0xf4,0x73,0x10,0xd7,0xb6,0x59,0x5a,0x7c,0xbe,0xd0,0x56,0x51, + 0x3d,0x97,0xbe,0x84,0xb7,0x02,0xb5,0x89,0x72,0xbd,0xb3,0x19,0x2a,0x54,0x5f,0x57, + 0x52,0x09,0x1d,0xff,0x0f,0xe6,0x70,0x1e,0x71,0x23,0xaa,0x3f,0x98,0x89,0x86,0x35, + 0x87,0xc2,0x66,0xd9,0x99,0xbd,0xa2,0x7e,0x16,0x12,0xd9,0x6b,0xc4,0xd3,0x0c,0x00, + 0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x65,0x02,0x2d,0x22,0x36, + 0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5, + 0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x2d,0x22, + 0x53,0x49,0x4c,0x45,0x4e,0x54,0x41,0x52,0x54,0x49,0x53,0x54,0x2d,0x31,0x2d,0x31, + 0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64, + 0x00,0x00,0x80,0x00,0x00,0x8a,0xd0,0xde,0x20,0xc6,0x65,0x55,0xb3,0x60,0x01,0x02, + 0x11,0xd6,0x4b,0xc5,0x88,0x33,0x4b,0x6c,0x1e,0x0c,0x4c,0x5c,0x65,0x69,0x35,0x66, + 0x45,0x80,0xbc,0x4b,0x56,0x3d,0x98,0x2c,0xb3,0x45,0xef,0x22,0x44,0x6e,0xca,0x6c, + 0x1f,0xe9,0x2a,0xf2,0x4a,0xe1,0x26,0xdb,0x15,0x6f,0x7e,0x3b,0xdd,0xd3,0x40,0x54, + 0xb2,0xc7,0x07,0xfe,0x67,0xb0,0xf3,0x35,0x56,0x25,0xc6,0x53,0xfd,0x54,0x56,0x5e, + 0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf, + 0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f, + 0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x60,0x01,0x01,0x00,0x06, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a, + 0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x95,0x87,0xf8,0x92,0xf3, + 0x65,0x55,0xb3,0x65,0x01,0x01,0x32,0x6c,0xde,0x4a,0xc5,0xe8,0xd4,0xa0,0xed,0xbc, + 0x2c,0x13,0x5e,0xb9,0x1e,0xc3,0xc3,0x86,0xcb,0x75,0xeb,0x6f,0xce,0xc5,0xc5,0x57, + 0x01,0x1c,0x9c,0xb7,0x32,0x17,0x01,0x10,0x8c,0xdd,0x04,0x31,0x78,0xae,0xb4,0x88, + 0x8d,0xf8,0xe8,0x35,0x90,0x69,0x91,0x84,0xd0,0x16,0xd8,0x44,0xbc,0xde,0x37,0xe8, + 0x4e,0x1a,0x95,0xb6,0xa6,0x73,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65, + 0x55,0xb3,0x65,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87, + 0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c, + 0x3a,0x5d,0x88,0x5d,0x03,0x5d,0x2b,0x48,0x4f,0x50,0x50,0x49,0x4e,0x47,0x46,0x49, + 0x52,0x45,0x2d,0x63,0x31,0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38, + 0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x8a,0xcb,0xd4,0xc7, + 0xa1,0x65,0x55,0xb3,0x65,0x01,0x02,0x1d,0x3f,0x42,0x7f,0x3d,0xdb,0x58,0x2b,0xcb, + 0x78,0x5d,0x24,0xf1,0x67,0xc6,0xc7,0xd8,0x6e,0x6c,0x5b,0xf8,0xfb,0x27,0x17,0x58, + 0xaa,0x7e,0x46,0x86,0x49,0x66,0x21,0x47,0x76,0xbd,0xf2,0x2d,0xae,0x29,0xf0,0x6f, + 0x17,0x6e,0xf2,0x7f,0x01,0xda,0x16,0xa9,0x1d,0x6a,0x61,0x4c,0x41,0x71,0x19,0x4d, + 0x37,0xac,0x8a,0x28,0xd8,0x62,0xfb,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca, + 0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7, + 0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65, + 0x55,0xb3,0x65,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80, + 0x00,0x01,0xbc,0x39,0xdb,0xc7,0xdf,0x00,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e,0x46,0x11, + 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44, + 0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e, + 0x3c,0xa3,0x1d,0x59,0x02,0x66,0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84, + 0x88,0x83,0x0b,0x60,0xf7,0xe7,0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83, + 0xb3,0x15,0xc0,0x35,0x18,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99,0x5d, + 0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c,0x17, + 0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99, + 0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c, + 0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x80,0x00,0x00,0x8e,0x85,0x67,0x9b,0xcf,0x00, + 0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x27,0x9e,0x4e,0x43,0x39,0xa6,0x92, + 0x19,0x35,0x50,0x19,0xbb,0x51,0x5b,0xf9,0xac,0xdb,0xda,0x9c,0xde,0x81,0x8b,0x56, + 0x2e,0x0a,0x3d,0xd5,0xb0,0x5f,0x10,0x2e,0x6c,0x22,0x55,0x7e,0x07,0xc2,0x5f,0x4b, + 0x9c,0xc1,0x21,0x6e,0x07,0x66,0x41,0x60,0xde,0x3e,0xe2,0x24,0xa5,0x9e,0xec,0xaf, + 0xd7,0xcc,0x3f,0x87,0x7c,0x32,0x29,0xca,0xe7,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6c,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0xca,0xa4,0x8e,0x70,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x4e,0x3f,0x3b,0x6d,0xda,0xcc,0xd3,0xef,0x5f,0xaf,0x26,0x76,0x16, + 0x64,0xa2,0x82,0x97,0xe8,0xb4,0xe4,0xb1,0x2d,0xec,0xa1,0x9e,0x91,0x69,0xd3,0xde, + 0xe9,0x58,0xc7,0x19,0x06,0x90,0x42,0x86,0x97,0xf3,0x88,0xca,0x35,0xd5,0xec,0x79, + 0x5e,0x59,0x33,0x31,0xf4,0x0c,0xdb,0x55,0x5d,0x78,0xd7,0x22,0x59,0xa2,0xe5,0x8d, + 0xeb,0x65,0x41,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x6c,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x8a,0xbf, + 0x0d,0x7a,0xbc,0x65,0x55,0xb3,0x6f,0x01,0x02,0x59,0xc9,0x36,0x84,0xaa,0x13,0x70, + 0x73,0x7d,0xa7,0xe6,0x8a,0x72,0x05,0x15,0xa9,0x06,0x69,0xe0,0xc0,0x0d,0x15,0x6d, + 0x22,0x5c,0xd6,0x1a,0x3e,0x56,0xaa,0x9d,0x98,0x68,0x5a,0x3c,0xdc,0x38,0x71,0xee, + 0x0d,0x02,0x3e,0x2f,0xd0,0x97,0xd7,0xab,0xe2,0x0d,0xdf,0xf5,0xa6,0xd1,0x9c,0xb6, + 0xb9,0x30,0xd6,0xdd,0x10,0xa7,0xa3,0xce,0x5e,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6f,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0x80,0x00,0x75,0xd3,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x26,0x62,0x25,0x68,0x2d,0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93, + 0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d,0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3, + 0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10,0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf, + 0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39,0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7, + 0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00, + 0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80,0x00,0x00,0x8e,0xdc, + 0x5e,0x38,0x7a,0x00,0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x5d,0xf9,0x14, + 0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7,0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b, + 0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc,0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73, + 0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd,0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e, + 0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30,0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e, + 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, + 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e, + 0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00, + 0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x01,0xb0,0xb8,0x17,0x71,0xe9,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x0d,0xef,0xc0,0x12,0x4f,0xd4,0xe4,0x1c,0xce,0xc3,0xf4,0x83,0x17, + 0x21,0x7e,0x33,0x11,0x5a,0x8f,0x8c,0x39,0xae,0xbb,0x06,0x2b,0x4e,0x73,0xa6,0x52, + 0xee,0x0e,0x61,0x03,0xf9,0xf1,0x16,0x7b,0x22,0xbd,0xcb,0x92,0xcf,0x82,0x2d,0x0f, + 0xcc,0x26,0xcb,0x11,0x9f,0x0a,0xf5,0x23,0xf4,0x26,0x97,0x86,0x7e,0x21,0x51,0x85, + 0x16,0x3a,0x0e,0x4b,0x1f,0x64,0xf3,0x62,0xf4,0x2f,0x13,0x54,0x5c,0x9a,0xed,0xd6, + 0x9d,0x5d,0xf5,0x17,0x85,0xcc,0x5d,0x53,0xa4,0x84,0x36,0x9b,0xe9,0xa7,0x4a,0x04, + 0x1f,0x8c,0x1c,0x28,0xc7,0x1e,0xab,0xb3,0xf2,0x53,0x3d,0xf8,0xb6,0xcd,0xd8,0x45, + 0x6e,0xc3,0x77,0xdb,0xb1,0x2b,0xa5,0xdd,0xc9,0xbf,0x69,0xa7,0xdf,0x98,0x2c,0x54, + 0xa7,0xa8,0xf5,0x4f,0xc3,0xd1,0x57,0x81,0x98,0x60,0xa0,0xb6,0x32,0x83,0x08,0x65, + 0x1e,0x79,0x24,0xf4,0xbe,0xfe,0x14,0xa6,0xfd,0x31,0x9b,0xfa,0x15,0x6f,0x1b,0xab, + 0x64,0x8b,0x69,0x48,0xb4,0x2e,0x99,0xca,0xd7,0x46,0x97,0x57,0x17,0x1d,0x5d,0x53, + 0xe5,0xde,0xae,0xbb,0x2d,0x74,0x86,0xa5,0xe5,0x8e,0x02,0x5c,0x2c,0x8d,0x0d,0x78, + 0xdc,0xf1,0xa0,0x05,0xb8,0xbd,0x64,0x7d,0x51,0x47,0x5e,0x39,0xaa,0x08,0x2d,0xf2, + 0xd0,0x1a,0x96,0x59,0xab,0x88,0x94,0xa2,0xf7,0x2e,0x09,0x3b,0xd0,0xed,0xfc,0xb4, + 0x1b,0xaa,0xba,0x34,0xf8,0x7b,0x11,0x51,0x36,0x7b,0x13,0x84,0x6f,0xc9,0x4a,0x58, + 0x92,0x3c,0x0c,0xa2,0x4c,0x8f,0xc5,0x78,0xb4,0x4a,0xad,0x98,0x08,0x4e,0x4a,0xf3, + 0x7a,0x28,0x80,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22, + 0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d, + 0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x03, + 0xbb,0xee,0x60,0xc3,0x95,0x05,0x6b,0x8a,0x12,0x01,0xe0,0x6e,0xd7,0x9e,0x29,0x14, + 0xc1,0x1a,0x61,0xd7,0xb1,0xaa,0x78,0x18,0x46,0x46,0x8d,0x02,0x48,0x9d,0xba,0x69, + 0x02,0x32,0x42,0x66,0xde,0x84,0x03,0xb3,0xab,0x15,0x7a,0x09,0xf1,0xf7,0x84,0xd5, + 0x87,0xaf,0x61,0x83,0x1c,0x99,0x8c,0x15,0x1b,0xcc,0x21,0xbb,0x74,0xc2,0xb2,0x31, + 0x4b,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00,0x00,0x10,0x05,0x00, + 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x00,0x00,0x00,0x8a,0xe1,0x31,0x6b,0x76,0x65, + 0x55,0xb3,0x71,0x01,0x02,0x5d,0xf9,0x14,0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7, + 0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b,0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc, + 0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73,0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd, + 0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e,0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30, + 0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00, + 0x8a,0xbd,0x6f,0x26,0xdf,0x65,0x55,0xb3,0x71,0x01,0x02,0x26,0x62,0x25,0x68,0x2d, + 0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93,0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d, + 0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3,0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10, + 0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf,0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39, + 0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7,0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11, + 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b, + 0x02,0x33,0x80,0x00,0x00,0x00,0x95,0xf6,0xd7,0x24,0x69,0x65,0x55,0xb3,0x79,0x01, + 0x01,0x42,0x62,0x2b,0xf0,0x0a,0x44,0xc3,0xe0,0x78,0x3c,0xa7,0x08,0x5a,0xa0,0xaa, + 0x9d,0xb2,0xdc,0x2e,0xa7,0x29,0x0a,0x39,0x3d,0x01,0x57,0xbf,0x34,0x23,0x0f,0xb9, + 0x19,0x33,0x6f,0xc2,0xfb,0x9f,0x25,0xac,0xc4,0xc9,0x47,0xb7,0x41,0x92,0xdb,0x2f, + 0xd5,0xf0,0x1f,0x24,0x32,0xdf,0x38,0x30,0x89,0x93,0xeb,0xc9,0xec,0xf1,0x09,0x51, + 0xbb,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x79,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x02, + 0x66,0xe4,0x4a,0x55,0x4e,0x49,0x4f,0x52,0x42,0x45,0x41,0x4d,0x2d,0x72,0x63,0x31, + 0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64, + 0x65,0x64,0x00,0x00, }; static void check_cannounce(const u8 *cannounce, @@ -319,11 +356,11 @@ int main(int argc, char *argv[]) assert(gossmap_find_node(map, &l3)); assert(short_channel_id_from_str("103x1x0", 7, &scid23)); - assert(short_channel_id_from_str("110x1x1", 7, &scid12)); + assert(short_channel_id_from_str("110x1x0", 7, &scid12)); assert(gossmap_find_chan(map, &scid23)); assert(!gossmap_find_chan(map, &scid23)->private); assert(gossmap_find_chan(map, &scid12)); - assert(gossmap_find_chan(map, &scid12)->private); + assert(!gossmap_find_chan(map, &scid12)->private); assert(gossmap_chan_get_capacity(map, gossmap_find_chan(map, &scid23), &capacity)); assert(amount_sat_eq(capacity, AMOUNT_SAT(1000000))); @@ -340,7 +377,7 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1612141433); + assert(timestamp == 1700115301); assert(message_flags == 1); assert(channel_flags == 0); assert(fee_base_msat == 20); @@ -357,7 +394,7 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1612141435); + assert(timestamp == 1700115311); assert(message_flags == 1); assert(channel_flags == 1); assert(fee_base_msat == 20); @@ -374,7 +411,7 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1612141439); + assert(timestamp == 1700115313); assert(message_flags == 1); assert(channel_flags == 0); assert(fee_base_msat == 20); @@ -391,7 +428,7 @@ int main(int argc, char *argv[]) &fee_proportional_millionths, &htlc_minimum_msat, &htlc_maximum_msat); - assert(timestamp == 1612141439); + assert(timestamp == 1700115313); assert(message_flags == 1); assert(channel_flags == 1); assert(fee_base_msat == 20); @@ -413,7 +450,7 @@ int main(int argc, char *argv[]) nann = gossmap_node_get_announce(tmpctx, map, gossmap_find_node(map, &l1)); - assert(!nann); + assert(nann); nann = gossmap_node_get_announce(tmpctx, map, gossmap_find_node(map, &l2)); check_nannounce(nann, &l2); diff --git a/plugins/renepay/test/run-mcf.c b/plugins/renepay/test/run-mcf.c index f7d698f8425e..bfbb0a6f3358 100644 --- a/plugins/renepay/test/run-mcf.c +++ b/plugins/renepay/test/run-mcf.c @@ -34,214 +34,251 @@ static void swap(int *a, int *b) *b = temp; } -/* Canned gossmap, taken from tests/test_gossip.py's - * setup_gossip_store_test via od -v -Anone -tx1 < /tmp/ltests-kaf30pn0/test_gossip_store_compact_noappend_1/lightning-2/regtest/gossip_store +/* Canned gossmap, taken from tests/test_gossip.py, with channels mined. + * $> od -tx1 -Anone -v < /tmp/ltests-rtchpzh1/test_gossip_store_compact_noappend_1/lightning-2/regtest/gossip_store | sed 's/ / 0x/g'| cut -c2- | sed -e 's/ /,/g' -e 's/$/,/' */ static u8 canned_map[] = { - 0x09, 0x80, 0x00, 0x01, 0xbc, 0x09, 0x8b, 0x67, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x22, 0x6e - , 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f - , 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67 - , 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7 - , 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1 - , 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x03, 0x5d, 0x2b, 0x11, 0x92, 0xdf, 0xba, 0x13, 0x4e, 0x10 - , 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53, 0xd5, 0xaa, 0x76, 0x6b, 0x80, 0xc0 - , 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x03, 0x1b, 0x84, 0xc5, 0x56, 0x7b, 0x12, 0x64, 0x40 - , 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34, 0x60, 0x48, 0x19, 0xff - , 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x03, 0x1b, 0x84, 0xc5, 0x56, 0x7b, 0x12, 0x64 - , 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34, 0x60, 0x48, 0x19 - , 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x80, 0x00, 0x00, 0x8e, 0x33, 0x3b, 0x90 - , 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x14, 0xb8, 0x21, 0x42, 0x7d - , 0x40, 0x89, 0x60, 0x71, 0x05, 0x8d, 0xe4, 0x50, 0x8e, 0xc3, 0x87, 0x6f, 0xa6, 0x4b, 0x19, 0xe4 - , 0x81, 0xc5, 0x5f, 0xb7, 0x04, 0xb8, 0x74, 0x08, 0x0b, 0x40, 0x5a, 0x74, 0x89, 0xbc, 0x63, 0x24 - , 0x27, 0x93, 0x4d, 0xfc, 0x1a, 0x72, 0xe4, 0xc7, 0xf8, 0x9b, 0xc1, 0x6b, 0xad, 0x9b, 0x04, 0x2e - , 0x14, 0xa4, 0xe9, 0xf5, 0x80, 0xf1, 0x02, 0x8f, 0x50, 0xf3, 0x2c, 0x06, 0x22, 0x6e, 0x46, 0x11 - , 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e - , 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x70, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b - , 0x02, 0x33, 0x80, 0x80, 0x00, 0x00, 0x8e, 0x3e, 0xa2, 0x81, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10 - , 0x06, 0x00, 0x8a, 0x01, 0x02, 0x01, 0x0a, 0xb3, 0x54, 0x3f, 0xd2, 0xa9, 0xf5, 0x30, 0x0f, 0x60 - , 0x7d, 0xf9, 0xf1, 0xdd, 0x63, 0x62, 0xd8, 0xde, 0xe2, 0x94, 0xe4, 0x68, 0xc9, 0x5c, 0xe8, 0x32 - , 0x9b, 0x14, 0xd9, 0xf8, 0x6a, 0x23, 0x3a, 0x67, 0x10, 0x09, 0x64, 0x96, 0x40, 0xcb, 0x0b, 0xf5 - , 0xec, 0xe6, 0xba, 0x8e, 0x77, 0xb4, 0x6a, 0xf1, 0x39, 0x94, 0x86, 0xb0, 0x69, 0xd5, 0x17, 0x67 - , 0x83, 0xda, 0xfa, 0x49, 0x63, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12 - , 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7 - , 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53 - , 0x70, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x00 - , 0x0a, 0x01, 0xf0, 0xcb, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x07, 0x00, 0x00, 0x67, 0x00, 0x00 - , 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0xb0, 0xd2, 0xfa, 0x8f, 0x8d, 0x60, 0x17, 0x53, 0x70, 0x01 - , 0x00, 0x24, 0xfd, 0xae, 0x1a, 0xc8, 0x40, 0xa7, 0x33, 0x22, 0xe1, 0x45, 0x7e, 0x76, 0xb8, 0x86 - , 0xdd, 0x17, 0x8c, 0xd4, 0x49, 0x4b, 0x14, 0x3f, 0x81, 0xd4, 0xd4, 0xfa, 0xa7, 0x16, 0x17, 0xd2 - , 0x51, 0x33, 0x9e, 0xcb, 0x0e, 0x22, 0x1c, 0xf6, 0x02, 0x3a, 0x2e, 0x3e, 0x94, 0xf8, 0xae, 0xdb - , 0xee, 0x47, 0x23, 0xda, 0x5c, 0x35, 0x51, 0x57, 0xd8, 0xe4, 0x67, 0x2b, 0x46, 0x82, 0x5e, 0xc7 - , 0x98, 0x51, 0xb3, 0xb0, 0x1a, 0x2c, 0x72, 0x3f, 0x9b, 0xf5, 0xdb, 0xa8, 0xe3, 0x5f, 0x8b, 0x47 - , 0x9d, 0x9c, 0xd9, 0x73, 0xae, 0xc5, 0x0c, 0xca, 0x08, 0xfb, 0x97, 0x57, 0xb5, 0x21, 0x92, 0x05 - , 0x18, 0x42, 0x2d, 0x68, 0x19, 0x70, 0x76, 0x30, 0x61, 0x24, 0xff, 0xa5, 0xb6, 0x58, 0xa2, 0xe2 - , 0xb3, 0x68, 0x93, 0x37, 0xda, 0x6c, 0x3c, 0xcc, 0x5e, 0xf7, 0x3b, 0x51, 0x29, 0x64, 0x30, 0xbe - , 0x2a, 0x19, 0x38, 0x88, 0x9d, 0xda, 0x2a, 0xd1, 0xcb, 0x5e, 0x33, 0xdb, 0x75, 0xcf, 0x2e, 0x0e - , 0xfd, 0xbd, 0x38, 0xce, 0x01, 0x54, 0x62, 0x30, 0xb4, 0xdd, 0xdc, 0x7f, 0x67, 0xca, 0xf8, 0x39 - , 0x10, 0x02, 0x8a, 0x05, 0x3b, 0x76, 0x62, 0x72, 0xd2, 0x84, 0x71, 0x19, 0x19, 0x30, 0x92, 0xfa - , 0x2a, 0x1f, 0xdf, 0x71, 0xe3, 0xd8, 0x4a, 0x56, 0xd0, 0xe4, 0x35, 0xfe, 0x5d, 0x4a, 0x5b, 0x5b - , 0x90, 0x05, 0x28, 0xe4, 0x3b, 0x24, 0x13, 0x46, 0x99, 0x45, 0xc4, 0x92, 0x14, 0x7d, 0x43, 0x21 - , 0x06, 0x50, 0x51, 0xf8, 0x5b, 0x92, 0xb5, 0xb0, 0x90, 0xb1, 0xd7, 0x0d, 0x5a, 0xac, 0xfe, 0xf4 - , 0xe2, 0x70, 0x3e, 0x97, 0x42, 0x25, 0xfb, 0x21, 0x15, 0xf6, 0xb9, 0x32, 0xc8, 0xc3, 0x03, 0xbd - , 0x7a, 0xbd, 0x86, 0xf7, 0xcd, 0x64, 0xe6, 0x1a, 0x7f, 0x5a, 0x04, 0x7a, 0x22, 0xad, 0x7c, 0xfc - , 0x6a, 0x00, 0x00, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x2d, 0x22, 0x36, 0x20 - , 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33 - , 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x03, 0x5d, 0x2b, 0x11 - , 0x92, 0xdf, 0xba, 0x13, 0x4e, 0x10, 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53 - , 0xd5, 0xaa, 0x76, 0x6b, 0x80, 0xc0, 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x02, 0xd5, 0x95 - , 0xae, 0x92, 0xb3, 0x54, 0x4c, 0x32, 0x50, 0xfb, 0x77, 0x2f, 0x21, 0x4a, 0xd8, 0xd4, 0xc5, 0x14 - , 0x25, 0x03, 0x37, 0x40, 0xa5, 0xbc, 0xc3, 0x57, 0x19, 0x0a, 0xdd, 0x6d, 0x7e, 0x7a, 0x02, 0xd6 - , 0x06, 0x3d, 0x02, 0x26, 0x91, 0xb2, 0x49, 0x0a, 0xb4, 0x54, 0xde, 0xe7, 0x3a, 0x57, 0xc6, 0xff - , 0x5d, 0x30, 0x83, 0x52, 0xb4, 0x61, 0xec, 0xe6, 0x9f, 0x3c, 0x28, 0x4f, 0x2c, 0x24, 0x12, 0x00 - , 0x00, 0x00, 0x0a, 0x91, 0x11, 0x83, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x0f, 0x42, 0x40, 0xc0, 0x00, 0x00, 0x8a, 0xf3, 0x48, 0xd5, 0xb3, 0x60, 0x17, 0x53 - , 0x70, 0x01, 0x02, 0x14, 0xb8, 0x21, 0x42, 0x7d, 0x40, 0x89, 0x60, 0x71, 0x05, 0x8d, 0xe4, 0x50 - , 0x8e, 0xc3, 0x87, 0x6f, 0xa6, 0x4b, 0x19, 0xe4, 0x81, 0xc5, 0x5f, 0xb7, 0x04, 0xb8, 0x74, 0x08 - , 0x0b, 0x40, 0x5a, 0x74, 0x89, 0xbc, 0x63, 0x24, 0x27, 0x93, 0x4d, 0xfc, 0x1a, 0x72, 0xe4, 0xc7 - , 0xf8, 0x9b, 0xc1, 0x6b, 0xad, 0x9b, 0x04, 0x2e, 0x14, 0xa4, 0xe9, 0xf5, 0x80, 0xf1, 0x02, 0x8f - , 0x50, 0xf3, 0x2c, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x70, 0x01 - , 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 - , 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0xc0, 0x00, 0x00, 0x8a, 0xfe - , 0xd1, 0xc4, 0x47, 0x60, 0x17, 0x53, 0x70, 0x01, 0x02, 0x01, 0x0a, 0xb3, 0x54, 0x3f, 0xd2, 0xa9 - , 0xf5, 0x30, 0x0f, 0x60, 0x7d, 0xf9, 0xf1, 0xdd, 0x63, 0x62, 0xd8, 0xde, 0xe2, 0x94, 0xe4, 0x68 - , 0xc9, 0x5c, 0xe8, 0x32, 0x9b, 0x14, 0xd9, 0xf8, 0x6a, 0x23, 0x3a, 0x67, 0x10, 0x09, 0x64, 0x96 - , 0x40, 0xcb, 0x0b, 0xf5, 0xec, 0xe6, 0xba, 0x8e, 0x77, 0xb4, 0x6a, 0xf1, 0x39, 0x94, 0x86, 0xb0 - , 0x69, 0xd5, 0x17, 0x67, 0x83, 0xda, 0xfa, 0x49, 0x63, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67, 0x00, 0x00, 0x01, 0x00 - , 0x00, 0x60, 0x17, 0x53, 0x70, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x40, 0x00, 0x00, 0x9b, 0x4f, 0x9d, 0xb7, 0xb9, 0x60, 0x17, 0x53, 0x77, 0x01, 0x01, 0x6e - , 0x99, 0xf5, 0x9c, 0x1f, 0x21, 0x8d, 0x4a, 0x2b, 0x6e, 0x36, 0x9a, 0x95, 0x20, 0x76, 0x2c, 0x27 - , 0xfb, 0xa8, 0xb1, 0x82, 0x1f, 0x64, 0x34, 0x93, 0x91, 0x9c, 0xeb, 0xfa, 0x40, 0x50, 0x73, 0x4d - , 0x00, 0xce, 0x10, 0xbf, 0x3f, 0x42, 0x3e, 0x56, 0x8f, 0xf8, 0xe0, 0x59, 0x58, 0xb5, 0xbd, 0xc5 - , 0x00, 0x82, 0xe3, 0x27, 0x92, 0x5b, 0xf8, 0x4f, 0x2c, 0x39, 0xec, 0x49, 0x3b, 0x07, 0x5e, 0x00 - , 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x22, 0xaa, 0xa2, 0x60, 0x17 - , 0x53, 0x77, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59, 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c - , 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22, 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c - , 0xa3, 0x1d, 0x59, 0x02, 0x2d, 0x22, 0x53, 0x49, 0x4c, 0x45, 0x4e, 0x54, 0x41, 0x52, 0x54, 0x49 - , 0x53, 0x54, 0x2d, 0x2d, 0x35, 0x36, 0x2d, 0x67, 0x64, 0x64, 0x31, 0x35, 0x33, 0x63, 0x38, 0x2d - , 0x6d, 0x6f, 0x64, 0x64, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x15, 0x33, 0x0c, 0x6b - , 0x60, 0x17, 0x53, 0x77, 0x01, 0x01, 0x0e, 0x07, 0xaf, 0xd2, 0x33, 0x19, 0x0e, 0x06, 0x01, 0x6d - , 0x57, 0x88, 0x4e, 0x66, 0xf8, 0x08, 0xd9, 0x65, 0x8a, 0x73, 0xfb, 0x1d, 0xe0, 0xad, 0xee, 0x47 - , 0xf8, 0x1c, 0xfc, 0xc3, 0xd2, 0xfd, 0x06, 0x3e, 0x5a, 0x05, 0x65, 0x72, 0x18, 0x61, 0xb8, 0x23 - , 0x04, 0x3d, 0x4b, 0x39, 0x79, 0xe0, 0x85, 0x38, 0xd2, 0x92, 0x14, 0x35, 0x32, 0xaa, 0x9f, 0xab - , 0x5f, 0x98, 0x2c, 0x53, 0xfe, 0x0d, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 - , 0x00, 0x00, 0x22, 0xaa, 0xa2, 0x60, 0x17, 0x53, 0x77, 0x03, 0x5d, 0x2b, 0x11, 0x92, 0xdf, 0xba - , 0x13, 0x4e, 0x10, 0xe5, 0x40, 0x87, 0x5d, 0x36, 0x6e, 0xbc, 0x8b, 0xc3, 0x53, 0xd5, 0xaa, 0x76 - , 0x6b, 0x80, 0xc0, 0x90, 0xb3, 0x9c, 0x3a, 0x5d, 0x88, 0x5d, 0x03, 0x5d, 0x2b, 0x48, 0x4f, 0x50 - , 0x50, 0x49, 0x4e, 0x47, 0x46, 0x49, 0x52, 0x45, 0x2d, 0x33, 0x2d, 0x35, 0x36, 0x2d, 0x67, 0x64 - , 0x64, 0x31, 0x35, 0x33, 0x63, 0x38, 0x2d, 0x6d, 0x6f, 0x64, 0x64, 0x65, 0x64, 0x00, 0x00, 0x40 - , 0x00, 0x00, 0x8a, 0x22, 0x55, 0xdf, 0xb2, 0x60, 0x17, 0x53, 0x79, 0x01, 0x02, 0x3a, 0x2b, 0xe5 - , 0x81, 0x83, 0xa3, 0x1a, 0x49, 0x93, 0x89, 0x8d, 0xac, 0xa7, 0xb2, 0x2e, 0xc3, 0x94, 0x6c, 0xd1 - , 0xd6, 0xd0, 0x82, 0x34, 0xf3, 0x9c, 0x71, 0xa0, 0xd1, 0xdb, 0x3f, 0xcc, 0xfc, 0x53, 0xce, 0x8c - , 0x84, 0x3d, 0x14, 0x2c, 0x81, 0x4a, 0x07, 0xf0, 0x00, 0x03, 0x7a, 0x28, 0x10, 0xf4, 0xb9, 0x50 - , 0xb3, 0x22, 0x00, 0xdf, 0xc2, 0xc7, 0xfb, 0x6f, 0xf3, 0xfb, 0xf6, 0x94, 0x8e, 0x06, 0x22, 0x6e - , 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f - , 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x67 - , 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x79, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00 - , 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x01, 0xbc, 0x4d, 0x34, 0xb9, 0xcd, 0x00, 0x00, 0x00 - , 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x42, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b - , 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91 - , 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x2d, 0x22, 0x36, 0x20, 0xa3, 0x59 - , 0xa4, 0x7f, 0xf7, 0xf7, 0xac, 0x44, 0x7c, 0x85, 0xc4, 0x6c, 0x92, 0x3d, 0xa5, 0x33, 0x89, 0x22 - , 0x1a, 0x00, 0x54, 0xc1, 0x1c, 0x1e, 0x3c, 0xa3, 0x1d, 0x59, 0x02, 0x66, 0xe4, 0x59, 0x8d, 0x1d - , 0x3c, 0x41, 0x5f, 0x57, 0x2a, 0x84, 0x88, 0x83, 0x0b, 0x60, 0xf7, 0xe7, 0x44, 0xed, 0x92, 0x35 - , 0xeb, 0x0b, 0x1b, 0xa9, 0x32, 0x83, 0xb3, 0x15, 0xc0, 0x35, 0x18, 0x03, 0x1b, 0x84, 0xc5, 0x56 - , 0x7b, 0x12, 0x64, 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18, 0x34 - , 0x60, 0x48, 0x19, 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x03, 0x1b, 0x84, 0xc5 - , 0x56, 0x7b, 0x12, 0x64, 0x40, 0x99, 0x5d, 0x3e, 0xd5, 0xaa, 0xba, 0x05, 0x65, 0xd7, 0x1e, 0x18 - , 0x34, 0x60, 0x48, 0x19, 0xff, 0x9c, 0x17, 0xf5, 0xe9, 0xd5, 0xdd, 0x07, 0x8f, 0x80, 0x00, 0x00 - , 0x8e, 0xf4, 0xbc, 0x2c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x7a - , 0x2a, 0x3b, 0xad, 0x69, 0xf3, 0x8b, 0xba, 0xd2, 0xd3, 0xa2, 0x99, 0x66, 0x5f, 0x2d, 0x14, 0xc2 - , 0xca, 0xc2, 0xf4, 0x84, 0x97, 0x21, 0x93, 0x2f, 0xfd, 0x44, 0x19, 0xf6, 0xfa, 0x7f, 0x21, 0x3c - , 0x61, 0x45, 0x1e, 0x67, 0xfd, 0x5f, 0x9e, 0xee, 0x35, 0x03, 0xda, 0x96, 0xc3, 0x37, 0x2b, 0xfd - , 0x99, 0xb4, 0xdb, 0x0b, 0x6e, 0xa3, 0xdc, 0x8e, 0xad, 0x64, 0xf5, 0x9a, 0x4f, 0x5f, 0xae, 0x06 - , 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28 - , 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00 - , 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x60, 0x17, 0x53, 0x7a, 0x01, 0x00, 0x00, 0x06, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00 - , 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x80, 0x00, 0x00, 0x8e, 0xc3, 0xd8, 0xfd, 0x83, 0x00 - , 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x17, 0xdf, 0xc0, 0xb6, 0x5f, 0x8f, 0x42 - , 0x50, 0xe1, 0x4d, 0x35, 0xe7, 0x57, 0x2a, 0x07, 0x66, 0x8e, 0xa9, 0xe2, 0x61, 0xbf, 0xbc, 0x91 - , 0x5c, 0xa1, 0x80, 0x43, 0xcf, 0xb2, 0xba, 0x40, 0xf6, 0x2f, 0x0d, 0x37, 0x2c, 0xbc, 0x90, 0x96 - , 0x71, 0x00, 0x79, 0x35, 0xe3, 0xe8, 0x94, 0x90, 0x3c, 0x23, 0x8f, 0x5b, 0x8e, 0xcc, 0x39, 0x82 - , 0x2e, 0xdf, 0xbc, 0xcb, 0x66, 0xe9, 0xe4, 0x3e, 0xad, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00 - , 0x01, 0x60, 0x17, 0x53, 0x7a, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x40, 0x00, 0x00, 0x8a, 0x62, 0xdd, 0xe7, 0xfd, 0x60, 0x17, 0x53, 0x7b, 0x01, 0x02, 0x0b - , 0x5d, 0x1b, 0x41, 0x29, 0x50, 0xe7, 0x79, 0x39, 0x76, 0xc2, 0xd0, 0xbd, 0x54, 0x2c, 0x1c, 0x2b - , 0x78, 0x25, 0x8b, 0xd6, 0x2d, 0x70, 0x09, 0x73, 0xb7, 0x1c, 0xe4, 0xa2, 0x88, 0x98, 0xb6, 0x44 - , 0xa5, 0x33, 0x0a, 0x98, 0xdc, 0x63, 0xd1, 0x7b, 0x99, 0x49, 0xf2, 0x29, 0xe6, 0x6f, 0x58, 0xc6 - , 0xcb, 0x5a, 0x74, 0xa0, 0xdf, 0xa7, 0x74, 0x84, 0xd5, 0xe1, 0x0f, 0x03, 0x7d, 0xb6, 0xcd, 0x06 - , 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28 - , 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00 - , 0x00, 0x67, 0x00, 0x00, 0x01, 0x00, 0x00, 0x60, 0x17, 0x53, 0x7b, 0x01, 0x01, 0x00, 0x06, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00 - , 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80, 0x00, 0x00, 0x00, 0x8e, 0x76, 0xce, 0x94, 0x8e, 0x00 - , 0x00, 0x00, 0x00, 0x10, 0x06, 0x00, 0x8a, 0x01, 0x02, 0x25, 0x9f, 0x23, 0x6a, 0xbd, 0x5b, 0x6a - , 0x6b, 0x0f, 0x77, 0xaa, 0xce, 0xe9, 0xe1, 0x6d, 0xe3, 0xfb, 0xcd, 0x10, 0xa6, 0x2b, 0xb6, 0x15 - , 0x0c, 0xdf, 0xa1, 0xde, 0x79, 0x82, 0x99, 0xb1, 0x83, 0x47, 0x44, 0xf7, 0x20, 0xbc, 0x49, 0x11 - , 0x59, 0x58, 0x25, 0x63, 0x76, 0x01, 0x69, 0x27, 0xdc, 0xb3, 0x6c, 0x68, 0xc8, 0x5f, 0xae, 0x13 - , 0xaa, 0x46, 0xcc, 0xe9, 0x68, 0x03, 0x2a, 0xd3, 0x21, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b - , 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a - , 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00 - , 0x01, 0x60, 0x17, 0x53, 0x7f, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - , 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33 - , 0x80, 0x00, 0x00, 0x00, 0x8e, 0x4b, 0x8b, 0x0b, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06, 0x00 - , 0x8a, 0x01, 0x02, 0x7b, 0xd9, 0xa5, 0xe6, 0xfb, 0x26, 0xe2, 0xe1, 0xcb, 0x9a, 0x68, 0xdf, 0x50 - , 0x6c, 0x14, 0xcb, 0x5a, 0x2d, 0x12, 0x40, 0x94, 0x5e, 0xa4, 0x2d, 0xe9, 0x2a, 0x29, 0x48, 0xd5 - , 0xd0, 0x2e, 0xd9, 0x0c, 0xdc, 0xba, 0xe2, 0x74, 0x6e, 0xfb, 0xca, 0x77, 0xea, 0xe9, 0xa2, 0xce - , 0x9a, 0xa8, 0x42, 0x09, 0xa3, 0xa3, 0xae, 0x0e, 0x0f, 0xcc, 0xd3, 0x93, 0xd5, 0xcc, 0x38, 0x76 - , 0xd3, 0x58, 0xcc, 0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59, 0xca, 0xaf, 0x12, 0x60, 0x43 - , 0xeb, 0x5b, 0xbf, 0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f, 0xc7, 0xb2, 0xb7, 0x3c, 0xf1 - , 0x88, 0x91, 0x0f, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x01, 0x60, 0x17, 0x53, 0x7f, 0x01 - , 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00 - , 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x02, 0x33, 0x80 + 0x0c,0x80,0x00,0x01,0xbc,0x09,0x8b,0x67,0xe6,0x00,0x00,0x00,0x00,0x10,0x08,0x00, + 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e, + 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, + 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67, + 0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7, + 0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1, + 0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10, + 0xe5,0x40,0x87,0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0, + 0x90,0xb3,0x9c,0x3a,0x5d,0x88,0x5d,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40, + 0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff, + 0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64, + 0x40,0x99,0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19, + 0xff,0x9c,0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x00,0x00,0x01,0xb0,0x6e,0x30,0x94, + 0x60,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x33,0x57,0x33,0xf5,0x94,0x2d,0xf5,0xd9, + 0x50,0xeb,0x87,0x66,0xde,0xe3,0xa9,0xd6,0x62,0x69,0x22,0x84,0x4e,0xd6,0xae,0x7a, + 0x11,0x0d,0xd7,0xe7,0xed,0xc3,0x2e,0x3f,0x6f,0x3d,0x9a,0xc5,0xcd,0xea,0x23,0xce, + 0x25,0xbb,0x8d,0xbf,0x76,0x1f,0xd3,0xd5,0xfc,0x56,0xc0,0x5b,0x68,0x56,0x31,0x6d, + 0x12,0xe9,0xd3,0x2c,0xa0,0xf0,0x8c,0x69,0xca,0x03,0x06,0xfe,0x71,0x6e,0x7b,0x51, + 0x51,0x31,0x7d,0x64,0x40,0xb7,0x37,0x3d,0x9f,0xbc,0x64,0x6e,0xad,0x48,0xf2,0x16, + 0x3f,0x2b,0x6d,0x51,0x1a,0xfe,0x6a,0x79,0xc7,0x55,0x51,0xc2,0x62,0x0f,0xc8,0x09, + 0x74,0xf2,0xf8,0x64,0x32,0x9d,0x97,0x78,0xa0,0x8c,0xdf,0xbc,0x9f,0x2c,0x9c,0x13, + 0x44,0xc4,0x32,0x70,0x2c,0x66,0x80,0x7c,0xfb,0x4d,0xb6,0x9b,0x80,0xfa,0xe8,0xc3, + 0x3c,0x70,0x14,0x3d,0x94,0x8b,0x36,0x61,0x4d,0x62,0x08,0x91,0xbe,0xe2,0xdf,0x99, + 0xc8,0x6b,0xc6,0x22,0x07,0xc1,0x7e,0x3b,0x91,0x86,0x21,0x4c,0x0c,0xcf,0xf2,0xde, + 0xd5,0x59,0x8a,0xcc,0xc9,0x0e,0xb1,0xd5,0xb2,0xf7,0xa8,0x3c,0xd7,0xf6,0x8d,0x71, + 0x2e,0xa0,0x47,0xd8,0x01,0x9f,0x34,0x30,0x63,0xb0,0xa2,0x36,0x35,0x6a,0x38,0x71, + 0x46,0xf5,0x8f,0xa8,0x32,0xdd,0xc1,0x3c,0x47,0x14,0x52,0x2c,0xbb,0x50,0x3f,0x5f, + 0x3c,0xa8,0xfc,0xec,0x66,0x02,0xbe,0x24,0x38,0xad,0x3f,0x98,0xfa,0x0c,0xee,0xd5, + 0x8f,0xe3,0xa0,0x66,0xd3,0x85,0xfc,0xac,0xd9,0x8c,0x70,0x4b,0x2a,0x8e,0x98,0xa3, + 0xe2,0x0b,0xf7,0x6b,0x35,0xb7,0x36,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85, + 0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3, + 0x1d,0x59,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87,0x5d, + 0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c,0x3a, + 0x5d,0x88,0x5d,0x02,0x90,0x53,0x52,0x1d,0x6e,0xa7,0xa5,0x2c,0xdd,0x55,0xf7,0x33, + 0xd0,0xfb,0x2d,0x07,0x7c,0x03,0x73,0xb0,0x05,0x3b,0x5b,0x81,0x0d,0x92,0x72,0x44, + 0x06,0x1b,0x75,0x73,0x02,0xd6,0x06,0x3d,0x02,0x26,0x91,0xb2,0x49,0x0a,0xb4,0x54, + 0xde,0xe7,0x3a,0x57,0xc6,0xff,0x5d,0x30,0x83,0x52,0xb4,0x61,0xec,0xe6,0x9f,0x3c, + 0x28,0x4f,0x2c,0x24,0x12,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00, + 0x00,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x80,0x00,0x00,0x8a,0xc5, + 0x33,0xff,0x38,0x65,0x55,0xb3,0x60,0x01,0x02,0x2f,0xd9,0x23,0x60,0x1e,0x1c,0xa0, + 0xac,0xe5,0x06,0x8c,0xe4,0x8e,0x14,0xf3,0xcd,0x31,0x44,0x16,0xc4,0x0d,0x2e,0x14, + 0x8c,0xa1,0xc8,0x4f,0xa6,0xa8,0xe4,0x64,0x9b,0x45,0x79,0xd1,0xb5,0x2f,0x04,0x19, + 0x86,0xe5,0x5c,0x99,0x43,0xf1,0xd0,0xf3,0x6f,0x52,0xd6,0x88,0xf0,0x9b,0x9c,0x58, + 0x98,0x69,0x0d,0x4e,0x76,0x3e,0xbd,0x6e,0x95,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x60,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x00,0x00,0x00,0x95,0x97,0xd7,0xa4,0x39,0x65,0x55,0xb3,0x65,0x01,0x01,0x36, + 0x59,0x20,0x77,0x0e,0xf4,0x73,0x10,0xd7,0xb6,0x59,0x5a,0x7c,0xbe,0xd0,0x56,0x51, + 0x3d,0x97,0xbe,0x84,0xb7,0x02,0xb5,0x89,0x72,0xbd,0xb3,0x19,0x2a,0x54,0x5f,0x57, + 0x52,0x09,0x1d,0xff,0x0f,0xe6,0x70,0x1e,0x71,0x23,0xaa,0x3f,0x98,0x89,0x86,0x35, + 0x87,0xc2,0x66,0xd9,0x99,0xbd,0xa2,0x7e,0x16,0x12,0xd9,0x6b,0xc4,0xd3,0x0c,0x00, + 0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x65,0x02,0x2d,0x22,0x36, + 0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5, + 0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x2d,0x22, + 0x53,0x49,0x4c,0x45,0x4e,0x54,0x41,0x52,0x54,0x49,0x53,0x54,0x2d,0x31,0x2d,0x31, + 0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64, + 0x00,0x00,0x80,0x00,0x00,0x8a,0xd0,0xde,0x20,0xc6,0x65,0x55,0xb3,0x60,0x01,0x02, + 0x11,0xd6,0x4b,0xc5,0x88,0x33,0x4b,0x6c,0x1e,0x0c,0x4c,0x5c,0x65,0x69,0x35,0x66, + 0x45,0x80,0xbc,0x4b,0x56,0x3d,0x98,0x2c,0xb3,0x45,0xef,0x22,0x44,0x6e,0xca,0x6c, + 0x1f,0xe9,0x2a,0xf2,0x4a,0xe1,0x26,0xdb,0x15,0x6f,0x7e,0x3b,0xdd,0xd3,0x40,0x54, + 0xb2,0xc7,0x07,0xfe,0x67,0xb0,0xf3,0x35,0x56,0x25,0xc6,0x53,0xfd,0x54,0x56,0x5e, + 0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf, + 0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f, + 0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x60,0x01,0x01,0x00,0x06, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a, + 0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x95,0x87,0xf8,0x92,0xf3, + 0x65,0x55,0xb3,0x65,0x01,0x01,0x32,0x6c,0xde,0x4a,0xc5,0xe8,0xd4,0xa0,0xed,0xbc, + 0x2c,0x13,0x5e,0xb9,0x1e,0xc3,0xc3,0x86,0xcb,0x75,0xeb,0x6f,0xce,0xc5,0xc5,0x57, + 0x01,0x1c,0x9c,0xb7,0x32,0x17,0x01,0x10,0x8c,0xdd,0x04,0x31,0x78,0xae,0xb4,0x88, + 0x8d,0xf8,0xe8,0x35,0x90,0x69,0x91,0x84,0xd0,0x16,0xd8,0x44,0xbc,0xde,0x37,0xe8, + 0x4e,0x1a,0x95,0xb6,0xa6,0x73,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65, + 0x55,0xb3,0x65,0x03,0x5d,0x2b,0x11,0x92,0xdf,0xba,0x13,0x4e,0x10,0xe5,0x40,0x87, + 0x5d,0x36,0x6e,0xbc,0x8b,0xc3,0x53,0xd5,0xaa,0x76,0x6b,0x80,0xc0,0x90,0xb3,0x9c, + 0x3a,0x5d,0x88,0x5d,0x03,0x5d,0x2b,0x48,0x4f,0x50,0x50,0x49,0x4e,0x47,0x46,0x49, + 0x52,0x45,0x2d,0x63,0x31,0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38, + 0x2d,0x6d,0x6f,0x64,0x64,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x8a,0xcb,0xd4,0xc7, + 0xa1,0x65,0x55,0xb3,0x65,0x01,0x02,0x1d,0x3f,0x42,0x7f,0x3d,0xdb,0x58,0x2b,0xcb, + 0x78,0x5d,0x24,0xf1,0x67,0xc6,0xc7,0xd8,0x6e,0x6c,0x5b,0xf8,0xfb,0x27,0x17,0x58, + 0xaa,0x7e,0x46,0x86,0x49,0x66,0x21,0x47,0x76,0xbd,0xf2,0x2d,0xae,0x29,0xf0,0x6f, + 0x17,0x6e,0xf2,0x7f,0x01,0xda,0x16,0xa9,0x1d,0x6a,0x61,0x4c,0x41,0x71,0x19,0x4d, + 0x37,0xac,0x8a,0x28,0xd8,0x62,0xfb,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca, + 0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7, + 0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00,0x00,0x65, + 0x55,0xb3,0x65,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80, + 0x00,0x01,0xbc,0x39,0xdb,0xc7,0xdf,0x00,0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00, + 0x00,0x00,0x0f,0x42,0x40,0x01,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x22,0x6e,0x46,0x11, + 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x02,0x2d,0x22,0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44, + 0x7c,0x85,0xc4,0x6c,0x92,0x3d,0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e, + 0x3c,0xa3,0x1d,0x59,0x02,0x66,0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84, + 0x88,0x83,0x0b,0x60,0xf7,0xe7,0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83, + 0xb3,0x15,0xc0,0x35,0x18,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99,0x5d, + 0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c,0x17, + 0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x03,0x1b,0x84,0xc5,0x56,0x7b,0x12,0x64,0x40,0x99, + 0x5d,0x3e,0xd5,0xaa,0xba,0x05,0x65,0xd7,0x1e,0x18,0x34,0x60,0x48,0x19,0xff,0x9c, + 0x17,0xf5,0xe9,0xd5,0xdd,0x07,0x8f,0x80,0x00,0x00,0x8e,0x85,0x67,0x9b,0xcf,0x00, + 0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x27,0x9e,0x4e,0x43,0x39,0xa6,0x92, + 0x19,0x35,0x50,0x19,0xbb,0x51,0x5b,0xf9,0xac,0xdb,0xda,0x9c,0xde,0x81,0x8b,0x56, + 0x2e,0x0a,0x3d,0xd5,0xb0,0x5f,0x10,0x2e,0x6c,0x22,0x55,0x7e,0x07,0xc2,0x5f,0x4b, + 0x9c,0xc1,0x21,0x6e,0x07,0x66,0x41,0x60,0xde,0x3e,0xe2,0x24,0xa5,0x9e,0xec,0xaf, + 0xd7,0xcc,0x3f,0x87,0x7c,0x32,0x29,0xca,0xe7,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6c,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0xca,0xa4,0x8e,0x70,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x4e,0x3f,0x3b,0x6d,0xda,0xcc,0xd3,0xef,0x5f,0xaf,0x26,0x76,0x16, + 0x64,0xa2,0x82,0x97,0xe8,0xb4,0xe4,0xb1,0x2d,0xec,0xa1,0x9e,0x91,0x69,0xd3,0xde, + 0xe9,0x58,0xc7,0x19,0x06,0x90,0x42,0x86,0x97,0xf3,0x88,0xca,0x35,0xd5,0xec,0x79, + 0x5e,0x59,0x33,0x31,0xf4,0x0c,0xdb,0x55,0x5d,0x78,0xd7,0x22,0x59,0xa2,0xe5,0x8d, + 0xeb,0x65,0x41,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x6c,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00,0x8a,0xbf, + 0x0d,0x7a,0xbc,0x65,0x55,0xb3,0x6f,0x01,0x02,0x59,0xc9,0x36,0x84,0xaa,0x13,0x70, + 0x73,0x7d,0xa7,0xe6,0x8a,0x72,0x05,0x15,0xa9,0x06,0x69,0xe0,0xc0,0x0d,0x15,0x6d, + 0x22,0x5c,0xd6,0x1a,0x3e,0x56,0xaa,0x9d,0x98,0x68,0x5a,0x3c,0xdc,0x38,0x71,0xee, + 0x0d,0x02,0x3e,0x2f,0xd0,0x97,0xd7,0xab,0xe2,0x0d,0xdf,0xf5,0xa6,0xd1,0x9c,0xb6, + 0xb9,0x30,0xd6,0xdd,0x10,0xa7,0xa3,0xce,0x5e,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b, + 0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a, + 0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x67,0x00,0x00,0x01,0x00, + 0x00,0x65,0x55,0xb3,0x6f,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33, + 0x80,0x80,0x00,0x00,0x8e,0x80,0x00,0x75,0xd3,0x00,0x00,0x00,0x00,0x10,0x06,0x00, + 0x8a,0x01,0x02,0x26,0x62,0x25,0x68,0x2d,0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93, + 0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d,0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3, + 0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10,0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf, + 0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39,0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7, + 0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43, + 0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1, + 0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01, + 0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00, + 0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x80,0x00,0x00,0x8e,0xdc, + 0x5e,0x38,0x7a,0x00,0x00,0x00,0x00,0x10,0x06,0x00,0x8a,0x01,0x02,0x5d,0xf9,0x14, + 0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7,0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b, + 0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc,0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73, + 0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd,0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e, + 0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30,0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e, + 0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f, + 0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e, + 0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00, + 0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x01,0xb0,0xb8,0x17,0x71,0xe9,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x0d,0xef,0xc0,0x12,0x4f,0xd4,0xe4,0x1c,0xce,0xc3,0xf4,0x83,0x17, + 0x21,0x7e,0x33,0x11,0x5a,0x8f,0x8c,0x39,0xae,0xbb,0x06,0x2b,0x4e,0x73,0xa6,0x52, + 0xee,0x0e,0x61,0x03,0xf9,0xf1,0x16,0x7b,0x22,0xbd,0xcb,0x92,0xcf,0x82,0x2d,0x0f, + 0xcc,0x26,0xcb,0x11,0x9f,0x0a,0xf5,0x23,0xf4,0x26,0x97,0x86,0x7e,0x21,0x51,0x85, + 0x16,0x3a,0x0e,0x4b,0x1f,0x64,0xf3,0x62,0xf4,0x2f,0x13,0x54,0x5c,0x9a,0xed,0xd6, + 0x9d,0x5d,0xf5,0x17,0x85,0xcc,0x5d,0x53,0xa4,0x84,0x36,0x9b,0xe9,0xa7,0x4a,0x04, + 0x1f,0x8c,0x1c,0x28,0xc7,0x1e,0xab,0xb3,0xf2,0x53,0x3d,0xf8,0xb6,0xcd,0xd8,0x45, + 0x6e,0xc3,0x77,0xdb,0xb1,0x2b,0xa5,0xdd,0xc9,0xbf,0x69,0xa7,0xdf,0x98,0x2c,0x54, + 0xa7,0xa8,0xf5,0x4f,0xc3,0xd1,0x57,0x81,0x98,0x60,0xa0,0xb6,0x32,0x83,0x08,0x65, + 0x1e,0x79,0x24,0xf4,0xbe,0xfe,0x14,0xa6,0xfd,0x31,0x9b,0xfa,0x15,0x6f,0x1b,0xab, + 0x64,0x8b,0x69,0x48,0xb4,0x2e,0x99,0xca,0xd7,0x46,0x97,0x57,0x17,0x1d,0x5d,0x53, + 0xe5,0xde,0xae,0xbb,0x2d,0x74,0x86,0xa5,0xe5,0x8e,0x02,0x5c,0x2c,0x8d,0x0d,0x78, + 0xdc,0xf1,0xa0,0x05,0xb8,0xbd,0x64,0x7d,0x51,0x47,0x5e,0x39,0xaa,0x08,0x2d,0xf2, + 0xd0,0x1a,0x96,0x59,0xab,0x88,0x94,0xa2,0xf7,0x2e,0x09,0x3b,0xd0,0xed,0xfc,0xb4, + 0x1b,0xaa,0xba,0x34,0xf8,0x7b,0x11,0x51,0x36,0x7b,0x13,0x84,0x6f,0xc9,0x4a,0x58, + 0x92,0x3c,0x0c,0xa2,0x4c,0x8f,0xc5,0x78,0xb4,0x4a,0xad,0x98,0x08,0x4e,0x4a,0xf3, + 0x7a,0x28,0x80,0x00,0x00,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x02,0x2d,0x22, + 0x36,0x20,0xa3,0x59,0xa4,0x7f,0xf7,0xf7,0xac,0x44,0x7c,0x85,0xc4,0x6c,0x92,0x3d, + 0xa5,0x33,0x89,0x22,0x1a,0x00,0x54,0xc1,0x1c,0x1e,0x3c,0xa3,0x1d,0x59,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x03, + 0xbb,0xee,0x60,0xc3,0x95,0x05,0x6b,0x8a,0x12,0x01,0xe0,0x6e,0xd7,0x9e,0x29,0x14, + 0xc1,0x1a,0x61,0xd7,0xb1,0xaa,0x78,0x18,0x46,0x46,0x8d,0x02,0x48,0x9d,0xba,0x69, + 0x02,0x32,0x42,0x66,0xde,0x84,0x03,0xb3,0xab,0x15,0x7a,0x09,0xf1,0xf7,0x84,0xd5, + 0x87,0xaf,0x61,0x83,0x1c,0x99,0x8c,0x15,0x1b,0xcc,0x21,0xbb,0x74,0xc2,0xb2,0x31, + 0x4b,0x00,0x00,0x00,0x0a,0x91,0x11,0x83,0xf6,0x00,0x00,0x00,0x00,0x10,0x05,0x00, + 0x00,0x00,0x00,0x00,0x0f,0x42,0x40,0x00,0x00,0x00,0x8a,0xe1,0x31,0x6b,0x76,0x65, + 0x55,0xb3,0x71,0x01,0x02,0x5d,0xf9,0x14,0xa0,0xd1,0x46,0x69,0x9a,0x2a,0x97,0xf7, + 0xb3,0x83,0xf0,0x30,0x73,0x48,0x5e,0x7b,0x3e,0x6c,0x45,0xd3,0xf1,0x51,0xf8,0xbc, + 0x4b,0xd7,0xae,0x02,0xd9,0x57,0x51,0x73,0x8f,0x0f,0xd0,0xdd,0x38,0x36,0x48,0xcd, + 0xda,0xea,0x01,0x24,0x16,0x3d,0x14,0x7e,0x5a,0x9e,0xac,0xcd,0x81,0xd1,0x96,0x30, + 0xd9,0xbc,0xa6,0xe4,0xe8,0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12, + 0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7, + 0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00,0x01,0x00,0x00,0x65,0x55,0xb3, + 0x71,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b,0x02,0x33,0x80,0x00,0x00,0x00, + 0x8a,0xbd,0x6f,0x26,0xdf,0x65,0x55,0xb3,0x71,0x01,0x02,0x26,0x62,0x25,0x68,0x2d, + 0x27,0x06,0x9a,0x3b,0xaa,0x1a,0x43,0x93,0xac,0xb5,0x05,0x14,0x1c,0x09,0x22,0x8d, + 0xfb,0x54,0x43,0x73,0x3a,0x88,0xaa,0xa3,0x18,0xc8,0xd8,0x0d,0x36,0xd4,0x26,0x10, + 0xe9,0x82,0xa6,0x3c,0xb4,0x38,0x24,0xaf,0xdc,0x06,0xd5,0x3d,0xe3,0x7a,0xe8,0x39, + 0xdd,0xd4,0x5f,0xd8,0x92,0xf5,0x4b,0xe7,0x8d,0xf7,0xab,0x06,0x22,0x6e,0x46,0x11, + 0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e, + 0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f,0x00,0x00,0x6e,0x00,0x00, + 0x01,0x00,0x00,0x65,0x55,0xb3,0x71,0x01,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x03,0xe8,0x00,0x00,0x00,0x00,0x3b, + 0x02,0x33,0x80,0x00,0x00,0x00,0x95,0xf6,0xd7,0x24,0x69,0x65,0x55,0xb3,0x79,0x01, + 0x01,0x42,0x62,0x2b,0xf0,0x0a,0x44,0xc3,0xe0,0x78,0x3c,0xa7,0x08,0x5a,0xa0,0xaa, + 0x9d,0xb2,0xdc,0x2e,0xa7,0x29,0x0a,0x39,0x3d,0x01,0x57,0xbf,0x34,0x23,0x0f,0xb9, + 0x19,0x33,0x6f,0xc2,0xfb,0x9f,0x25,0xac,0xc4,0xc9,0x47,0xb7,0x41,0x92,0xdb,0x2f, + 0xd5,0xf0,0x1f,0x24,0x32,0xdf,0x38,0x30,0x89,0x93,0xeb,0xc9,0xec,0xf1,0x09,0x51, + 0xbb,0x00,0x07,0x88,0xa0,0x00,0x0a,0x0a,0x69,0xa2,0x65,0x55,0xb3,0x79,0x02,0x66, + 0xe4,0x59,0x8d,0x1d,0x3c,0x41,0x5f,0x57,0x2a,0x84,0x88,0x83,0x0b,0x60,0xf7,0xe7, + 0x44,0xed,0x92,0x35,0xeb,0x0b,0x1b,0xa9,0x32,0x83,0xb3,0x15,0xc0,0x35,0x18,0x02, + 0x66,0xe4,0x4a,0x55,0x4e,0x49,0x4f,0x52,0x42,0x45,0x41,0x4d,0x2d,0x72,0x63,0x31, + 0x2d,0x31,0x2d,0x67,0x63,0x63,0x65,0x34,0x66,0x36,0x38,0x2d,0x6d,0x6f,0x64,0x64, + 0x65,0x64,0x00,0x00, }; /* not_mcf sets NDEBUG, so assert() is useless */ @@ -296,12 +333,11 @@ int main(int argc, char *argv[]) assert(gossmap); remove(gossfile); - /* There is a public channel 2<->3 (103x1x0), and private - * 1<->2 (110x1x1). */ + /* There is a public channel 2<->3 (103x1x0), and 1<->2 (110x1x1). */ assert(node_id_from_hexstr("0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518", 66, &l1)); assert(node_id_from_hexstr("022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59", 66, &l2)); assert(node_id_from_hexstr("035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d", 66, &l3)); - assert(short_channel_id_from_str("110x1x1", 7, &scid12)); + assert(short_channel_id_from_str("110x1x0", 7, &scid12)); assert(short_channel_id_from_str("103x1x0", 7, &scid23)); chan_extra_map = tal(tmpctx, struct chan_extra_map); From 84361ca202e92323c6057f9305f4480d0a97e94b Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Thu, 7 Dec 2023 06:44:04 +1030 Subject: [PATCH 03/29] pytest: use wait_local_channel_active --- tests/test_gossip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index cf8815cc00a8..c4ed0999dc41 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -2180,8 +2180,8 @@ def test_gossip_private_updates(node_factory, bitcoind): scid, _ = l1.fundchannel(l2, 10**6, None, False) bitcoind.generate_block(5) - l1.wait_channel_active(scid) - l2.wait_channel_active(scid) + l1.wait_local_channel_active(scid) + l2.wait_local_channel_active(scid) l2.rpc.setchannel(l1.info['id'], feebase=11) wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 12) From 9b34784785d69dc8ee8f9005716f899a2bc16294 Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Thu, 7 Dec 2023 06:44:04 +1030 Subject: [PATCH 04/29] gossipd: correctly attribute our own channel update to ourselves --- gossipd/gossip_generation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index 40a81c5f7f72..2223d7be2d30 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -600,7 +600,7 @@ static void apply_update(struct daemon *daemon, take(update); } - msg = handle_channel_update(daemon->rstate, update, &chan->nodes[!direction]->id, NULL, true); + msg = handle_channel_update(daemon->rstate, update, &chan->nodes[direction]->id, NULL, true); if (msg) status_failed(STATUS_FAIL_INTERNAL_ERROR, "%s: rejected local channel update %s: %s", From 5a29ddab91d63309d1f12a77ffc15f3246ac7d67 Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 05/29] db: add private channel inbound fields This will be used for generating route hints rather than private gossip --- wallet/db.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wallet/db.c b/wallet/db.c index 33e322aafd36..3215f86cdea4 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1011,6 +1011,11 @@ static struct migration dbmigrations[] = { {SQL("CREATE INDEX forwards_updated_idx ON forwards (updated_index)"), NULL}, {NULL, migrate_initialize_forwards_wait_indexes}, {SQL("ALTER TABLE channel_funding_inflights ADD force_sign_first INTEGER DEFAULT 0"), NULL}, + {SQL("ALTER TABLE channels ADD remote_feerate_base INTEGER DEFAULT NULL;"), NULL}, + {SQL("ALTER TABLE channels ADD remote_feerate_ppm INTEGER DEFAULT NULL;"), NULL}, + {SQL("ALTER TABLE channels ADD remote_cltv_expiry_delta INTEGER DEFAULT NULL;"), NULL}, + {SQL("ALTER TABLE channels ADD remote_htlc_maximum_msat BIGINT DEFAULT NULL;"), NULL}, + {SQL("ALTER TABLE channels ADD remote_htlc_minimum_msat BIGINT DEFAULT NULL;"), NULL}, }; /** From 4dfe403593e0bab656e3bd3f22d6228d3d27ebef Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 06/29] gossipd: pass remote private channel update to ld and stash in the database. Rusty: I added the bad gossip message so we would see unknown updates in CI, and made sure we don't send our own generated updates to lightningd. Signed-off-by: Rusty Russell --- gossipd/gossip_generation.c | 2 +- gossipd/gossipd.c | 1 + gossipd/gossipd_wire.csv | 13 +++++ gossipd/routing.c | 43 +++++++++++++- gossipd/test/run-check_channel_announcement.c | 6 ++ gossipd/test/run-txout_failure.c | 6 ++ lightningd/channel.c | 6 +- lightningd/channel.h | 9 ++- lightningd/gossip_control.c | 57 +++++++++++++++++++ lightningd/opening_control.c | 6 +- plugins/Makefile | 2 +- wallet/test/run-db.c | 4 +- wallet/test/run-wallet.c | 3 +- wallet/wallet.c | 52 ++++++++++++++++- 14 files changed, 198 insertions(+), 12 deletions(-) diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index 2223d7be2d30..84532bc19218 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -600,7 +600,7 @@ static void apply_update(struct daemon *daemon, take(update); } - msg = handle_channel_update(daemon->rstate, update, &chan->nodes[direction]->id, NULL, true); + msg = handle_channel_update(daemon->rstate, update, NULL, NULL, true); if (msg) status_failed(STATUS_FAIL_INTERNAL_ERROR, "%s: rejected local channel update %s: %s", diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 33bf8cda70c6..35015ec49012 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1206,6 +1206,7 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIPD_NEW_BLOCKHEIGHT_REPLY: case WIRE_GOSSIPD_GET_ADDRS_REPLY: case WIRE_GOSSIPD_GOT_LOCAL_CHANNEL_UPDATE: + case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE: break; } diff --git a/gossipd/gossipd_wire.csv b/gossipd/gossipd_wire.csv index a94afb1bbfaf..9fd669dc1c2d 100644 --- a/gossipd/gossipd_wire.csv +++ b/gossipd/gossipd_wire.csv @@ -136,3 +136,16 @@ msgdata,gossipd_used_local_channel_update,scid,short_channel_id, # Tell gossipd we have verified a new public IP by the remote_addr feature msgtype,gossipd_discovered_ip,3009 msgdata,gossipd_discovered_ip,discovered_ip,wireaddr, + +subtype,remote_priv_update +subtypedata,remote_priv_update,source_node,node_id, +subtypedata,remote_priv_update,scid,short_channel_id, +subtypedata,remote_priv_update,fee_base,u32, +subtypedata,remote_priv_update,fee_ppm,u32, +subtypedata,remote_priv_update,cltv_delta,u16, +subtypedata,remote_priv_update,htlc_minimum_msat,amount_msat, +subtypedata,remote_priv_update,htlc_maximum_msat,amount_msat, + +# Tell lightningd we received channel update info for a local channel +msgtype,gossipd_remote_channel_update,3010 +msgdata,gossipd_remote_channel_update,update,remote_priv_update, diff --git a/gossipd/routing.c b/gossipd/routing.c index adedcb6c8b72..2948298d2df9 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -1347,9 +1348,32 @@ static bool is_chan_dying(struct routing_state *rstate, return false; } +static void tell_lightningd_private_update(struct routing_state *rstate, + const struct node_id *source_peer, + struct short_channel_id scid, + u32 fee_base_msat, + u32 fee_ppm, + u16 cltv_delta, + struct amount_msat htlc_minimum, + struct amount_msat htlc_maximum) +{ + struct remote_priv_update remote_update; + u8* msg; + remote_update.source_node = *source_peer; + remote_update.scid = scid; + remote_update.fee_base = fee_base_msat; + remote_update.fee_ppm = fee_ppm; + remote_update.cltv_delta = cltv_delta; + remote_update.htlc_minimum_msat = htlc_minimum; + remote_update.htlc_maximum_msat = htlc_maximum; + msg = towire_gossipd_remote_channel_update(NULL, &remote_update); + daemon_conn_send(rstate->daemon->master, take(msg)); +} + bool routing_add_channel_update(struct routing_state *rstate, const u8 *update TAKES, u32 index, + /* NULL if it's us */ const struct node_id *source_peer, bool ignore_timestamp, bool force_spam_flag, @@ -1398,6 +1422,16 @@ bool routing_add_channel_update(struct routing_state *rstate, /* Maybe announcement was waiting for this update? */ uc = get_unupdated_channel(rstate, &short_channel_id); if (!uc) { + if (index) + return false; + /* Allow ld to process a private channel update */ + if (source_peer) { + tell_lightningd_private_update(rstate, source_peer, + short_channel_id, fee_base_msat, + fee_proportional_millionths, + expiry, htlc_minimum, + htlc_maximum); + } return false; } sat = uc->sat; @@ -1535,6 +1569,14 @@ bool routing_add_channel_update(struct routing_state *rstate, hc->bcast.index = index; hc->rgraph.index = index; } + if (source_peer) { + /* give lightningd the channel's inbound info to store to db */ + tell_lightningd_private_update(rstate, source_peer, + short_channel_id, fee_base_msat, + fee_proportional_millionths, + expiry, htlc_minimum, + htlc_maximum); + } return true; } @@ -2340,4 +2382,3 @@ void routing_channel_spent(struct routing_state *rstate, type_to_string(msg, struct short_channel_id, &chan->scid)); remember_chan_dying(rstate, &chan->scid, deadline, index); } - diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index 2a307ef36d0b..cf92664b91dc 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -59,6 +59,9 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED, const struct half_chan *hc UNNEEDED, const u8 *cupdate UNNEEDED) { fprintf(stderr, "cupdate_different called!\n"); abort(); } +/* Generated stub for daemon_conn_send */ +void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED) +{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); } /* Generated stub for gossip_store_add */ u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED, u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED, @@ -133,6 +136,9 @@ void status_fmt(enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...) { fprintf(stderr, "status_fmt called!\n"); abort(); } +/* Generated stub for towire_gossipd_remote_channel_update */ +u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED) +{ fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ int main(int argc, char *argv[]) diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index 1fb6271990fb..fd62f10bd7bc 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -30,6 +30,9 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED, const struct half_chan *hc UNNEEDED, const u8 *cupdate UNNEEDED) { fprintf(stderr, "cupdate_different called!\n"); abort(); } +/* Generated stub for daemon_conn_send */ +void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED) +{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); } /* Generated stub for gossip_store_add */ u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED, u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED, @@ -99,6 +102,9 @@ void status_fmt(enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...) { fprintf(stderr, "status_fmt called!\n"); abort(); } +/* Generated stub for towire_gossipd_remote_channel_update */ +u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED) +{ fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); } /* Generated stub for towire_warningfmt */ u8 *towire_warningfmt(const tal_t *ctx UNNEEDED, const struct channel_id *channel UNNEEDED, diff --git a/lightningd/channel.c b/lightningd/channel.c index a20b3f5387c9..562b7e7672ca 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -264,6 +264,7 @@ struct channel *new_unsaved_channel(struct peer *peer, = CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE; channel->shutdown_wrong_funding = NULL; channel->closing_feerate_range = NULL; + channel->private_update = NULL; channel->channel_update = NULL; channel->alias[LOCAL] = channel->alias[REMOTE] = NULL; @@ -427,7 +428,9 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u16 lease_chan_max_ppt, struct amount_msat htlc_minimum_msat, struct amount_msat htlc_maximum_msat, - bool ignore_fee_limits) + bool ignore_fee_limits, + /* NULL or stolen */ + struct remote_priv_update *private_update STEALS) { struct channel *channel = tal(peer->ld, struct channel); struct amount_msat htlc_min, htlc_max; @@ -553,6 +556,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->lease_commit_sig = tal_steal(channel, lease_commit_sig); channel->lease_chan_max_msat = lease_chan_max_msat; channel->lease_chan_max_ppt = lease_chan_max_ppt; + channel->private_update = tal_steal(channel, private_update); channel->blockheight_states = dup_height_states(channel, height_states); channel->channel_update = NULL; diff --git a/lightningd/channel.h b/lightningd/channel.h index 1df9bd032793..7da224273747 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -297,6 +298,10 @@ struct channel { /* Lease commited max part per thousandth channel fee (ppm * 1000) */ u16 lease_chan_max_ppt; + /* Private channel incoming fee rates, cltv delta min/max htlc from + * peer. Used to generate route hints, blinded paths. */ + struct remote_priv_update *private_update; + /* Latest channel_update, for use in error messages. */ u8 *channel_update; @@ -383,7 +388,9 @@ struct channel *new_channel(struct peer *peer, u64 dbid, u16 lease_chan_max_ppt, struct amount_msat htlc_minimum_msat, struct amount_msat htlc_maximum_msat, - bool ignore_fee_limits); + bool ignore_fee_limits, + /* NULL or stolen */ + struct remote_priv_update *private_update STEALS); /* new_inflight - Create a new channel_inflight for a channel */ struct channel_inflight *new_inflight(struct channel *channel, diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index f9f462d395df..e96dcf34f5a6 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,57 @@ const u8 *get_channel_update(struct channel *channel) return channel->channel_update; } +static void set_channel_remote_update(struct lightningd *ld, + struct channel *channel, + struct remote_priv_update* update TAKES) +{ + struct short_channel_id *scid; + + scid = channel->scid; + if (!scid) + scid = channel->alias[LOCAL]; + + if (!node_id_eq(&update->source_node, &channel->peer->id)) { + log_unusual(ld->log, "Bad gossip order: %s sent us a channel update for a " + "channel owned by %s (%s)", + type_to_string(tmpctx, struct node_id, + &update->source_node), + type_to_string(tmpctx, struct node_id, + &channel->peer->id), + type_to_string(tmpctx, struct short_channel_id, scid)); + if (taken(update)) + tal_free(update); + return; + } + log_debug(ld->log, "updating channel %s with private inbound settings", + type_to_string(tmpctx, struct short_channel_id, scid)); + tal_free(channel->private_update); + channel->private_update = tal_dup(channel, + struct remote_priv_update, update); + if (taken(update)) + tal_free(update); + wallet_channel_save(ld->wallet, channel); +} + +static void handle_private_update_data(struct lightningd *ld, const u8 *msg) +{ + struct channel *channel; + struct remote_priv_update *update; + + update = tal(tmpctx, struct remote_priv_update); + if (!fromwire_gossipd_remote_channel_update(msg, update)) + fatal("Gossip gave bad GOSSIPD_REMOTE_CHANNEL_UPDATE %s", + tal_hex(msg, msg)); + channel = any_channel_by_scid(ld, &update->scid, true); + if (!channel) { + log_unusual(ld->log, "could not find channel for peer's " + "private channel update"); + return; + } + + set_channel_remote_update(ld, channel, update); +} + static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) { enum gossipd_wire t = fromwire_peektype(msg); @@ -213,6 +265,11 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPD_GOT_LOCAL_CHANNEL_UPDATE: handle_local_channel_update(gossip->ld, msg); break; + case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE: + /* Please stash in database for us! */ + handle_private_update_data(gossip->ld, msg); + tal_free(msg); + break; } return 0; } diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 0acc6f1b2d58..8a043184c834 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -232,7 +232,8 @@ wallet_commit_channel(struct lightningd *ld, 0, NULL, 0, 0, /* No leases on v1s */ ld->config.htlc_minimum_msat, ld->config.htlc_maximum_msat, - ld->config.ignore_fee_limits); + ld->config.ignore_fee_limits, + NULL); /* Now we finally put it in the database. */ wallet_channel_insert(ld->wallet, channel); @@ -1486,7 +1487,8 @@ static struct channel *stub_chan(struct command *cmd, 0, NULL, 0, 0, /* No leases on v1s */ ld->config.htlc_minimum_msat, ld->config.htlc_maximum_msat, - false); + false, + NULL); return channel; } diff --git a/plugins/Makefile b/plugins/Makefile index 852b93cbd81d..edc29a0f74e8 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -198,7 +198,7 @@ plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJ # Topology wants to decode node_announcement, and peer_wiregen which # pulls in some of bitcoin/. -plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) +plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o common/gossmods_listpeerchannels.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index ddabea496a5d..f3e7a51f6c3e 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -176,7 +176,9 @@ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid 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) + bool ignore_fee_limits UNNEEDED, + /* NULL or stolen */ + struct remote_priv_update* remote_update STEALS 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, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 42cec47f1ef0..29652fe4821c 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1904,7 +1904,8 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) 7777, 22, AMOUNT_MSAT(0), AMOUNT_MSAT(-1ULL), - false); + false, + NULL); db_begin_transaction(w->db); CHECK(!wallet_err); wallet_channel_insert(w, chan); diff --git a/wallet/wallet.c b/wallet/wallet.c index e2e7986594a6..a740193b5a82 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1514,6 +1514,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm u32 lease_chan_max_msat; u16 lease_chan_max_ppt; bool ignore_fee_limits; + struct remote_priv_update *remote_update; peer_dbid = db_col_u64(stmt, "peer_id"); peer = find_peer_by_dbid(w->ld, peer_dbid); @@ -1678,6 +1679,27 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm last_sig = NULL; } + if (!db_col_is_null(stmt, "remote_cltv_expiry_delta")) { + remote_update = tal(NULL, struct remote_priv_update); + remote_update->source_node = peer->id; + if (scid) + remote_update->scid = *scid; + else + remote_update->scid = *alias[LOCAL]; + remote_update->fee_base = db_col_int(stmt, "remote_feerate_base"); + remote_update->fee_ppm = db_col_int(stmt, "remote_feerate_ppm"); + remote_update->cltv_delta = db_col_int(stmt, "remote_cltv_expiry_delta"); + remote_update->htlc_minimum_msat = db_col_amount_msat(stmt, "remote_htlc_minimum_msat"); + remote_update->htlc_maximum_msat = db_col_amount_msat(stmt, "remote_htlc_maximum_msat"); + } else { + remote_update = NULL; + db_col_ignore(stmt, "remote_feerate_base"); + db_col_ignore(stmt, "remote_feerate_ppm"); + db_col_ignore(stmt, "remote_cltv_expiry_delta"); + db_col_ignore(stmt, "remote_htlc_minimum_msat"); + db_col_ignore(stmt, "remote_htlc_maximum_msat"); + } + chan = new_channel(peer, db_col_u64(stmt, "id"), &wshachain, channel_state_in_db(db_col_int(stmt, "state")), @@ -1737,7 +1759,8 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm lease_chan_max_ppt, htlc_minimum_msat, htlc_maximum_msat, - ignore_fee_limits); + ignore_fee_limits, + remote_update); if (!wallet_channel_load_inflights(w, chan)) { tal_free(chan); @@ -1925,6 +1948,11 @@ static bool wallet_channels_load_active(struct wallet *w) ", alias_local" ", alias_remote" ", ignore_fee_limits" + ", remote_feerate_base" + ", remote_feerate_ppm" + ", remote_cltv_expiry_delta" + ", remote_htlc_minimum_msat" + ", remote_htlc_maximum_msat" " FROM channels" " WHERE state != ?;")); //? 0 db_bind_int(stmt, CLOSED); @@ -2238,8 +2266,13 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) " htlc_maximum_msat=?," // 43 " alias_local=?," // 44 " alias_remote=?," // 45 - " ignore_fee_limits=?" // 46 - " WHERE id=?")); // 47 + " ignore_fee_limits=?," // 46 + " remote_feerate_base=?," // 47 + " remote_feerate_ppm=?," // 48 + " remote_cltv_expiry_delta=?," // 49 + " remote_htlc_minimum_msat=?," // 50 + " remote_htlc_maximum_msat=?" // 51 + " WHERE id=?")); // 52 db_bind_u64(stmt, chan->their_shachain.id); if (chan->scid) db_bind_short_channel_id(stmt, chan->scid); @@ -2321,6 +2354,19 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_null(stmt); db_bind_int(stmt, chan->ignore_fee_limits); + if (chan->private_update) { + db_bind_int(stmt, chan->private_update->fee_base); + db_bind_int(stmt, chan->private_update->fee_ppm); + db_bind_int(stmt, chan->private_update->cltv_delta); + db_bind_amount_msat(stmt, &chan->private_update->htlc_minimum_msat); + db_bind_amount_msat(stmt, &chan->private_update->htlc_maximum_msat); + } else { + db_bind_null(stmt); + db_bind_null(stmt); + db_bind_null(stmt); + db_bind_null(stmt); + db_bind_null(stmt); + } db_bind_u64(stmt, chan->dbid); db_exec_prepared_v2(take(stmt)); From 2fa59d91676fdf12045cb73d30dea66af8323eae Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 07/29] gossipd: always send information about our channels' gossip updates. Not just when it's a private channel. This is useful for listpeerchannels in the next patch. Most of this is renaming. It also means that source can be NULL, so move it out of the struct and put it in the message, where it logically belongs, and make it an optional field. Signed-off-by: Rusty Russell --- gossipd/gossipd_wire.csv | 18 +++--- gossipd/routing.c | 57 ++++++++++--------- gossipd/test/run-check_channel_announcement.c | 2 +- gossipd/test/run-txout_failure.c | 2 +- lightningd/channel.c | 6 +- lightningd/channel.h | 6 +- lightningd/gossip_control.c | 32 ++++++----- wallet/test/run-db.c | 2 +- wallet/wallet.c | 17 +++--- 9 files changed, 73 insertions(+), 69 deletions(-) diff --git a/gossipd/gossipd_wire.csv b/gossipd/gossipd_wire.csv index 9fd669dc1c2d..0dd73b6696fc 100644 --- a/gossipd/gossipd_wire.csv +++ b/gossipd/gossipd_wire.csv @@ -137,15 +137,15 @@ msgdata,gossipd_used_local_channel_update,scid,short_channel_id, msgtype,gossipd_discovered_ip,3009 msgdata,gossipd_discovered_ip,discovered_ip,wireaddr, -subtype,remote_priv_update -subtypedata,remote_priv_update,source_node,node_id, -subtypedata,remote_priv_update,scid,short_channel_id, -subtypedata,remote_priv_update,fee_base,u32, -subtypedata,remote_priv_update,fee_ppm,u32, -subtypedata,remote_priv_update,cltv_delta,u16, -subtypedata,remote_priv_update,htlc_minimum_msat,amount_msat, -subtypedata,remote_priv_update,htlc_maximum_msat,amount_msat, +subtype,peer_update +subtypedata,peer_update,scid,short_channel_id, +subtypedata,peer_update,fee_base,u32, +subtypedata,peer_update,fee_ppm,u32, +subtypedata,peer_update,cltv_delta,u16, +subtypedata,peer_update,htlc_minimum_msat,amount_msat, +subtypedata,peer_update,htlc_maximum_msat,amount_msat, # Tell lightningd we received channel update info for a local channel msgtype,gossipd_remote_channel_update,3010 -msgdata,gossipd_remote_channel_update,update,remote_priv_update, +msgdata,gossipd_remote_channel_update,source_node,?node_id, +msgdata,gossipd_remote_channel_update,peer_update,peer_update, diff --git a/gossipd/routing.c b/gossipd/routing.c index 2948298d2df9..a236a102a532 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1348,25 +1348,24 @@ static bool is_chan_dying(struct routing_state *rstate, return false; } -static void tell_lightningd_private_update(struct routing_state *rstate, - const struct node_id *source_peer, - struct short_channel_id scid, - u32 fee_base_msat, - u32 fee_ppm, - u16 cltv_delta, - struct amount_msat htlc_minimum, - struct amount_msat htlc_maximum) -{ - struct remote_priv_update remote_update; +static void tell_lightningd_peer_update(struct routing_state *rstate, + const struct node_id *source_peer, + struct short_channel_id scid, + u32 fee_base_msat, + u32 fee_ppm, + u16 cltv_delta, + struct amount_msat htlc_minimum, + struct amount_msat htlc_maximum) +{ + struct peer_update remote_update; u8* msg; - remote_update.source_node = *source_peer; remote_update.scid = scid; remote_update.fee_base = fee_base_msat; remote_update.fee_ppm = fee_ppm; remote_update.cltv_delta = cltv_delta; remote_update.htlc_minimum_msat = htlc_minimum; remote_update.htlc_maximum_msat = htlc_maximum; - msg = towire_gossipd_remote_channel_update(NULL, &remote_update); + msg = towire_gossipd_remote_channel_update(NULL, source_peer, &remote_update); daemon_conn_send(rstate->daemon->master, take(msg)); } @@ -1425,13 +1424,11 @@ bool routing_add_channel_update(struct routing_state *rstate, if (index) return false; /* Allow ld to process a private channel update */ - if (source_peer) { - tell_lightningd_private_update(rstate, source_peer, - short_channel_id, fee_base_msat, - fee_proportional_millionths, - expiry, htlc_minimum, - htlc_maximum); - } + tell_lightningd_peer_update(rstate, source_peer, + short_channel_id, fee_base_msat, + fee_proportional_millionths, + expiry, htlc_minimum, + htlc_maximum); return false; } sat = uc->sat; @@ -1542,6 +1539,20 @@ bool routing_add_channel_update(struct routing_state *rstate, if (!spam) hc->bcast.timestamp = timestamp; + /* If this is a peer's update to one of our local channels, tell lightningd. */ + if (node_id_eq(&chan->nodes[!direction]->id, &rstate->daemon->id)) { + /* give lightningd the channel's inbound info to store to db */ + tell_lightningd_peer_update(rstate, + /* Note: we can get public + * channel_updates from other than + * direct peer! */ + is_chan_public(chan) ? NULL : source_peer, + short_channel_id, fee_base_msat, + fee_proportional_millionths, + expiry, htlc_minimum, + htlc_maximum); + } + /* BOLT #7: * - MUST consider the `timestamp` of the `channel_announcement` to be * the `timestamp` of a corresponding `channel_update`. @@ -1569,14 +1580,6 @@ bool routing_add_channel_update(struct routing_state *rstate, hc->bcast.index = index; hc->rgraph.index = index; } - if (source_peer) { - /* give lightningd the channel's inbound info to store to db */ - tell_lightningd_private_update(rstate, source_peer, - short_channel_id, fee_base_msat, - fee_proportional_millionths, - expiry, htlc_minimum, - htlc_maximum); - } return true; } diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index cf92664b91dc..a299d0a35830 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -137,7 +137,7 @@ void status_fmt(enum log_level level UNNEEDED, { fprintf(stderr, "status_fmt called!\n"); abort(); } /* Generated stub for towire_gossipd_remote_channel_update */ -u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED) +u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct node_id *source_node UNNEEDED, const struct peer_update *peer_update UNNEEDED) { fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index fd62f10bd7bc..21c9290c8da8 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -103,7 +103,7 @@ void status_fmt(enum log_level level UNNEEDED, { fprintf(stderr, "status_fmt called!\n"); abort(); } /* Generated stub for towire_gossipd_remote_channel_update */ -u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct remote_priv_update *update UNNEEDED) +u8 *towire_gossipd_remote_channel_update(const tal_t *ctx UNNEEDED, const struct node_id *source_node UNNEEDED, const struct peer_update *peer_update UNNEEDED) { fprintf(stderr, "towire_gossipd_remote_channel_update called!\n"); abort(); } /* Generated stub for towire_warningfmt */ u8 *towire_warningfmt(const tal_t *ctx UNNEEDED, diff --git a/lightningd/channel.c b/lightningd/channel.c index 562b7e7672ca..e9994db6ed73 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -264,7 +264,7 @@ struct channel *new_unsaved_channel(struct peer *peer, = CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE; channel->shutdown_wrong_funding = NULL; channel->closing_feerate_range = NULL; - channel->private_update = NULL; + channel->peer_update = NULL; channel->channel_update = NULL; channel->alias[LOCAL] = channel->alias[REMOTE] = NULL; @@ -430,7 +430,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, struct amount_msat htlc_maximum_msat, bool ignore_fee_limits, /* NULL or stolen */ - struct remote_priv_update *private_update STEALS) + struct peer_update *peer_update STEALS) { struct channel *channel = tal(peer->ld, struct channel); struct amount_msat htlc_min, htlc_max; @@ -556,7 +556,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->lease_commit_sig = tal_steal(channel, lease_commit_sig); channel->lease_chan_max_msat = lease_chan_max_msat; channel->lease_chan_max_ppt = lease_chan_max_ppt; - channel->private_update = tal_steal(channel, private_update); + channel->peer_update = tal_steal(channel, peer_update); channel->blockheight_states = dup_height_states(channel, height_states); channel->channel_update = NULL; diff --git a/lightningd/channel.h b/lightningd/channel.h index 7da224273747..bf70c249ae9d 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -298,9 +298,9 @@ struct channel { /* Lease commited max part per thousandth channel fee (ppm * 1000) */ u16 lease_chan_max_ppt; - /* Private channel incoming fee rates, cltv delta min/max htlc from + /* Channel incoming fee rates, cltv delta min/max htlc from * peer. Used to generate route hints, blinded paths. */ - struct remote_priv_update *private_update; + const struct peer_update *peer_update; /* Latest channel_update, for use in error messages. */ u8 *channel_update; @@ -390,7 +390,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, struct amount_msat htlc_maximum_msat, bool ignore_fee_limits, /* NULL or stolen */ - struct remote_priv_update *private_update STEALS); + struct peer_update *peer_update STEALS); /* new_inflight - Create a new channel_inflight for a channel */ struct channel_inflight *new_inflight(struct channel *channel, diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index e96dcf34f5a6..4378f6c1a26a 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -175,7 +175,8 @@ const u8 *get_channel_update(struct channel *channel) static void set_channel_remote_update(struct lightningd *ld, struct channel *channel, - struct remote_priv_update* update TAKES) + const struct node_id *source, + struct peer_update *update TAKES) { struct short_channel_id *scid; @@ -183,11 +184,11 @@ static void set_channel_remote_update(struct lightningd *ld, if (!scid) scid = channel->alias[LOCAL]; - if (!node_id_eq(&update->source_node, &channel->peer->id)) { + /* NULL source means it's from gossipd itself */ + if (source && !node_id_eq(source, &channel->peer->id)) { log_unusual(ld->log, "Bad gossip order: %s sent us a channel update for a " "channel owned by %s (%s)", - type_to_string(tmpctx, struct node_id, - &update->source_node), + type_to_string(tmpctx, struct node_id, source), type_to_string(tmpctx, struct node_id, &channel->peer->id), type_to_string(tmpctx, struct short_channel_id, scid)); @@ -197,31 +198,32 @@ static void set_channel_remote_update(struct lightningd *ld, } log_debug(ld->log, "updating channel %s with private inbound settings", type_to_string(tmpctx, struct short_channel_id, scid)); - tal_free(channel->private_update); - channel->private_update = tal_dup(channel, - struct remote_priv_update, update); + tal_free(channel->peer_update); + channel->peer_update = tal_dup(channel, struct peer_update, update); if (taken(update)) tal_free(update); wallet_channel_save(ld->wallet, channel); } -static void handle_private_update_data(struct lightningd *ld, const u8 *msg) +static void handle_peer_update_data(struct lightningd *ld, const u8 *msg) { struct channel *channel; - struct remote_priv_update *update; + struct peer_update *update; + struct node_id *source; - update = tal(tmpctx, struct remote_priv_update); - if (!fromwire_gossipd_remote_channel_update(msg, update)) + update = tal(tmpctx, struct peer_update); + if (!fromwire_gossipd_remote_channel_update(msg, msg, &source, update)) fatal("Gossip gave bad GOSSIPD_REMOTE_CHANNEL_UPDATE %s", tal_hex(msg, msg)); channel = any_channel_by_scid(ld, &update->scid, true); if (!channel) { - log_unusual(ld->log, "could not find channel for peer's " - "private channel update"); + log_unusual(ld->log, "Bad gossip: could not find channel %s for peer's " + "channel update", + short_channel_id_to_str(tmpctx, &update->scid)); return; } - set_channel_remote_update(ld, channel, update); + set_channel_remote_update(ld, channel, source, update); } static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) @@ -267,7 +269,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) break; case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE: /* Please stash in database for us! */ - handle_private_update_data(gossip->ld, msg); + handle_peer_update_data(gossip->ld, msg); tal_free(msg); break; } diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index f3e7a51f6c3e..bb6afec36ac5 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -178,7 +178,7 @@ struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED, struct amount_msat htlc_maximum_msat UNNEEDED, bool ignore_fee_limits UNNEEDED, /* NULL or stolen */ - struct remote_priv_update* remote_update STEALS UNNEEDED) + struct peer_update *peer_update STEALS 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, diff --git a/wallet/wallet.c b/wallet/wallet.c index a740193b5a82..12723c336725 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1514,7 +1514,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm u32 lease_chan_max_msat; u16 lease_chan_max_ppt; bool ignore_fee_limits; - struct remote_priv_update *remote_update; + struct peer_update *remote_update; peer_dbid = db_col_u64(stmt, "peer_id"); peer = find_peer_by_dbid(w->ld, peer_dbid); @@ -1680,8 +1680,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm } if (!db_col_is_null(stmt, "remote_cltv_expiry_delta")) { - remote_update = tal(NULL, struct remote_priv_update); - remote_update->source_node = peer->id; + remote_update = tal(NULL, struct peer_update); if (scid) remote_update->scid = *scid; else @@ -2354,12 +2353,12 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_null(stmt); db_bind_int(stmt, chan->ignore_fee_limits); - if (chan->private_update) { - db_bind_int(stmt, chan->private_update->fee_base); - db_bind_int(stmt, chan->private_update->fee_ppm); - db_bind_int(stmt, chan->private_update->cltv_delta); - db_bind_amount_msat(stmt, &chan->private_update->htlc_minimum_msat); - db_bind_amount_msat(stmt, &chan->private_update->htlc_maximum_msat); + if (chan->peer_update) { + db_bind_int(stmt, chan->peer_update->fee_base); + db_bind_int(stmt, chan->peer_update->fee_ppm); + db_bind_int(stmt, chan->peer_update->cltv_delta); + db_bind_amount_msat(stmt, &chan->peer_update->htlc_minimum_msat); + db_bind_amount_msat(stmt, &chan->peer_update->htlc_maximum_msat); } else { db_bind_null(stmt); db_bind_null(stmt); From cc215c4b1546e2b0f290d98c87dc8a7b110164d5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 08/29] listpeerchannels: show gossip updates. This is redundant if it's a public channel, but vital if it's not. Publishing unconditionally makes it easier for gossmap: we create a local modification all the time, even if redundant (and we can have the actual capacity ceiling accurate in this case, since we know it for local channels). Signed-off-by: Rusty Russell Changelog-Added: JSON-RPC: `listpeerchannels` now shows gossip update contents (even if channel unannounced). --- .msggen.json | 73 +++- cln-grpc/proto/node.proto | 22 ++ cln-grpc/src/convert.rs | 37 ++ cln-rpc/src/model.rs | 38 ++ contrib/msggen/msggen/patch.py | 1 + contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py | 370 +++++++++--------- contrib/pyln-testing/pyln/testing/grpc2py.py | 25 ++ doc/lightning-listpeerchannels.7.md | 15 +- doc/lightning-sql.7.md | 12 +- doc/schemas/listpeerchannels.schema.json | 95 +++++ lightningd/peer_control.c | 32 ++ tests/test_plugin.py | 20 + 12 files changed, 555 insertions(+), 185 deletions(-) diff --git a/.msggen.json b/.msggen.json index 0d4f6417215f..15381b47ea17 100644 --- a/.msggen.json +++ b/.msggen.json @@ -1171,7 +1171,8 @@ "ListPeerChannels.channels[].their_reserve_msat": 31, "ListPeerChannels.channels[].their_to_self_delay": 38, "ListPeerChannels.channels[].to_us_msat": 23, - "ListPeerChannels.channels[].total_msat": 26 + "ListPeerChannels.channels[].total_msat": 26, + "ListPeerChannels.channels[].updates": 55 }, "ListpeerchannelsChannelsAlias": { "ListPeerChannels.channels[].alias.local": 1, @@ -1218,6 +1219,24 @@ "ListPeerChannels.channels[].state_changes[].old_state": 2, "ListPeerChannels.channels[].state_changes[].timestamp": 1 }, + "ListpeerchannelsChannelsUpdates": { + "ListPeerChannels.channels[].updates.local": 1, + "ListPeerChannels.channels[].updates.remote": 2 + }, + "ListpeerchannelsChannelsUpdatesLocal": { + "ListPeerChannels.channels[].updates.local.cltv_expiry_delta": 3, + "ListPeerChannels.channels[].updates.local.fee_base_msat": 4, + "ListPeerChannels.channels[].updates.local.fee_proportional_millionths": 5, + "ListPeerChannels.channels[].updates.local.htlc_maximum_msat": 2, + "ListPeerChannels.channels[].updates.local.htlc_minimum_msat": 1 + }, + "ListpeerchannelsChannelsUpdatesRemote": { + "ListPeerChannels.channels[].updates.remote.cltv_expiry_delta": 3, + "ListPeerChannels.channels[].updates.remote.fee_base_msat": 4, + "ListPeerChannels.channels[].updates.remote.fee_proportional_millionths": 5, + "ListPeerChannels.channels[].updates.remote.htlc_maximum_msat": 2, + "ListPeerChannels.channels[].updates.remote.htlc_minimum_msat": 1 + }, "ListpeerchannelsRequest": { "ListPeerChannels.id": 1 }, @@ -4511,6 +4530,58 @@ "added": "v23.02", "deprecated": false }, + "ListPeerChannels.channels[].updates": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local.cltv_expiry_delta": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local.fee_base_msat": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local.fee_proportional_millionths": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local.htlc_maximum_msat": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.local.htlc_minimum_msat": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote.cltv_expiry_delta": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote.fee_base_msat": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote.fee_proportional_millionths": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote.htlc_maximum_msat": { + "added": "v24.02", + "deprecated": false + }, + "ListPeerChannels.channels[].updates.remote.htlc_minimum_msat": { + "added": "v24.02", + "deprecated": false + }, "ListPeerChannels.id": { "added": "v23.02", "deprecated": false diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index 8d7ed3086d47..d936b793f4e1 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -1190,6 +1190,7 @@ message ListpeerchannelsChannels { optional bool peer_connected = 2; optional ListpeerchannelsChannelsState state = 3; optional bytes scratch_txid = 4; + optional ListpeerchannelsChannelsUpdates updates = 55; optional bool ignore_fee_limits = 54; optional ListpeerchannelsChannelsFeerate feerate = 6; optional string owner = 7; @@ -1239,6 +1240,27 @@ message ListpeerchannelsChannels { optional string close_to_addr = 53; } +message ListpeerchannelsChannelsUpdates { + optional ListpeerchannelsChannelsUpdatesLocal local = 1; + optional ListpeerchannelsChannelsUpdatesRemote remote = 2; +} + +message ListpeerchannelsChannelsUpdatesLocal { + optional Amount htlc_minimum_msat = 1; + optional Amount htlc_maximum_msat = 2; + optional uint32 cltv_expiry_delta = 3; + optional Amount fee_base_msat = 4; + optional uint32 fee_proportional_millionths = 5; +} + +message ListpeerchannelsChannelsUpdatesRemote { + optional Amount htlc_minimum_msat = 1; + optional Amount htlc_maximum_msat = 2; + optional uint32 cltv_expiry_delta = 3; + optional Amount fee_base_msat = 4; + optional uint32 fee_proportional_millionths = 5; +} + message ListpeerchannelsChannelsFeerate { optional uint32 perkw = 1; optional uint32 perkb = 2; diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 5f6693fcd22b..599550239cea 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -1014,6 +1014,42 @@ impl From for pb::TxsendResponse { } } +#[allow(unused_variables)] +impl From for pb::ListpeerchannelsChannelsUpdatesLocal { + fn from(c: responses::ListpeerchannelsChannelsUpdatesLocal) -> Self { + Self { + htlc_minimum_msat: c.htlc_minimum_msat.map(|f| f.into()), // Rule #2 for type msat? + htlc_maximum_msat: c.htlc_maximum_msat.map(|f| f.into()), // Rule #2 for type msat? + cltv_expiry_delta: c.cltv_expiry_delta, // Rule #2 for type u32? + fee_base_msat: c.fee_base_msat.map(|f| f.into()), // Rule #2 for type msat? + fee_proportional_millionths: c.fee_proportional_millionths, // Rule #2 for type u32? + } + } +} + +#[allow(unused_variables)] +impl From for pb::ListpeerchannelsChannelsUpdatesRemote { + fn from(c: responses::ListpeerchannelsChannelsUpdatesRemote) -> Self { + Self { + htlc_minimum_msat: c.htlc_minimum_msat.map(|f| f.into()), // Rule #2 for type msat? + htlc_maximum_msat: c.htlc_maximum_msat.map(|f| f.into()), // Rule #2 for type msat? + cltv_expiry_delta: c.cltv_expiry_delta, // Rule #2 for type u32? + fee_base_msat: c.fee_base_msat.map(|f| f.into()), // Rule #2 for type msat? + fee_proportional_millionths: c.fee_proportional_millionths, // Rule #2 for type u32? + } + } +} + +#[allow(unused_variables)] +impl From for pb::ListpeerchannelsChannelsUpdates { + fn from(c: responses::ListpeerchannelsChannelsUpdates) -> Self { + Self { + local: c.local.map(|v| v.into()), + remote: c.remote.map(|v| v.into()), + } + } +} + #[allow(unused_variables)] impl From for pb::ListpeerchannelsChannelsFeerate { fn from(c: responses::ListpeerchannelsChannelsFeerate) -> Self { @@ -1086,6 +1122,7 @@ impl From for pb::ListpeerchannelsChannels peer_connected: c.peer_connected, // Rule #2 for type boolean? state: c.state.map(|v| v as i32), scratch_txid: c.scratch_txid.map(|v| hex::decode(v).unwrap()), // Rule #2 for type txid? + updates: c.updates.map(|v| v.into()), ignore_fee_limits: c.ignore_fee_limits, // Rule #2 for type boolean? feerate: c.feerate.map(|v| v.into()), owner: c.owner, // Rule #2 for type string? diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index 5cb6576fc1b6..14d702904d5a 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -4007,6 +4007,42 @@ pub mod responses { } } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListpeerchannelsChannelsUpdatesLocal { + #[serde(skip_serializing_if = "Option::is_none")] + pub htlc_minimum_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub htlc_maximum_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub cltv_expiry_delta: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_base_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_proportional_millionths: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListpeerchannelsChannelsUpdatesRemote { + #[serde(skip_serializing_if = "Option::is_none")] + pub htlc_minimum_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub htlc_maximum_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub cltv_expiry_delta: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_base_msat: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub fee_proportional_millionths: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListpeerchannelsChannelsUpdates { + #[serde(skip_serializing_if = "Option::is_none")] + pub local: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub remote: Option, + } + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ListpeerchannelsChannelsFeerate { #[serde(skip_serializing_if = "Option::is_none")] @@ -4115,6 +4151,8 @@ pub mod responses { #[serde(skip_serializing_if = "Option::is_none")] pub scratch_txid: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub updates: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub ignore_fee_limits: Option, #[serde(skip_serializing_if = "Option::is_none")] pub feerate: Option, diff --git a/contrib/msggen/msggen/patch.py b/contrib/msggen/msggen/patch.py index 8d2cf3e7b94f..24e9a85af2b7 100644 --- a/contrib/msggen/msggen/patch.py +++ b/contrib/msggen/msggen/patch.py @@ -109,6 +109,7 @@ class OptionalPatch(Patch): 'v23.05', 'v23.08', 'v23.11', + 'v24.02', ] # Oldest supported versions. Bump this if you no longer want to # support older versions, and you want to make required fields diff --git a/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py b/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py index 2e54f125d12e..23bfdcbc76d8 100644 --- a/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py +++ b/contrib/pyln-grpc-proto/pyln/grpc/node_pb2.py @@ -14,7 +14,7 @@ from pyln.grpc import primitives_pb2 as primitives__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nnode.proto\x12\x03\x63ln\x1a\x10primitives.proto\"\x10\n\x0eGetinfoRequest\"\xc1\x04\n\x0fGetinfoResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x61lias\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\r\n\x05\x63olor\x18\x03 \x01(\x0c\x12\x11\n\tnum_peers\x18\x04 \x01(\r\x12\x1c\n\x14num_pending_channels\x18\x05 \x01(\r\x12\x1b\n\x13num_active_channels\x18\x06 \x01(\r\x12\x1d\n\x15num_inactive_channels\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\rlightning_dir\x18\t \x01(\t\x12\x33\n\x0cour_features\x18\n \x01(\x0b\x32\x18.cln.GetinfoOur_featuresH\x01\x88\x01\x01\x12\x13\n\x0b\x62lockheight\x18\x0b \x01(\r\x12\x0f\n\x07network\x18\x0c \x01(\t\x12(\n\x13\x66\x65\x65s_collected_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x07\x61\x64\x64ress\x18\x0e \x03(\x0b\x32\x13.cln.GetinfoAddress\x12$\n\x07\x62inding\x18\x0f \x03(\x0b\x32\x13.cln.GetinfoBinding\x12\"\n\x15warning_bitcoind_sync\x18\x10 \x01(\tH\x02\x88\x01\x01\x12$\n\x17warning_lightningd_sync\x18\x11 \x01(\tH\x03\x88\x01\x01\x42\x08\n\x06_aliasB\x0f\n\r_our_featuresB\x18\n\x16_warning_bitcoind_syncB\x1a\n\x18_warning_lightningd_sync\"S\n\x13GetinfoOur_features\x12\x0c\n\x04init\x18\x01 \x01(\x0c\x12\x0c\n\x04node\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\x0c\x12\x0f\n\x07invoice\x18\x04 \x01(\x0c\"\xc4\x01\n\x0eGetinfoAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoAddress.GetinfoAddressType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"G\n\x12GetinfoAddressType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"\x8a\x02\n\x0eGetinfoBinding\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoBinding.GetinfoBindingType\x12\x14\n\x07\x61\x64\x64ress\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06socket\x18\x04 \x01(\tH\x02\x88\x01\x01\"_\n\x12GetinfoBindingType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\r\n\tWEBSOCKET\x10\x05\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_addressB\x07\n\x05_portB\t\n\x07_socket\"H\n\x10ListpeersRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\x05level\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_idB\x08\n\x06_level\"7\n\x11ListpeersResponse\x12\"\n\x05peers\x18\x01 \x03(\x0b\x32\x13.cln.ListpeersPeers\"\x8e\x02\n\x0eListpeersPeers\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x11\n\tconnected\x18\x02 \x01(\x08\x12\x19\n\x0cnum_channels\x18\x08 \x01(\rH\x00\x88\x01\x01\x12#\n\x03log\x18\x03 \x03(\x0b\x32\x16.cln.ListpeersPeersLog\x12-\n\x08\x63hannels\x18\x04 \x03(\x0b\x32\x1b.cln.ListpeersPeersChannels\x12\x0f\n\x07netaddr\x18\x05 \x03(\t\x12\x18\n\x0bremote_addr\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x42\x0f\n\r_num_channelsB\x0e\n\x0c_remote_addrB\x0b\n\t_features\"\xfd\x02\n\x11ListpeersPeersLog\x12?\n\titem_type\x18\x01 \x01(\x0e\x32,.cln.ListpeersPeersLog.ListpeersPeersLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"i\n\x15ListpeersPeersLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"\x95\x18\n\x16ListpeersPeersChannels\x12\x46\n\x05state\x18\x01 \x01(\x0e\x32\x37.cln.ListpeersPeersChannels.ListpeersPeersChannelsState\x12\x19\n\x0cscratch_txid\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x38\n\x07\x66\x65\x65rate\x18\x03 \x01(\x0b\x32\".cln.ListpeersPeersChannelsFeerateH\x01\x88\x01\x01\x12\x12\n\x05owner\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x17\n\nchannel_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\x07 \x01(\x0cH\x05\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x08 \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\t \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\n \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0b \x01(\tH\t\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0c \x01(\rH\n\x88\x01\x01\x12\x35\n\x08inflight\x18\r \x03(\x0b\x32#.cln.ListpeersPeersChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x0e \x01(\x0cH\x0b\x88\x01\x01\x12\x14\n\x07private\x18\x0f \x01(\x08H\x0c\x88\x01\x01\x12 \n\x06opener\x18\x10 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x11 \x01(\x0e\x32\x10.cln.ChannelSideH\r\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x12 \x03(\t\x12\x38\n\x07\x66unding\x18\x13 \x01(\x0b\x32\".cln.ListpeersPeersChannelsFundingH\x0e\x88\x01\x01\x12$\n\nto_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.AmountH\x0f\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.AmountH\x10\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x16 \x01(\x0b\x32\x0b.cln.AmountH\x11\x88\x01\x01\x12$\n\ntotal_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x12\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x13\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x19 \x01(\rH\x14\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12*\n\x10our_reserve_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12(\n\x0espendable_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12)\n\x0freceivable_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18\x30 \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12 \n\x13their_to_self_delay\x18! \x01(\rH\x1e\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\" \x01(\rH\x1f\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18# \x01(\rH \x88\x01\x01\x12\x34\n\x05\x61lias\x18\x32 \x01(\x0b\x32 .cln.ListpeersPeersChannelsAliasH!\x88\x01\x01\x12\x0e\n\x06status\x18% \x03(\t\x12 \n\x13in_payments_offered\x18& \x01(\x04H\"\x88\x01\x01\x12)\n\x0fin_offered_msat\x18\' \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18( \x01(\x04H$\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18) \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12!\n\x14out_payments_offered\x18* \x01(\x04H&\x88\x01\x01\x12*\n\x10out_offered_msat\x18+ \x01(\x0b\x32\x0b.cln.AmountH\'\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18, \x01(\x04H(\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH)\x88\x01\x01\x12/\n\x05htlcs\x18. \x03(\x0b\x32 .cln.ListpeersPeersChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18/ \x01(\tH*\x88\x01\x01\"\xe0\x02\n\x1bListpeersPeersChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0b\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\x0c\x42\x0f\n\r_scratch_txidB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addr\"=\n\x1dListpeersPeersChannelsFeerate\x12\r\n\x05perkw\x18\x01 \x01(\r\x12\r\n\x05perkb\x18\x02 \x01(\r\"\xf3\x01\n\x1eListpeersPeersChannelsInflight\x12\x14\n\x0c\x66unding_txid\x18\x01 \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\x02 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x03 \x01(\t\x12\'\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x00\x88\x01\x01\x12\x14\n\x0cscratch_txid\x18\x06 \x01(\x0c\x42\x10\n\x0e_splice_amount\"\x9b\x02\n\x1dListpeersPeersChannelsFunding\x12%\n\x0bpushed_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12%\n\x10local_funds_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11remote_funds_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\rfee_paid_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"[\n\x1bListpeersPeersChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xf1\x02\n\x1bListpeersPeersChannelsHtlcs\x12X\n\tdirection\x18\x01 \x01(\x0e\x32\x45.cln.ListpeersPeersChannelsHtlcs.ListpeersPeersChannelsHtlcsDirection\x12\n\n\x02id\x18\x02 \x01(\x04\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcState\"7\n$ListpeersPeersChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x10\n\x0e_local_trimmedB\t\n\x07_status\"0\n\x10ListfundsRequest\x12\x12\n\x05spent\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_spent\"e\n\x11ListfundsResponse\x12&\n\x07outputs\x18\x01 \x03(\x0b\x32\x15.cln.ListfundsOutputs\x12(\n\x08\x63hannels\x18\x02 \x03(\x0b\x32\x16.cln.ListfundsChannels\"\x83\x03\n\x10ListfundsOutputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06output\x18\x02 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptpubkey\x18\x04 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0credeemscript\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12<\n\x06status\x18\x07 \x01(\x0e\x32,.cln.ListfundsOutputs.ListfundsOutputsStatus\x12\x10\n\x08reserved\x18\t \x01(\x08\x12\x18\n\x0b\x62lockheight\x18\x08 \x01(\rH\x02\x88\x01\x01\"Q\n\x16ListfundsOutputsStatus\x12\x0f\n\x0bUNCONFIRMED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\t\n\x05SPENT\x10\x02\x12\x0c\n\x08IMMATURE\x10\x03\x42\n\n\x08_addressB\x0f\n\r_redeemscriptB\x0e\n\x0c_blockheight\"\xab\x02\n\x11ListfundsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12$\n\x0four_amount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x04 \x01(\x0c\x12\x16\n\x0e\x66unding_output\x18\x05 \x01(\r\x12\x11\n\tconnected\x18\x06 \x01(\x08\x12 \n\x05state\x18\x07 \x01(\x0e\x32\x11.cln.ChannelState\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x00\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x01\x88\x01\x01\x42\r\n\x0b_channel_idB\x13\n\x11_short_channel_id\"\xdd\x02\n\x0eSendpayRequest\x12 \n\x05route\x18\x01 \x03(\x0b\x32\x11.cln.SendpayRoute\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0b \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\t \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\x11\n\x0f_payment_secretB\t\n\x07_partidB\x10\n\x0e_localinvreqidB\n\n\x08_groupid\"\xad\x05\n\x0fSendpayResponse\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x01\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x02\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x32\n\x06status\x18\x04 \x01(\x0e\x32\".cln.SendpayResponse.SendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12\x19\n\x0c\x63ompleted_at\x18\x0f \x01(\x04H\x05\x88\x01\x01\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x07\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\t\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\n\x88\x01\x01\x12\x14\n\x07message\x18\x0e \x01(\tH\x0b\x88\x01\x01\"*\n\rSendpayStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_message\"\\\n\x0cSendpayRoute\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\n\n\x02id\x18\x02 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\t\"\x93\x01\n\x13ListchannelsRequest\x12\x1d\n\x10short_channel_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06source\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\t\n\x07_sourceB\x0e\n\x0c_destination\"C\n\x14ListchannelsResponse\x12+\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x19.cln.ListchannelsChannels\"\xb3\x03\n\x14ListchannelsChannels\x12\x0e\n\x06source\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x03 \x01(\t\x12\x11\n\tdirection\x18\x10 \x01(\r\x12\x0e\n\x06public\x18\x04 \x01(\x08\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\rmessage_flags\x18\x06 \x01(\r\x12\x15\n\rchannel_flags\x18\x07 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x08 \x01(\x08\x12\x13\n\x0blast_update\x18\t \x01(\r\x12\x1d\n\x15\x62\x61se_fee_millisatoshi\x18\n \x01(\r\x12\x19\n\x11\x66\x65\x65_per_millionth\x18\x0b \x01(\r\x12\r\n\x05\x64\x65lay\x18\x0c \x01(\r\x12&\n\x11htlc_minimum_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x11htlc_maximum_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x0f \x01(\x0c\x42\x14\n\x12_htlc_maximum_msat\"#\n\x10\x41\x64\x64gossipRequest\x12\x0f\n\x07message\x18\x01 \x01(\x0c\"\x13\n\x11\x41\x64\x64gossipResponse\"o\n\x17\x41utocleaninvoiceRequest\x12\x17\n\nexpired_by\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds\"\x81\x01\n\x18\x41utocleaninvoiceResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\nexpired_by\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x03 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds\"U\n\x13\x43heckmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05zbase\x18\x02 \x01(\t\x12\x13\n\x06pubkey\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey\"8\n\x14\x43heckmessageResponse\x12\x10\n\x08verified\x18\x01 \x01(\x08\x12\x0e\n\x06pubkey\x18\x02 \x01(\x0c\"\xcb\x02\n\x0c\x43loseRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x11unilateraltimeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x66\x65\x65_negotiation_step\x18\x04 \x01(\tH\x02\x88\x01\x01\x12)\n\rwrong_funding\x18\x05 \x01(\x0b\x32\r.cln.OutpointH\x03\x88\x01\x01\x12\x1f\n\x12\x66orce_lease_closed\x18\x06 \x01(\x08H\x04\x88\x01\x01\x12\x1e\n\x08\x66\x65\x65range\x18\x07 \x03(\x0b\x32\x0c.cln.FeerateB\x14\n\x12_unilateraltimeoutB\x0e\n\x0c_destinationB\x17\n\x15_fee_negotiation_stepB\x10\n\x0e_wrong_fundingB\x15\n\x13_force_lease_closed\"\xab\x01\n\rCloseResponse\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.CloseResponse.CloseType\x12\x0f\n\x02tx\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04txid\x18\x03 \x01(\x0cH\x01\x88\x01\x01\"5\n\tCloseType\x12\n\n\x06MUTUAL\x10\x00\x12\x0e\n\nUNILATERAL\x10\x01\x12\x0c\n\x08UNOPENED\x10\x02\x42\x05\n\x03_txB\x07\n\x05_txid\"T\n\x0e\x43onnectRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x04host\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_hostB\x07\n\x05_port\"\xb4\x01\n\x0f\x43onnectResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0c\x12\x38\n\tdirection\x18\x03 \x01(\x0e\x32%.cln.ConnectResponse.ConnectDirection\x12$\n\x07\x61\x64\x64ress\x18\x04 \x01(\x0b\x32\x13.cln.ConnectAddress\"#\n\x10\x43onnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\xfb\x01\n\x0e\x43onnectAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.ConnectAddress.ConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"P\n\x12\x43onnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"J\n\x14\x43reateinvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\"\xfe\x05\n\x15\x43reateinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12>\n\x06status\x18\x06 \x01(\x0e\x32..cln.CreateinvoiceResponse.CreateinvoiceStatus\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12;\n\rpaid_outpoint\x18\x11 \x01(\x0b\x32\x1f.cln.CreateinvoicePaid_outpointH\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x08\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\r \x01(\x0cH\t\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\n\x88\x01\x01\"8\n\x13\x43reateinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x10\n\x0e_created_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimageB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_note\"X\n\x1a\x43reateinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\xb4\x02\n\x10\x44\x61tastoreRequest\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x13\n\x06string\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x36\n\x04mode\x18\x03 \x01(\x0e\x32#.cln.DatastoreRequest.DatastoreModeH\x02\x88\x01\x01\x12\x17\n\ngeneration\x18\x04 \x01(\x04H\x03\x88\x01\x01\"p\n\rDatastoreMode\x12\x0f\n\x0bMUST_CREATE\x10\x00\x12\x10\n\x0cMUST_REPLACE\x10\x01\x12\x15\n\x11\x43REATE_OR_REPLACE\x10\x02\x12\x0f\n\x0bMUST_APPEND\x10\x03\x12\x14\n\x10\x43REATE_OR_APPEND\x10\x04\x42\t\n\x07_stringB\x06\n\x04_hexB\x07\n\x05_modeB\r\n\x0b_generation\"\x82\x01\n\x11\x44\x61tastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\x17\n\x15\x44\x61tastoreusageRequest\"k\n\x16\x44\x61tastoreusageResponse\x12>\n\x0e\x64\x61tastoreusage\x18\x01 \x01(\x0b\x32!.cln.DatastoreusageDatastoreusageH\x00\x88\x01\x01\x42\x11\n\x0f_datastoreusage\"b\n\x1c\x44\x61tastoreusageDatastoreusage\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0btotal_bytes\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x06\n\x04_keyB\x0e\n\x0c_total_bytes\"\x9d\x01\n\x12\x43reateonionRequest\x12\"\n\x04hops\x18\x01 \x03(\x0b\x32\x14.cln.CreateonionHops\x12\x11\n\tassocdata\x18\x02 \x01(\x0c\x12\x18\n\x0bsession_key\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x17\n\nonion_size\x18\x04 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_session_keyB\r\n\x0b_onion_size\"<\n\x13\x43reateonionResponse\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x16\n\x0eshared_secrets\x18\x02 \x03(\x0c\"2\n\x0f\x43reateonionHops\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x13\x44\x65ldatastoreRequest\x12\x0b\n\x03key\x18\x03 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x42\r\n\x0b_generation\"\x85\x01\n\x14\x44\x65ldatastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"H\n\x18\x44\x65lexpiredinvoiceRequest\x12\x1a\n\rmaxexpirytime\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\x10\n\x0e_maxexpirytime\"\x1b\n\x19\x44\x65lexpiredinvoiceResponse\"\xb6\x01\n\x11\x44\x65linvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\x12\x37\n\x06status\x18\x02 \x01(\x0e\x32\'.cln.DelinvoiceRequest.DelinvoiceStatus\x12\x15\n\x08\x64\x65sconly\x18\x03 \x01(\x08H\x00\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\x0b\n\t_desconly\"\xa1\x04\n\x12\x44\x65linvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x04\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x05\x88\x01\x01\x12\x38\n\x06status\x18\x07 \x01(\x0e\x32(.cln.DelinvoiceResponse.DelinvoiceStatus\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x06\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0b \x01(\tH\x07\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_note\"\xfa\x01\n\x0eInvoiceRequest\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x10.cln.AmountOrAny\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\x12\x13\n\x06\x65xpiry\x18\x07 \x01(\x04H\x00\x88\x01\x01\x12\x11\n\tfallbacks\x18\x04 \x03(\t\x12\x15\n\x08preimage\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x11\n\x04\x63ltv\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x19\n\x0c\x64\x65schashonly\x18\t \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_expiryB\x0b\n\t_preimageB\x07\n\x05_cltvB\x0f\n\r_deschashonly\"\x95\x03\n\x0fInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x03 \x01(\x0c\x12\x12\n\nexpires_at\x18\x04 \x01(\x04\x12\x1a\n\rcreated_index\x18\n \x01(\x04H\x00\x88\x01\x01\x12\x1d\n\x10warning_capacity\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1c\n\x0fwarning_offline\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10warning_deadends\x18\x07 \x01(\tH\x03\x88\x01\x01\x12#\n\x16warning_private_unused\x18\x08 \x01(\tH\x04\x88\x01\x01\x12\x18\n\x0bwarning_mpp\x18\t \x01(\tH\x05\x88\x01\x01\x42\x10\n\x0e_created_indexB\x13\n\x11_warning_capacityB\x12\n\x10_warning_offlineB\x13\n\x11_warning_deadendsB\x19\n\x17_warning_private_unusedB\x0e\n\x0c_warning_mpp\"#\n\x14ListdatastoreRequest\x12\x0b\n\x03key\x18\x02 \x03(\t\"G\n\x15ListdatastoreResponse\x12.\n\tdatastore\x18\x01 \x03(\x0b\x32\x1b.cln.ListdatastoreDatastore\"\x87\x01\n\x16ListdatastoreDatastore\x12\x0b\n\x03key\x18\x01 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xde\x02\n\x13ListinvoicesRequest\x12\x12\n\x05label\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tinvstring\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08offer_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12>\n\x05index\x18\x05 \x01(\x0e\x32*.cln.ListinvoicesRequest.ListinvoicesIndexH\x04\x88\x01\x01\x12\x12\n\x05start\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x12\n\x05limit\x18\x07 \x01(\rH\x06\x88\x01\x01\"-\n\x11ListinvoicesIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\x08\n\x06_labelB\x0c\n\n_invstringB\x0f\n\r_payment_hashB\x0b\n\t_offer_idB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListinvoicesResponse\x12+\n\x08invoices\x18\x01 \x03(\x0b\x32\x19.cln.ListinvoicesInvoices\"\xd4\x06\n\x14ListinvoicesInvoices\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListinvoicesInvoices.ListinvoicesInvoicesStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x07\x88\x01\x01\x12\x16\n\tpay_index\x18\x0b \x01(\x04H\x08\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\t\x88\x01\x01\x12\x14\n\x07paid_at\x18\r \x01(\x04H\n\x88\x01\x01\x12\x42\n\rpaid_outpoint\x18\x12 \x01(\x0b\x32&.cln.ListinvoicesInvoicesPaid_outpointH\x0b\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0e \x01(\x0cH\x0c\x88\x01\x01\"?\n\x1aListinvoicesInvoicesStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"_\n!ListinvoicesInvoicesPaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\x8a\x03\n\x10SendonionRequest\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12*\n\tfirst_hop\x18\x02 \x01(\x0b\x32\x17.cln.SendonionFirst_hop\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\x05label\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eshared_secrets\x18\x05 \x03(\x0c\x12\x13\n\x06partid\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\r \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x10\n\x0e_localinvreqidB\n\n\x08_groupid\"\xe7\x04\n\x11SendonionResponse\x12\x1a\n\rcreated_index\x18\x0e \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x36\n\x06status\x18\x03 \x01(\x0e\x32&.cln.SendonionResponse.SendonionStatus\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x05 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x06 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06partid\x18\r \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0f \x01(\x04H\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0b \x01(\x0cH\x08\x88\x01\x01\x12\x14\n\x07message\x18\x0c \x01(\tH\t\x88\x01\x01\",\n\x0fSendonionStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x10\n\x0e_created_indexB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\t\n\x07_partidB\x10\n\x0e_updated_indexB\x13\n\x11_payment_preimageB\n\n\x08_message\"Q\n\x12SendonionFirst_hop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\"\xa0\x03\n\x13ListsendpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12@\n\x06status\x18\x03 \x01(\x0e\x32+.cln.ListsendpaysRequest.ListsendpaysStatusH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListsendpaysRequest.ListsendpaysIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\";\n\x12ListsendpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"-\n\x11ListsendpaysIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_statusB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListsendpaysResponse\x12+\n\x08payments\x18\x01 \x03(\x0b\x32\x19.cln.ListsendpaysPayments\"\xd0\x05\n\x14ListsendpaysPayments\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07groupid\x18\x02 \x01(\x04\x12\x13\n\x06partid\x18\x0f \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x02\x88\x01\x01\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListsendpaysPayments.ListsendpaysPaymentsStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\n \x01(\tH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\x12\x17\n\nerroronion\x18\r \x01(\x0cH\n\x88\x01\x01\"C\n\x1aListsendpaysPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x10\n\x0e_created_indexB\t\n\x07_partidB\x10\n\x0e_updated_indexB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\r\n\x0b_erroronion\"\x19\n\x17ListtransactionsRequest\"S\n\x18ListtransactionsResponse\x12\x37\n\x0ctransactions\x18\x01 \x03(\x0b\x32!.cln.ListtransactionsTransactions\"\xf8\x01\n\x1cListtransactionsTransactions\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\r\n\x05rawtx\x18\x02 \x01(\x0c\x12\x13\n\x0b\x62lockheight\x18\x03 \x01(\r\x12\x0f\n\x07txindex\x18\x04 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x37\n\x06inputs\x18\t \x03(\x0b\x32\'.cln.ListtransactionsTransactionsInputs\x12\x39\n\x07outputs\x18\n \x03(\x0b\x32(.cln.ListtransactionsTransactionsOutputs\"S\n\"ListtransactionsTransactionsInputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\"l\n#ListtransactionsTransactionsOutputs\x12\r\n\x05index\x18\x01 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptPubKey\x18\x03 \x01(\x0c\"\xda\x03\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\nriskfactor\x18\x08 \x01(\x01H\x02\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x03\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x05\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0e \x01(\x0cH\x07\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\n \x03(\t\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0c \x01(\tH\t\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x08\n\x06_labelB\r\n\x0b_riskfactorB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\x10\n\x0e_localinvreqidB\t\n\x07_maxfeeB\x0e\n\x0c_description\"\xfb\x02\n\x0bPayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12*\n\x06status\x18\t \x01(\x0e\x32\x1a.cln.PayResponse.PayStatus\"2\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"*\n\x10ListnodesRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListnodesResponse\x12\"\n\x05nodes\x18\x01 \x03(\x0b\x32\x13.cln.ListnodesNodes\"\xe1\x01\n\x0eListnodesNodes\x12\x0e\n\x06nodeid\x18\x01 \x01(\x0c\x12\x1b\n\x0elast_timestamp\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05\x63olor\x18\x04 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12/\n\taddresses\x18\x06 \x03(\x0b\x32\x1c.cln.ListnodesNodesAddressesB\x11\n\x0f_last_timestampB\x08\n\x06_aliasB\x08\n\x06_colorB\x0b\n\t_features\"\xe8\x01\n\x17ListnodesNodesAddresses\x12K\n\titem_type\x18\x01 \x01(\x0e\x32\x38.cln.ListnodesNodesAddresses.ListnodesNodesAddressesType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"P\n\x1bListnodesNodesAddressesType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"g\n\x15WaitanyinvoiceRequest\x12\x1a\n\rlastpay_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x10\n\x0e_lastpay_indexB\n\n\x08_timeout\"\xbf\x05\n\x16WaitanyinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12@\n\x06status\x18\x04 \x01(\x0e\x32\x30.cln.WaitanyinvoiceResponse.WaitanyinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x07\x88\x01\x01\x12<\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32 .cln.WaitanyinvoicePaid_outpointH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\"-\n\x14WaitanyinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"Y\n\x1bWaitanyinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"#\n\x12WaitinvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\"\xb0\x05\n\x13WaitinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitinvoiceResponse.WaitinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x07\x88\x01\x01\x12\x39\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32\x1d.cln.WaitinvoicePaid_outpointH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\"*\n\x11WaitinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"V\n\x18WaitinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\x8e\x01\n\x12WaitsendpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x14\n\x07timeout\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06partid\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x02\x88\x01\x01\x42\n\n\x08_timeoutB\t\n\x07_partidB\n\n\x08_groupid\"\x8e\x05\n\x13WaitsendpayResponse\x12\x1a\n\rcreated_index\x18\x0f \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitsendpayResponse.WaitsendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12\x1a\n\rupdated_index\x18\x10 \x01(\x04H\x04\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0e \x01(\x01H\x05\x88\x01\x01\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x07\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\t\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\n\x88\x01\x01\"!\n\x11WaitsendpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x10\n\x0e_created_indexB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x10\n\x0e_updated_indexB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimage\"\x97\x01\n\x0eNewaddrRequest\x12@\n\x0b\x61\x64\x64resstype\x18\x01 \x01(\x0e\x32&.cln.NewaddrRequest.NewaddrAddresstypeH\x00\x88\x01\x01\"3\n\x12NewaddrAddresstype\x12\n\n\x06\x42\x45\x43H32\x10\x00\x12\x08\n\x04P2TR\x10\x03\x12\x07\n\x03\x41LL\x10\x02\x42\x0e\n\x0c_addresstype\"w\n\x0fNewaddrResponse\x12\x11\n\x04p2tr\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62\x65\x63h32\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bp2sh_segwit\x18\x02 \x01(\tH\x02\x88\x01\x01\x42\x07\n\x05_p2trB\t\n\x07_bech32B\x0e\n\x0c_p2sh_segwit\"\xca\x01\n\x0fWithdrawRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\t\x12&\n\x07satoshi\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAllH\x00\x88\x01\x01\x12\"\n\x07\x66\x65\x65rate\x18\x05 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_satoshiB\n\n\x08_feerateB\n\n\x08_minconf\":\n\x10WithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0c\n\x04psbt\x18\x03 \x01(\t\"\x82\x03\n\x0eKeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12+\n\nroutehints\x18\x08 \x01(\x0b\x32\x12.cln.RoutehintListH\x05\x88\x01\x01\x12&\n\textratlvs\x18\t \x01(\x0b\x32\x0e.cln.TlvStreamH\x06\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_routehintsB\x0c\n\n_extratlvs\"\xf2\x02\n\x0fKeysendResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x32\n\x06status\x18\t \x01(\x0e\x32\".cln.KeysendResponse.KeysendStatus\"\x1d\n\rKeysendStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"\xa4\x03\n\x0f\x46undpsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x14\n\x07minconf\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x17\n\nnonwrapped\x18\t \x01(\x08H\x05\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\r\n\x0b_nonwrappedB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10\x46undpsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.FundpsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14\x46undpsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"A\n\x0fSendpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_reserve\",\n\x10SendpsbtResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"1\n\x0fSignpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x10\n\x08signonly\x18\x02 \x03(\r\"\'\n\x10SignpsbtResponse\x12\x13\n\x0bsigned_psbt\x18\x01 \x01(\t\"\x9b\x03\n\x0fUtxopsbtRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x17\n\nreservedok\x18\x08 \x01(\x08H\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\t \x01(\x08H\x04\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_reserveB\r\n\x0b_reservedokB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10UtxopsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.UtxopsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14UtxopsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\" \n\x10TxdiscardRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"6\n\x11TxdiscardResponse\x12\x13\n\x0bunsigned_tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa4\x01\n\x10TxprepareRequest\x12 \n\x07outputs\x18\x05 \x03(\x0b\x32\x0f.cln.OutputDesc\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_feerateB\n\n\x08_minconf\"D\n\x11TxprepareResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x13\n\x0bunsigned_tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"\x1d\n\rTxsendRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"8\n\x0eTxsendResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"1\n\x17ListpeerchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"K\n\x18ListpeerchannelsResponse\x12/\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1d.cln.ListpeerchannelsChannels\"\xda\x19\n\x18ListpeerchannelsChannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x1b\n\x0epeer_connected\x18\x02 \x01(\x08H\x01\x88\x01\x01\x12O\n\x05state\x18\x03 \x01(\x0e\x32;.cln.ListpeerchannelsChannels.ListpeerchannelsChannelsStateH\x02\x88\x01\x01\x12\x19\n\x0cscratch_txid\x18\x04 \x01(\x0cH\x03\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x36 \x01(\x08H\x04\x88\x01\x01\x12:\n\x07\x66\x65\x65rate\x18\x06 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFeerateH\x05\x88\x01\x01\x12\x12\n\x05owner\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x07\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x08\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\n \x01(\x0cH\t\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\x0c \x01(\tH\x0b\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\r \x01(\tH\x0c\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0e \x01(\tH\r\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0f \x01(\rH\x0e\x88\x01\x01\x12\x37\n\x08inflight\x18\x10 \x03(\x0b\x32%.cln.ListpeerchannelsChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x11 \x01(\x0cH\x0f\x88\x01\x01\x12\x14\n\x07private\x18\x12 \x01(\x08H\x10\x88\x01\x01\x12%\n\x06opener\x18\x13 \x01(\x0e\x32\x10.cln.ChannelSideH\x11\x88\x01\x01\x12%\n\x06\x63loser\x18\x14 \x01(\x0e\x32\x10.cln.ChannelSideH\x12\x88\x01\x01\x12:\n\x07\x66unding\x18\x16 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFundingH\x13\x88\x01\x01\x12$\n\nto_us_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x14\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x19 \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12$\n\ntotal_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x1c \x01(\rH\x19\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12*\n\x10our_reserve_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12(\n\x0espendable_msat\x18! \x01(\x0b\x32\x0b.cln.AmountH\x1e\x88\x01\x01\x12)\n\x0freceivable_msat\x18\" \x01(\x0b\x32\x0b.cln.AmountH\x1f\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18# \x01(\x0b\x32\x0b.cln.AmountH \x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18$ \x01(\x0b\x32\x0b.cln.AmountH!\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18% \x01(\x0b\x32\x0b.cln.AmountH\"\x88\x01\x01\x12 \n\x13their_to_self_delay\x18& \x01(\rH#\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\' \x01(\rH$\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18( \x01(\rH%\x88\x01\x01\x12\x36\n\x05\x61lias\x18) \x01(\x0b\x32\".cln.ListpeerchannelsChannelsAliasH&\x88\x01\x01\x12\x0e\n\x06status\x18+ \x03(\t\x12 \n\x13in_payments_offered\x18, \x01(\x04H\'\x88\x01\x01\x12)\n\x0fin_offered_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH(\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18. \x01(\x04H)\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18/ \x01(\x0b\x32\x0b.cln.AmountH*\x88\x01\x01\x12!\n\x14out_payments_offered\x18\x30 \x01(\x04H+\x88\x01\x01\x12*\n\x10out_offered_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH,\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18\x32 \x01(\x04H-\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18\x33 \x01(\x0b\x32\x0b.cln.AmountH.\x88\x01\x01\x12\x31\n\x05htlcs\x18\x34 \x03(\x0b\x32\".cln.ListpeerchannelsChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18\x35 \x01(\tH/\x88\x01\x01\"\x80\x03\n\x1dListpeerchannelsChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x43HANNELD_AWAITING_SPLICE\x10\x0b\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0c\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\rB\n\n\x08_peer_idB\x11\n\x0f_peer_connectedB\x08\n\x06_stateB\x0f\n\r_scratch_txidB\x14\n\x12_ignore_fee_limitsB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_openerB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addr\"]\n\x1fListpeerchannelsChannelsFeerate\x12\x12\n\x05perkw\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05perkb\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x08\n\x06_perkwB\x08\n\x06_perkb\"\x80\x03\n ListpeerchannelsChannelsInflight\x12\x19\n\x0c\x66unding_txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x03 \x01(\tH\x02\x88\x01\x01\x12,\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x04\x88\x01\x01\x12*\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x19\n\x0cscratch_txid\x18\x06 \x01(\x0cH\x06\x88\x01\x01\x42\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\n\n\x08_feerateB\x15\n\x13_total_funding_msatB\x10\n\x0e_splice_amountB\x13\n\x11_our_funding_msatB\x0f\n\r_scratch_txid\"\xd2\x02\n\x1fListpeerchannelsChannelsFunding\x12%\n\x0bpushed_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12*\n\x10local_funds_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12+\n\x11remote_funds_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\'\n\rfee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x13\n\x11_local_funds_msatB\x14\n\x12_remote_funds_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"]\n\x1dListpeerchannelsChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xe2\x03\n\x1dListpeerchannelsChannelsHtlcs\x12\x61\n\tdirection\x18\x01 \x01(\x0e\x32I.cln.ListpeerchannelsChannelsHtlcs.ListpeerchannelsChannelsHtlcsDirectionH\x00\x88\x01\x01\x12\x0f\n\x02id\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x05 \x01(\x0cH\x04\x88\x01\x01\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\"\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcStateH\x07\x88\x01\x01\"9\n&ListpeerchannelsChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x0c\n\n_directionB\x05\n\x03_idB\x0e\n\x0c_amount_msatB\t\n\x07_expiryB\x0f\n\r_payment_hashB\x10\n\x0e_local_trimmedB\t\n\x07_statusB\x08\n\x06_state\"3\n\x19ListclosedchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"[\n\x1aListclosedchannelsResponse\x12=\n\x0e\x63losedchannels\x18\x01 \x03(\x0b\x32%.cln.ListclosedchannelsClosedchannels\"\xb2\t\n ListclosedchannelsClosedchannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x12>\n\x05\x61lias\x18\x04 \x01(\x0b\x32*.cln.ListclosedchannelsClosedchannelsAliasH\x02\x88\x01\x01\x12 \n\x06opener\x18\x05 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x06 \x01(\x0e\x32\x10.cln.ChannelSideH\x03\x88\x01\x01\x12\x0f\n\x07private\x18\x07 \x01(\x08\x12\x1f\n\x17total_local_commitments\x18\t \x01(\x04\x12 \n\x18total_remote_commitments\x18\n \x01(\x04\x12\x18\n\x10total_htlcs_sent\x18\x0b \x01(\x04\x12\x14\n\x0c\x66unding_txid\x18\x0c \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\r \x01(\r\x12\x0e\n\x06leased\x18\x0e \x01(\x08\x12/\n\x15\x66unding_fee_paid_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12/\n\x15\x66unding_fee_rcvd_msat\x18\x10 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12-\n\x13\x66unding_pushed_msat\x18\x11 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1f\n\ntotal_msat\x18\x12 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x66inal_to_us_msat\x18\x13 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emin_to_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emax_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.Amount\x12!\n\x14last_commitment_txid\x18\x16 \x01(\x0cH\x07\x88\x01\x01\x12\x32\n\x18last_commitment_fee_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x66\n\x0b\x63lose_cause\x18\x18 \x01(\x0e\x32Q.cln.ListclosedchannelsClosedchannels.ListclosedchannelsClosedchannelsClose_cause\"v\n+ListclosedchannelsClosedchannelsClose_cause\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05LOCAL\x10\x01\x12\x08\n\x04USER\x10\x02\x12\n\n\x06REMOTE\x10\x03\x12\x0c\n\x08PROTOCOL\x10\x04\x12\x0b\n\x07ONCHAIN\x10\x05\x42\n\n\x08_peer_idB\x13\n\x11_short_channel_idB\x08\n\x06_aliasB\t\n\x07_closerB\x18\n\x16_funding_fee_paid_msatB\x18\n\x16_funding_fee_rcvd_msatB\x16\n\x14_funding_pushed_msatB\x17\n\x15_last_commitment_txidB\x1b\n\x19_last_commitment_fee_msat\"e\n%ListclosedchannelsClosedchannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"L\n\x10\x44\x65\x63odepayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x04\n\x11\x44\x65\x63odepayResponse\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\x04\x12\r\n\x05payee\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x11\n\tsignature\x18\x07 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x1d\n\x15min_final_cltv_expiry\x18\n \x01(\r\x12\x1b\n\x0epayment_secret\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\r \x01(\x0cH\x05\x88\x01\x01\x12*\n\tfallbacks\x18\x0e \x03(\x0b\x32\x17.cln.DecodepayFallbacks\x12\"\n\x05\x65xtra\x18\x10 \x03(\x0b\x32\x13.cln.DecodepayExtraB\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x13\n\x11_description_hashB\x11\n\x0f_payment_secretB\x0b\n\t_featuresB\x13\n\x11_payment_metadata\"\xd0\x01\n\x12\x44\x65\x63odepayFallbacks\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.DecodepayFallbacks.DecodepayFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x0b\n\x03hex\x18\x03 \x01(\x0c\"N\n\x16\x44\x65\x63odepayFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42\x07\n\x05_addr\"+\n\x0e\x44\x65\x63odepayExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x1f\n\rDecodeRequest\x12\x0e\n\x06string\x18\x01 \x01(\t\"\xe8!\n\x0e\x44\x65\x63odeResponse\x12\x31\n\titem_type\x18\x01 \x01(\x0e\x32\x1e.cln.DecodeResponse.DecodeType\x12\r\n\x05valid\x18\x02 \x01(\x08\x12\x15\n\x08offer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0coffer_chains\x18\x04 \x03(\x0c\x12\x1b\n\x0eoffer_metadata\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0eoffer_currency\x18\x06 \x01(\tH\x02\x88\x01\x01\x12+\n\x1ewarning_unknown_offer_currency\x18\x07 \x01(\tH\x03\x88\x01\x01\x12 \n\x13\x63urrency_minor_unit\x18\x08 \x01(\rH\x04\x88\x01\x01\x12\x19\n\x0coffer_amount\x18\t \x01(\x04H\x05\x88\x01\x01\x12+\n\x11offer_amount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1e\n\x11offer_description\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0coffer_issuer\x18\x0c \x01(\tH\x08\x88\x01\x01\x12\x1b\n\x0eoffer_features\x18\r \x01(\x0cH\t\x88\x01\x01\x12\"\n\x15offer_absolute_expiry\x18\x0e \x01(\x04H\n\x88\x01\x01\x12\x1f\n\x12offer_quantity_max\x18\x0f \x01(\x04H\x0b\x88\x01\x01\x12+\n\x0boffer_paths\x18\x10 \x03(\x0b\x32\x16.cln.DecodeOffer_paths\x12\x1a\n\roffer_node_id\x18\x11 \x01(\x0cH\x0c\x88\x01\x01\x12*\n\x1dwarning_missing_offer_node_id\x18\x14 \x01(\tH\r\x88\x01\x01\x12.\n!warning_invalid_offer_description\x18\x15 \x01(\tH\x0e\x88\x01\x01\x12.\n!warning_missing_offer_description\x18\x16 \x01(\tH\x0f\x88\x01\x01\x12+\n\x1ewarning_invalid_offer_currency\x18\x17 \x01(\tH\x10\x88\x01\x01\x12)\n\x1cwarning_invalid_offer_issuer\x18\x18 \x01(\tH\x11\x88\x01\x01\x12\x1c\n\x0finvreq_metadata\x18\x19 \x01(\x0cH\x12\x88\x01\x01\x12\x1c\n\x0finvreq_payer_id\x18\x1a \x01(\x0cH\x13\x88\x01\x01\x12\x19\n\x0cinvreq_chain\x18\x1b \x01(\x0cH\x14\x88\x01\x01\x12,\n\x12invreq_amount_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x1c\n\x0finvreq_features\x18\x1d \x01(\x0cH\x16\x88\x01\x01\x12\x1c\n\x0finvreq_quantity\x18\x1e \x01(\x04H\x17\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x1f \x01(\tH\x18\x88\x01\x01\x12&\n\x19invreq_recurrence_counter\x18 \x01(\rH\x19\x88\x01\x01\x12$\n\x17invreq_recurrence_start\x18! \x01(\rH\x1a\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_metadata\x18# \x01(\tH\x1b\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_payer_id\x18$ \x01(\tH\x1c\x88\x01\x01\x12.\n!warning_invalid_invreq_payer_note\x18% \x01(\tH\x1d\x88\x01\x01\x12\x36\n)warning_missing_invoice_request_signature\x18& \x01(\tH\x1e\x88\x01\x01\x12\x36\n)warning_invalid_invoice_request_signature\x18\' \x01(\tH\x1f\x88\x01\x01\x12\x1f\n\x12invoice_created_at\x18) \x01(\x04H \x88\x01\x01\x12$\n\x17invoice_relative_expiry\x18* \x01(\rH!\x88\x01\x01\x12!\n\x14invoice_payment_hash\x18+ \x01(\x0cH\"\x88\x01\x01\x12-\n\x13invoice_amount_msat\x18, \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\x37\n\x11invoice_fallbacks\x18- \x03(\x0b\x32\x1c.cln.DecodeInvoice_fallbacks\x12\x1d\n\x10invoice_features\x18. \x01(\x0cH$\x88\x01\x01\x12\x1c\n\x0finvoice_node_id\x18/ \x01(\x0cH%\x88\x01\x01\x12(\n\x1binvoice_recurrence_basetime\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x1dwarning_missing_invoice_paths\x18\x32 \x01(\tH\'\x88\x01\x01\x12/\n\"warning_missing_invoice_blindedpay\x18\x33 \x01(\tH(\x88\x01\x01\x12/\n\"warning_missing_invoice_created_at\x18\x34 \x01(\tH)\x88\x01\x01\x12\x31\n$warning_missing_invoice_payment_hash\x18\x35 \x01(\tH*\x88\x01\x01\x12+\n\x1ewarning_missing_invoice_amount\x18\x36 \x01(\tH+\x88\x01\x01\x12\x38\n+warning_missing_invoice_recurrence_basetime\x18\x37 \x01(\tH,\x88\x01\x01\x12,\n\x1fwarning_missing_invoice_node_id\x18\x38 \x01(\tH-\x88\x01\x01\x12.\n!warning_missing_invoice_signature\x18\x39 \x01(\tH.\x88\x01\x01\x12.\n!warning_invalid_invoice_signature\x18: \x01(\tH/\x88\x01\x01\x12\'\n\tfallbacks\x18; \x03(\x0b\x32\x14.cln.DecodeFallbacks\x12\x17\n\ncreated_at\x18< \x01(\x04H0\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18= \x01(\x04H1\x88\x01\x01\x12\x12\n\x05payee\x18> \x01(\x0cH2\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18? \x01(\x0cH3\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18@ \x01(\x0cH4\x88\x01\x01\x12\"\n\x15min_final_cltv_expiry\x18\x41 \x01(\rH5\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x42 \x01(\x0cH6\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x43 \x01(\x0cH7\x88\x01\x01\x12\x1f\n\x05\x65xtra\x18\x45 \x03(\x0b\x32\x10.cln.DecodeExtra\x12\x16\n\tunique_id\x18\x46 \x01(\tH8\x88\x01\x01\x12\x14\n\x07version\x18G \x01(\tH9\x88\x01\x01\x12\x13\n\x06string\x18H \x01(\tH:\x88\x01\x01\x12-\n\x0crestrictions\x18I \x03(\x0b\x32\x17.cln.DecodeRestrictions\x12&\n\x19warning_rune_invalid_utf8\x18J \x01(\tH;\x88\x01\x01\x12\x10\n\x03hex\x18K \x01(\x0cH<\x88\x01\x01\x12\x16\n\tdecrypted\x18L \x01(\x0cH=\x88\x01\x01\"\x83\x01\n\nDecodeType\x12\x10\n\x0c\x42OLT12_OFFER\x10\x00\x12\x12\n\x0e\x42OLT12_INVOICE\x10\x01\x12\x1a\n\x16\x42OLT12_INVOICE_REQUEST\x10\x02\x12\x12\n\x0e\x42OLT11_INVOICE\x10\x03\x12\x08\n\x04RUNE\x10\x04\x12\x15\n\x11\x45MERGENCY_RECOVER\x10\x05\x42\x0b\n\t_offer_idB\x11\n\x0f_offer_metadataB\x11\n\x0f_offer_currencyB!\n\x1f_warning_unknown_offer_currencyB\x16\n\x14_currency_minor_unitB\x0f\n\r_offer_amountB\x14\n\x12_offer_amount_msatB\x14\n\x12_offer_descriptionB\x0f\n\r_offer_issuerB\x11\n\x0f_offer_featuresB\x18\n\x16_offer_absolute_expiryB\x15\n\x13_offer_quantity_maxB\x10\n\x0e_offer_node_idB \n\x1e_warning_missing_offer_node_idB$\n\"_warning_invalid_offer_descriptionB$\n\"_warning_missing_offer_descriptionB!\n\x1f_warning_invalid_offer_currencyB\x1f\n\x1d_warning_invalid_offer_issuerB\x12\n\x10_invreq_metadataB\x12\n\x10_invreq_payer_idB\x0f\n\r_invreq_chainB\x15\n\x13_invreq_amount_msatB\x12\n\x10_invreq_featuresB\x12\n\x10_invreq_quantityB\x14\n\x12_invreq_payer_noteB\x1c\n\x1a_invreq_recurrence_counterB\x1a\n\x18_invreq_recurrence_startB\"\n _warning_missing_invreq_metadataB\"\n _warning_missing_invreq_payer_idB$\n\"_warning_invalid_invreq_payer_noteB,\n*_warning_missing_invoice_request_signatureB,\n*_warning_invalid_invoice_request_signatureB\x15\n\x13_invoice_created_atB\x1a\n\x18_invoice_relative_expiryB\x17\n\x15_invoice_payment_hashB\x16\n\x14_invoice_amount_msatB\x13\n\x11_invoice_featuresB\x12\n\x10_invoice_node_idB\x1e\n\x1c_invoice_recurrence_basetimeB \n\x1e_warning_missing_invoice_pathsB%\n#_warning_missing_invoice_blindedpayB%\n#_warning_missing_invoice_created_atB\'\n%_warning_missing_invoice_payment_hashB!\n\x1f_warning_missing_invoice_amountB.\n,_warning_missing_invoice_recurrence_basetimeB\"\n _warning_missing_invoice_node_idB$\n\"_warning_missing_invoice_signatureB$\n\"_warning_invalid_invoice_signatureB\r\n\x0b_created_atB\t\n\x07_expiryB\x08\n\x06_payeeB\x0f\n\r_payment_hashB\x13\n\x11_description_hashB\x18\n\x16_min_final_cltv_expiryB\x11\n\x0f_payment_secretB\x13\n\x11_payment_metadataB\x0c\n\n_unique_idB\n\n\x08_versionB\t\n\x07_stringB\x1c\n\x1a_warning_rune_invalid_utf8B\x06\n\x04_hexB\x0c\n\n_decrypted\"<\n\x11\x44\x65\x63odeOffer_paths\x12\x15\n\rfirst_node_id\x18\x01 \x01(\x0c\x12\x10\n\x08\x62linding\x18\x02 \x01(\x0c\"\x8a\x01\n\x1f\x44\x65\x63odeOffer_recurrencePaywindow\x12\x16\n\x0eseconds_before\x18\x01 \x01(\r\x12\x15\n\rseconds_after\x18\x02 \x01(\r\x12 \n\x13proportional_amount\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\x16\n\x14_proportional_amount\"T\n\x17\x44\x65\x63odeInvoice_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"Y\n\x17\x44\x65\x63odeInvoice_fallbacks\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0b\n\x03hex\x18\x02 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_address\"w\n\x0f\x44\x65\x63odeFallbacks\x12\x36\n)warning_invoice_fallbacks_version_invalid\x18\x01 \x01(\tH\x00\x88\x01\x01\x42,\n*_warning_invoice_fallbacks_version_invalid\"(\n\x0b\x44\x65\x63odeExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\";\n\x12\x44\x65\x63odeRestrictions\x12\x14\n\x0c\x61lternatives\x18\x01 \x03(\t\x12\x0f\n\x07summary\x18\x02 \x01(\t\"=\n\x11\x44isconnectRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x66orce\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_force\"\x14\n\x12\x44isconnectResponse\"k\n\x0f\x46\x65\x65ratesRequest\x12\x31\n\x05style\x18\x01 \x01(\x0e\x32\".cln.FeeratesRequest.FeeratesStyle\"%\n\rFeeratesStyle\x12\t\n\x05PERKB\x10\x00\x12\t\n\x05PERKW\x10\x01\"\x9c\x02\n\x10\x46\x65\x65ratesResponse\x12%\n\x18warning_missing_feerates\x18\x01 \x01(\tH\x00\x88\x01\x01\x12&\n\x05perkb\x18\x02 \x01(\x0b\x32\x12.cln.FeeratesPerkbH\x01\x88\x01\x01\x12&\n\x05perkw\x18\x03 \x01(\x0b\x32\x12.cln.FeeratesPerkwH\x02\x88\x01\x01\x12\x46\n\x15onchain_fee_estimates\x18\x04 \x01(\x0b\x32\".cln.FeeratesOnchain_fee_estimatesH\x03\x88\x01\x01\x42\x1b\n\x19_warning_missing_feeratesB\x08\n\x06_perkbB\x08\n\x06_perkwB\x18\n\x16_onchain_fee_estimates\"\xd3\x03\n\rFeeratesPerkb\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x00\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkbEstimates\x12\x14\n\x07opening\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x07\x88\x01\x01\x42\x08\n\x06_floorB\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x1a\n\x18_unilateral_anchor_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty\"\x96\x01\n\x16\x46\x65\x65ratesPerkbEstimates\x12\x17\n\nblockcount\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10smoothed_feerate\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\r\n\x0b_blockcountB\n\n\x08_feerateB\x13\n\x11_smoothed_feerate\"\xd3\x03\n\rFeeratesPerkw\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x00\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkwEstimates\x12\x14\n\x07opening\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x07\x88\x01\x01\x42\x08\n\x06_floorB\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x1a\n\x18_unilateral_anchor_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty\"\x96\x01\n\x16\x46\x65\x65ratesPerkwEstimates\x12\x17\n\nblockcount\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10smoothed_feerate\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\r\n\x0b_blockcountB\n\n\x08_feerateB\x13\n\x11_smoothed_feerate\"\x9b\x02\n\x1d\x46\x65\x65ratesOnchain_fee_estimates\x12 \n\x18opening_channel_satoshis\x18\x01 \x01(\x04\x12\x1d\n\x15mutual_close_satoshis\x18\x02 \x01(\x04\x12!\n\x19unilateral_close_satoshis\x18\x03 \x01(\x04\x12\x30\n#unilateral_close_nonanchor_satoshis\x18\x06 \x01(\x04H\x00\x88\x01\x01\x12\x1d\n\x15htlc_timeout_satoshis\x18\x04 \x01(\x04\x12\x1d\n\x15htlc_success_satoshis\x18\x05 \x01(\x04\x42&\n$_unilateral_close_nonanchor_satoshis\"\xe9\x02\n\x13\x46\x65tchinvoiceRequest\x12\r\n\x05offer\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x15\n\x08quantity\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x1f\n\x12recurrence_counter\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x10recurrence_start\x18\x05 \x01(\x01H\x03\x88\x01\x01\x12\x1d\n\x10recurrence_label\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07timeout\x18\x07 \x01(\x01H\x05\x88\x01\x01\x12\x17\n\npayer_note\x18\x08 \x01(\tH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0b\n\t_quantityB\x15\n\x13_recurrence_counterB\x13\n\x11_recurrence_startB\x13\n\x11_recurrence_labelB\n\n\x08_timeoutB\r\n\x0b_payer_note\"\x9a\x01\n\x14\x46\x65tchinvoiceResponse\x12\x0f\n\x07invoice\x18\x01 \x01(\t\x12)\n\x07\x63hanges\x18\x02 \x01(\x0b\x32\x18.cln.FetchinvoiceChanges\x12\x36\n\x0bnext_period\x18\x03 \x01(\x0b\x32\x1c.cln.FetchinvoiceNext_periodH\x00\x88\x01\x01\x42\x0e\n\x0c_next_period\"\x82\x02\n\x13\x46\x65tchinvoiceChanges\x12!\n\x14\x64\x65scription_appended\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0evendor_removed\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06vendor\x18\x04 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x17\n\x15_description_appendedB\x0e\n\x0c_descriptionB\x11\n\x0f_vendor_removedB\t\n\x07_vendorB\x0e\n\x0c_amount_msat\"~\n\x17\x46\x65tchinvoiceNext_period\x12\x0f\n\x07\x63ounter\x18\x01 \x01(\x04\x12\x11\n\tstarttime\x18\x02 \x01(\x04\x12\x0f\n\x07\x65ndtime\x18\x03 \x01(\x04\x12\x17\n\x0fpaywindow_start\x18\x04 \x01(\x04\x12\x15\n\rpaywindow_end\x18\x05 \x01(\x04\"\xe5\x03\n\x12\x46undchannelRequest\x12\n\n\x02id\x18\t \x01(\x0c\x12 \n\x06\x61mount\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\x07minconf\x18\n \x01(\rH\x02\x88\x01\x01\x12#\n\tpush_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x04\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x05utxos\x18\x0b \x03(\x0b\x32\r.cln.Outpoint\x12\x15\n\x08mindepth\x18\x0c \x01(\rH\x07\x88\x01\x01\x12!\n\x07reserve\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x42\n\n\x08_feerateB\x0b\n\t_announceB\n\n\x08_minconfB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\x0b\n\t_mindepthB\n\n\x08_reserve\"\x9b\x01\n\x13\x46undchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0e\n\x06outnum\x18\x03 \x01(\r\x12\x12\n\nchannel_id\x18\x04 \x01(\x0c\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x01\x88\x01\x01\x42\x0b\n\t_close_toB\x0b\n\t_mindepth\"\xec\x01\n\x0fGetrouteRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\nriskfactor\x18\x03 \x01(\x04\x12\x11\n\x04\x63ltv\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06\x66romid\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x66uzzpercent\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\x07 \x03(\t\x12\x14\n\x07maxhops\x18\x08 \x01(\rH\x03\x88\x01\x01\x42\x07\n\x05_cltvB\t\n\x07_fromidB\x0e\n\x0c_fuzzpercentB\n\n\x08_maxhops\"5\n\x10GetrouteResponse\x12!\n\x05route\x18\x01 \x03(\x0b\x32\x12.cln.GetrouteRoute\"\xc5\x01\n\rGetrouteRoute\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\t\x12\x11\n\tdirection\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\r\x12\x34\n\x05style\x18\x06 \x01(\x0e\x32%.cln.GetrouteRoute.GetrouteRouteStyle\"\x1d\n\x12GetrouteRouteStyle\x12\x07\n\x03TLV\x10\x00\"\xb7\x03\n\x13ListforwardsRequest\x12@\n\x06status\x18\x01 \x01(\x0e\x32+.cln.ListforwardsRequest.ListforwardsStatusH\x00\x88\x01\x01\x12\x17\n\nin_channel\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x03 \x01(\tH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListforwardsRequest.ListforwardsIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\"L\n\x12ListforwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"-\n\x11ListforwardsIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_statusB\r\n\x0b_in_channelB\x0e\n\x0c_out_channelB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListforwardsResponse\x12+\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x19.cln.ListforwardsForwards\"\xba\x05\n\x14ListforwardsForwards\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x00\x88\x01\x01\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\x01\x88\x01\x01\x12\x1c\n\x07in_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x44\n\x06status\x18\x03 \x01(\x0e\x32\x34.cln.ListforwardsForwards.ListforwardsForwardsStatus\x12\x15\n\rreceived_time\x18\x04 \x01(\x01\x12\x18\n\x0bout_channel\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x18\n\x0bout_htlc_id\x18\x0b \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x04\x88\x01\x01\x12G\n\x05style\x18\t \x01(\x0e\x32\x33.cln.ListforwardsForwards.ListforwardsForwardsStyleH\x05\x88\x01\x01\x12\"\n\x08\x66\x65\x65_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\"\n\x08out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\"T\n\x1aListforwardsForwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"0\n\x19ListforwardsForwardsStyle\x12\n\n\x06LEGACY\x10\x00\x12\x07\n\x03TLV\x10\x01\x42\x10\n\x0e_created_indexB\r\n\x0b_in_htlc_idB\x0e\n\x0c_out_channelB\x0e\n\x0c_out_htlc_idB\x10\n\x0e_updated_indexB\x08\n\x06_styleB\x0b\n\t_fee_msatB\x0b\n\t_out_msat\"\xdb\x01\n\x0fListpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x38\n\x06status\x18\x03 \x01(\x0e\x32#.cln.ListpaysRequest.ListpaysStatusH\x02\x88\x01\x01\"7\n\x0eListpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status\"3\n\x10ListpaysResponse\x12\x1f\n\x04pays\x18\x01 \x03(\x0b\x32\x11.cln.ListpaysPays\"\xff\x04\n\x0cListpaysPays\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x34\n\x06status\x18\x02 \x01(\x0e\x32$.cln.ListpaysPays.ListpaysPaysStatus\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\ncreated_at\x18\x04 \x01(\x04\x12\x19\n\x0c\x63ompleted_at\x18\x0c \x01(\x04H\x01\x88\x01\x01\x12\x12\n\x05label\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x06 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0b \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x05\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12*\n\x10\x61mount_sent_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x12\x15\n\x08preimage\x18\r \x01(\x0cH\x08\x88\x01\x01\x12\x1c\n\x0fnumber_of_parts\x18\x0e \x01(\x04H\t\x88\x01\x01\x12\x17\n\nerroronion\x18\n \x01(\x0cH\n\x88\x01\x01\";\n\x12ListpaysPaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_destinationB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x13\n\x11_amount_sent_msatB\x0b\n\t_preimageB\x12\n\x10_number_of_partsB\r\n\x0b_erroronion\"*\n\x10ListhtlcsRequest\x12\x0f\n\x02id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListhtlcsResponse\x12\"\n\x05htlcs\x18\x01 \x03(\x0b\x32\x13.cln.ListhtlcsHtlcs\"\x89\x02\n\x0eListhtlcsHtlcs\x12\x18\n\x10short_channel_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12>\n\tdirection\x18\x05 \x01(\x0e\x32+.cln.ListhtlcsHtlcs.ListhtlcsHtlcsDirection\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1d\n\x05state\x18\x07 \x01(\x0e\x32\x0e.cln.HtlcState\"*\n\x17ListhtlcsHtlcsDirection\x12\x07\n\x03OUT\x10\x00\x12\x06\n\x02IN\x10\x01\"Y\n\x0bPingRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x03len\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x16\n\tpongbytes\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x06\n\x04_lenB\x0c\n\n_pongbytes\"\x1e\n\x0cPingResponse\x12\x0e\n\x06totlen\x18\x01 \x01(\r\"4\n\x14SendcustommsgRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"\'\n\x15SendcustommsgResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\"\xaa\x02\n\x11SetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12!\n\x07\x66\x65\x65\x62\x61se\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x66\x65\x65ppm\x18\x03 \x01(\rH\x01\x88\x01\x01\x12!\n\x07htlcmin\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12!\n\x07htlcmax\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x19\n\x0c\x65nforcedelay\x18\x06 \x01(\rH\x04\x88\x01\x01\x12\x1c\n\x0fignorefeelimits\x18\x07 \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_feebaseB\t\n\x07_feeppmB\n\n\x08_htlcminB\n\n\x08_htlcmaxB\x0f\n\r_enforcedelayB\x12\n\x10_ignorefeelimits\"?\n\x12SetchannelResponse\x12)\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x17.cln.SetchannelChannels\"\xca\x03\n\x12SetchannelChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\x12\x1e\n\x11ignore_fee_limits\x18\n \x01(\x08H\x01\x88\x01\x01\x12*\n\x15minimum_htlc_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x17warning_htlcmin_too_low\x18\x07 \x01(\tH\x02\x88\x01\x01\x12*\n\x15maximum_htlc_out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x18warning_htlcmax_too_high\x18\t \x01(\tH\x03\x88\x01\x01\x42\x13\n\x11_short_channel_idB\x14\n\x12_ignore_fee_limitsB\x1a\n\x18_warning_htlcmin_too_lowB\x1b\n\x19_warning_htlcmax_too_high\"\'\n\x12SigninvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\"%\n\x13SigninvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"%\n\x12SignmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\"F\n\x13SignmessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\r\n\x05recid\x18\x02 \x01(\x0c\x12\r\n\x05zbase\x18\x03 \x01(\t\"O\n\x16WaitblockheightRequest\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\x12\x14\n\x07timeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_timeout\".\n\x17WaitblockheightResponse\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\"\xf9\x01\n\x0bWaitRequest\x12\x31\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitSubsystem\x12\x31\n\tindexname\x18\x02 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitIndexname\x12\x11\n\tnextvalue\x18\x03 \x01(\x04\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\"6\n\rWaitIndexname\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x12\x0b\n\x07\x44\x45LETED\x10\x02\"\xe3\x01\n\x0cWaitResponse\x12\x32\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1f.cln.WaitResponse.WaitSubsystem\x12\x14\n\x07\x63reated\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07updated\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07\x64\x65leted\x18\x04 \x01(\x04H\x02\x88\x01\x01\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\x42\n\n\x08_createdB\n\n\x08_updatedB\n\n\x08_deleted\"\r\n\x0bStopRequest\"\x0e\n\x0cStopResponse\"\xa7\x01\n\x18PreapprovekeysendRequest\x12\x18\n\x0b\x64\x65stination\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_destinationB\x0f\n\r_payment_hashB\x0e\n\x0c_amount_msat\"\x1b\n\x19PreapprovekeysendResponse\":\n\x18PreapproveinvoiceRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_bolt11\"\x1b\n\x19PreapproveinvoiceResponse\"\x15\n\x13StaticbackupRequest\"#\n\x14StaticbackupResponse\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\x32\xa2\x1f\n\x04Node\x12\x36\n\x07Getinfo\x12\x13.cln.GetinfoRequest\x1a\x14.cln.GetinfoResponse\"\x00\x12<\n\tListPeers\x12\x15.cln.ListpeersRequest\x1a\x16.cln.ListpeersResponse\"\x00\x12<\n\tListFunds\x12\x15.cln.ListfundsRequest\x1a\x16.cln.ListfundsResponse\"\x00\x12\x36\n\x07SendPay\x12\x13.cln.SendpayRequest\x1a\x14.cln.SendpayResponse\"\x00\x12\x45\n\x0cListChannels\x12\x18.cln.ListchannelsRequest\x1a\x19.cln.ListchannelsResponse\"\x00\x12<\n\tAddGossip\x12\x15.cln.AddgossipRequest\x1a\x16.cln.AddgossipResponse\"\x00\x12Q\n\x10\x41utoCleanInvoice\x12\x1c.cln.AutocleaninvoiceRequest\x1a\x1d.cln.AutocleaninvoiceResponse\"\x00\x12\x45\n\x0c\x43heckMessage\x12\x18.cln.CheckmessageRequest\x1a\x19.cln.CheckmessageResponse\"\x00\x12\x30\n\x05\x43lose\x12\x11.cln.CloseRequest\x1a\x12.cln.CloseResponse\"\x00\x12:\n\x0b\x43onnectPeer\x12\x13.cln.ConnectRequest\x1a\x14.cln.ConnectResponse\"\x00\x12H\n\rCreateInvoice\x12\x19.cln.CreateinvoiceRequest\x1a\x1a.cln.CreateinvoiceResponse\"\x00\x12<\n\tDatastore\x12\x15.cln.DatastoreRequest\x1a\x16.cln.DatastoreResponse\"\x00\x12K\n\x0e\x44\x61tastoreUsage\x12\x1a.cln.DatastoreusageRequest\x1a\x1b.cln.DatastoreusageResponse\"\x00\x12\x42\n\x0b\x43reateOnion\x12\x17.cln.CreateonionRequest\x1a\x18.cln.CreateonionResponse\"\x00\x12\x45\n\x0c\x44\x65lDatastore\x12\x18.cln.DeldatastoreRequest\x1a\x19.cln.DeldatastoreResponse\"\x00\x12T\n\x11\x44\x65lExpiredInvoice\x12\x1d.cln.DelexpiredinvoiceRequest\x1a\x1e.cln.DelexpiredinvoiceResponse\"\x00\x12?\n\nDelInvoice\x12\x16.cln.DelinvoiceRequest\x1a\x17.cln.DelinvoiceResponse\"\x00\x12\x36\n\x07Invoice\x12\x13.cln.InvoiceRequest\x1a\x14.cln.InvoiceResponse\"\x00\x12H\n\rListDatastore\x12\x19.cln.ListdatastoreRequest\x1a\x1a.cln.ListdatastoreResponse\"\x00\x12\x45\n\x0cListInvoices\x12\x18.cln.ListinvoicesRequest\x1a\x19.cln.ListinvoicesResponse\"\x00\x12<\n\tSendOnion\x12\x15.cln.SendonionRequest\x1a\x16.cln.SendonionResponse\"\x00\x12\x45\n\x0cListSendPays\x12\x18.cln.ListsendpaysRequest\x1a\x19.cln.ListsendpaysResponse\"\x00\x12Q\n\x10ListTransactions\x12\x1c.cln.ListtransactionsRequest\x1a\x1d.cln.ListtransactionsResponse\"\x00\x12*\n\x03Pay\x12\x0f.cln.PayRequest\x1a\x10.cln.PayResponse\"\x00\x12<\n\tListNodes\x12\x15.cln.ListnodesRequest\x1a\x16.cln.ListnodesResponse\"\x00\x12K\n\x0eWaitAnyInvoice\x12\x1a.cln.WaitanyinvoiceRequest\x1a\x1b.cln.WaitanyinvoiceResponse\"\x00\x12\x42\n\x0bWaitInvoice\x12\x17.cln.WaitinvoiceRequest\x1a\x18.cln.WaitinvoiceResponse\"\x00\x12\x42\n\x0bWaitSendPay\x12\x17.cln.WaitsendpayRequest\x1a\x18.cln.WaitsendpayResponse\"\x00\x12\x36\n\x07NewAddr\x12\x13.cln.NewaddrRequest\x1a\x14.cln.NewaddrResponse\"\x00\x12\x39\n\x08Withdraw\x12\x14.cln.WithdrawRequest\x1a\x15.cln.WithdrawResponse\"\x00\x12\x36\n\x07KeySend\x12\x13.cln.KeysendRequest\x1a\x14.cln.KeysendResponse\"\x00\x12\x39\n\x08\x46undPsbt\x12\x14.cln.FundpsbtRequest\x1a\x15.cln.FundpsbtResponse\"\x00\x12\x39\n\x08SendPsbt\x12\x14.cln.SendpsbtRequest\x1a\x15.cln.SendpsbtResponse\"\x00\x12\x39\n\x08SignPsbt\x12\x14.cln.SignpsbtRequest\x1a\x15.cln.SignpsbtResponse\"\x00\x12\x39\n\x08UtxoPsbt\x12\x14.cln.UtxopsbtRequest\x1a\x15.cln.UtxopsbtResponse\"\x00\x12<\n\tTxDiscard\x12\x15.cln.TxdiscardRequest\x1a\x16.cln.TxdiscardResponse\"\x00\x12<\n\tTxPrepare\x12\x15.cln.TxprepareRequest\x1a\x16.cln.TxprepareResponse\"\x00\x12\x33\n\x06TxSend\x12\x12.cln.TxsendRequest\x1a\x13.cln.TxsendResponse\"\x00\x12Q\n\x10ListPeerChannels\x12\x1c.cln.ListpeerchannelsRequest\x1a\x1d.cln.ListpeerchannelsResponse\"\x00\x12W\n\x12ListClosedChannels\x12\x1e.cln.ListclosedchannelsRequest\x1a\x1f.cln.ListclosedchannelsResponse\"\x00\x12<\n\tDecodePay\x12\x15.cln.DecodepayRequest\x1a\x16.cln.DecodepayResponse\"\x00\x12\x33\n\x06\x44\x65\x63ode\x12\x12.cln.DecodeRequest\x1a\x13.cln.DecodeResponse\"\x00\x12?\n\nDisconnect\x12\x16.cln.DisconnectRequest\x1a\x17.cln.DisconnectResponse\"\x00\x12\x39\n\x08\x46\x65\x65rates\x12\x14.cln.FeeratesRequest\x1a\x15.cln.FeeratesResponse\"\x00\x12\x45\n\x0c\x46\x65tchInvoice\x12\x18.cln.FetchinvoiceRequest\x1a\x19.cln.FetchinvoiceResponse\"\x00\x12\x42\n\x0b\x46undChannel\x12\x17.cln.FundchannelRequest\x1a\x18.cln.FundchannelResponse\"\x00\x12\x39\n\x08GetRoute\x12\x14.cln.GetrouteRequest\x1a\x15.cln.GetrouteResponse\"\x00\x12\x45\n\x0cListForwards\x12\x18.cln.ListforwardsRequest\x1a\x19.cln.ListforwardsResponse\"\x00\x12\x39\n\x08ListPays\x12\x14.cln.ListpaysRequest\x1a\x15.cln.ListpaysResponse\"\x00\x12<\n\tListHtlcs\x12\x15.cln.ListhtlcsRequest\x1a\x16.cln.ListhtlcsResponse\"\x00\x12-\n\x04Ping\x12\x10.cln.PingRequest\x1a\x11.cln.PingResponse\"\x00\x12H\n\rSendCustomMsg\x12\x19.cln.SendcustommsgRequest\x1a\x1a.cln.SendcustommsgResponse\"\x00\x12?\n\nSetChannel\x12\x16.cln.SetchannelRequest\x1a\x17.cln.SetchannelResponse\"\x00\x12\x42\n\x0bSignInvoice\x12\x17.cln.SigninvoiceRequest\x1a\x18.cln.SigninvoiceResponse\"\x00\x12\x42\n\x0bSignMessage\x12\x17.cln.SignmessageRequest\x1a\x18.cln.SignmessageResponse\"\x00\x12N\n\x0fWaitBlockHeight\x12\x1b.cln.WaitblockheightRequest\x1a\x1c.cln.WaitblockheightResponse\"\x00\x12-\n\x04Wait\x12\x10.cln.WaitRequest\x1a\x11.cln.WaitResponse\"\x00\x12-\n\x04Stop\x12\x10.cln.StopRequest\x1a\x11.cln.StopResponse\"\x00\x12T\n\x11PreApproveKeysend\x12\x1d.cln.PreapprovekeysendRequest\x1a\x1e.cln.PreapprovekeysendResponse\"\x00\x12T\n\x11PreApproveInvoice\x12\x1d.cln.PreapproveinvoiceRequest\x1a\x1e.cln.PreapproveinvoiceResponse\"\x00\x12\x45\n\x0cStaticBackup\x12\x18.cln.StaticbackupRequest\x1a\x19.cln.StaticbackupResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nnode.proto\x12\x03\x63ln\x1a\x10primitives.proto\"\x10\n\x0eGetinfoRequest\"\xc1\x04\n\x0fGetinfoResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x61lias\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\r\n\x05\x63olor\x18\x03 \x01(\x0c\x12\x11\n\tnum_peers\x18\x04 \x01(\r\x12\x1c\n\x14num_pending_channels\x18\x05 \x01(\r\x12\x1b\n\x13num_active_channels\x18\x06 \x01(\r\x12\x1d\n\x15num_inactive_channels\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\rlightning_dir\x18\t \x01(\t\x12\x33\n\x0cour_features\x18\n \x01(\x0b\x32\x18.cln.GetinfoOur_featuresH\x01\x88\x01\x01\x12\x13\n\x0b\x62lockheight\x18\x0b \x01(\r\x12\x0f\n\x07network\x18\x0c \x01(\t\x12(\n\x13\x66\x65\x65s_collected_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x07\x61\x64\x64ress\x18\x0e \x03(\x0b\x32\x13.cln.GetinfoAddress\x12$\n\x07\x62inding\x18\x0f \x03(\x0b\x32\x13.cln.GetinfoBinding\x12\"\n\x15warning_bitcoind_sync\x18\x10 \x01(\tH\x02\x88\x01\x01\x12$\n\x17warning_lightningd_sync\x18\x11 \x01(\tH\x03\x88\x01\x01\x42\x08\n\x06_aliasB\x0f\n\r_our_featuresB\x18\n\x16_warning_bitcoind_syncB\x1a\n\x18_warning_lightningd_sync\"S\n\x13GetinfoOur_features\x12\x0c\n\x04init\x18\x01 \x01(\x0c\x12\x0c\n\x04node\x18\x02 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\x0c\x12\x0f\n\x07invoice\x18\x04 \x01(\x0c\"\xc4\x01\n\x0eGetinfoAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoAddress.GetinfoAddressType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"G\n\x12GetinfoAddressType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"\x8a\x02\n\x0eGetinfoBinding\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.GetinfoBinding.GetinfoBindingType\x12\x14\n\x07\x61\x64\x64ress\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06socket\x18\x04 \x01(\tH\x02\x88\x01\x01\"_\n\x12GetinfoBindingType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\r\n\tWEBSOCKET\x10\x05\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_addressB\x07\n\x05_portB\t\n\x07_socket\"H\n\x10ListpeersRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\x05level\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_idB\x08\n\x06_level\"7\n\x11ListpeersResponse\x12\"\n\x05peers\x18\x01 \x03(\x0b\x32\x13.cln.ListpeersPeers\"\x8e\x02\n\x0eListpeersPeers\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x11\n\tconnected\x18\x02 \x01(\x08\x12\x19\n\x0cnum_channels\x18\x08 \x01(\rH\x00\x88\x01\x01\x12#\n\x03log\x18\x03 \x03(\x0b\x32\x16.cln.ListpeersPeersLog\x12-\n\x08\x63hannels\x18\x04 \x03(\x0b\x32\x1b.cln.ListpeersPeersChannels\x12\x0f\n\x07netaddr\x18\x05 \x03(\t\x12\x18\n\x0bremote_addr\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x06 \x01(\x0cH\x02\x88\x01\x01\x42\x0f\n\r_num_channelsB\x0e\n\x0c_remote_addrB\x0b\n\t_features\"\xfd\x02\n\x11ListpeersPeersLog\x12?\n\titem_type\x18\x01 \x01(\x0e\x32,.cln.ListpeersPeersLog.ListpeersPeersLogType\x12\x18\n\x0bnum_skipped\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04time\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06source\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x10\n\x03log\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x07node_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x11\n\x04\x64\x61ta\x18\x07 \x01(\x0cH\x05\x88\x01\x01\"i\n\x15ListpeersPeersLogType\x12\x0b\n\x07SKIPPED\x10\x00\x12\n\n\x06\x42ROKEN\x10\x01\x12\x0b\n\x07UNUSUAL\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\t\n\x05\x44\x45\x42UG\x10\x04\x12\t\n\x05IO_IN\x10\x05\x12\n\n\x06IO_OUT\x10\x06\x42\x0e\n\x0c_num_skippedB\x07\n\x05_timeB\t\n\x07_sourceB\x06\n\x04_logB\n\n\x08_node_idB\x07\n\x05_data\"\x95\x18\n\x16ListpeersPeersChannels\x12\x46\n\x05state\x18\x01 \x01(\x0e\x32\x37.cln.ListpeersPeersChannels.ListpeersPeersChannelsState\x12\x19\n\x0cscratch_txid\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x38\n\x07\x66\x65\x65rate\x18\x03 \x01(\x0b\x32\".cln.ListpeersPeersChannelsFeerateH\x01\x88\x01\x01\x12\x12\n\x05owner\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x17\n\nchannel_id\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\x07 \x01(\x0cH\x05\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x08 \x01(\rH\x06\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\t \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\n \x01(\tH\x08\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0b \x01(\tH\t\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0c \x01(\rH\n\x88\x01\x01\x12\x35\n\x08inflight\x18\r \x03(\x0b\x32#.cln.ListpeersPeersChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x0e \x01(\x0cH\x0b\x88\x01\x01\x12\x14\n\x07private\x18\x0f \x01(\x08H\x0c\x88\x01\x01\x12 \n\x06opener\x18\x10 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x11 \x01(\x0e\x32\x10.cln.ChannelSideH\r\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x12 \x03(\t\x12\x38\n\x07\x66unding\x18\x13 \x01(\x0b\x32\".cln.ListpeersPeersChannelsFundingH\x0e\x88\x01\x01\x12$\n\nto_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.AmountH\x0f\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.AmountH\x10\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x16 \x01(\x0b\x32\x0b.cln.AmountH\x11\x88\x01\x01\x12$\n\ntotal_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x12\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x13\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x19 \x01(\rH\x14\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12*\n\x10our_reserve_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12(\n\x0espendable_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12)\n\x0freceivable_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x1a\x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18\x30 \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12 \n\x13their_to_self_delay\x18! \x01(\rH\x1e\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\" \x01(\rH\x1f\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18# \x01(\rH \x88\x01\x01\x12\x34\n\x05\x61lias\x18\x32 \x01(\x0b\x32 .cln.ListpeersPeersChannelsAliasH!\x88\x01\x01\x12\x0e\n\x06status\x18% \x03(\t\x12 \n\x13in_payments_offered\x18& \x01(\x04H\"\x88\x01\x01\x12)\n\x0fin_offered_msat\x18\' \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18( \x01(\x04H$\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18) \x01(\x0b\x32\x0b.cln.AmountH%\x88\x01\x01\x12!\n\x14out_payments_offered\x18* \x01(\x04H&\x88\x01\x01\x12*\n\x10out_offered_msat\x18+ \x01(\x0b\x32\x0b.cln.AmountH\'\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18, \x01(\x04H(\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH)\x88\x01\x01\x12/\n\x05htlcs\x18. \x03(\x0b\x32 .cln.ListpeersPeersChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18/ \x01(\tH*\x88\x01\x01\"\xe0\x02\n\x1bListpeersPeersChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0b\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\x0c\x42\x0f\n\r_scratch_txidB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addr\"=\n\x1dListpeersPeersChannelsFeerate\x12\r\n\x05perkw\x18\x01 \x01(\r\x12\r\n\x05perkb\x18\x02 \x01(\r\"\xf3\x01\n\x1eListpeersPeersChannelsInflight\x12\x14\n\x0c\x66unding_txid\x18\x01 \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\x02 \x01(\r\x12\x0f\n\x07\x66\x65\x65rate\x18\x03 \x01(\t\x12\'\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x00\x88\x01\x01\x12\x14\n\x0cscratch_txid\x18\x06 \x01(\x0c\x42\x10\n\x0e_splice_amount\"\x9b\x02\n\x1dListpeersPeersChannelsFunding\x12%\n\x0bpushed_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12%\n\x10local_funds_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12&\n\x11remote_funds_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\rfee_paid_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"[\n\x1bListpeersPeersChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xf1\x02\n\x1bListpeersPeersChannelsHtlcs\x12X\n\tdirection\x18\x01 \x01(\x0e\x32\x45.cln.ListpeersPeersChannelsHtlcs.ListpeersPeersChannelsHtlcsDirection\x12\n\n\x02id\x18\x02 \x01(\x04\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\r\x12\x14\n\x0cpayment_hash\x18\x05 \x01(\x0c\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcState\"7\n$ListpeersPeersChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x10\n\x0e_local_trimmedB\t\n\x07_status\"0\n\x10ListfundsRequest\x12\x12\n\x05spent\x18\x01 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_spent\"e\n\x11ListfundsResponse\x12&\n\x07outputs\x18\x01 \x03(\x0b\x32\x15.cln.ListfundsOutputs\x12(\n\x08\x63hannels\x18\x02 \x03(\x0b\x32\x16.cln.ListfundsChannels\"\x83\x03\n\x10ListfundsOutputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0e\n\x06output\x18\x02 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptpubkey\x18\x04 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x05 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0credeemscript\x18\x06 \x01(\x0cH\x01\x88\x01\x01\x12<\n\x06status\x18\x07 \x01(\x0e\x32,.cln.ListfundsOutputs.ListfundsOutputsStatus\x12\x10\n\x08reserved\x18\t \x01(\x08\x12\x18\n\x0b\x62lockheight\x18\x08 \x01(\rH\x02\x88\x01\x01\"Q\n\x16ListfundsOutputsStatus\x12\x0f\n\x0bUNCONFIRMED\x10\x00\x12\r\n\tCONFIRMED\x10\x01\x12\t\n\x05SPENT\x10\x02\x12\x0c\n\x08IMMATURE\x10\x03\x42\n\n\x08_addressB\x0f\n\r_redeemscriptB\x0e\n\x0c_blockheight\"\xab\x02\n\x11ListfundsChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12$\n\x0four_amount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12 \n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0c\x66unding_txid\x18\x04 \x01(\x0c\x12\x16\n\x0e\x66unding_output\x18\x05 \x01(\r\x12\x11\n\tconnected\x18\x06 \x01(\x08\x12 \n\x05state\x18\x07 \x01(\x0e\x32\x11.cln.ChannelState\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\x00\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x01\x88\x01\x01\x42\r\n\x0b_channel_idB\x13\n\x11_short_channel_id\"\xdd\x02\n\x0eSendpayRequest\x12 \n\x05route\x18\x01 \x03(\x0b\x32\x11.cln.SendpayRoute\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x13\n\x06partid\x18\x07 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0b \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\t \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\x11\n\x0f_payment_secretB\t\n\x07_partidB\x10\n\x0e_localinvreqidB\n\n\x08_groupid\"\xad\x05\n\x0fSendpayResponse\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x01\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x02\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x32\n\x06status\x18\x04 \x01(\x0e\x32\".cln.SendpayResponse.SendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12\x19\n\x0c\x63ompleted_at\x18\x0f \x01(\x04H\x05\x88\x01\x01\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x07\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\t\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\n\x88\x01\x01\x12\x14\n\x07message\x18\x0e \x01(\tH\x0b\x88\x01\x01\"*\n\rSendpayStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\n\n\x08_message\"\\\n\x0cSendpayRoute\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\n\n\x02id\x18\x02 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\t\"\x93\x01\n\x13ListchannelsRequest\x12\x1d\n\x10short_channel_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06source\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x42\x13\n\x11_short_channel_idB\t\n\x07_sourceB\x0e\n\x0c_destination\"C\n\x14ListchannelsResponse\x12+\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x19.cln.ListchannelsChannels\"\xb3\x03\n\x14ListchannelsChannels\x12\x0e\n\x06source\x18\x01 \x01(\x0c\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\x0c\x12\x18\n\x10short_channel_id\x18\x03 \x01(\t\x12\x11\n\tdirection\x18\x10 \x01(\r\x12\x0e\n\x06public\x18\x04 \x01(\x08\x12 \n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.Amount\x12\x15\n\rmessage_flags\x18\x06 \x01(\r\x12\x15\n\rchannel_flags\x18\x07 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x08 \x01(\x08\x12\x13\n\x0blast_update\x18\t \x01(\r\x12\x1d\n\x15\x62\x61se_fee_millisatoshi\x18\n \x01(\r\x12\x19\n\x11\x66\x65\x65_per_millionth\x18\x0b \x01(\r\x12\r\n\x05\x64\x65lay\x18\x0c \x01(\r\x12&\n\x11htlc_minimum_msat\x18\r \x01(\x0b\x32\x0b.cln.Amount\x12+\n\x11htlc_maximum_msat\x18\x0e \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x10\n\x08\x66\x65\x61tures\x18\x0f \x01(\x0c\x42\x14\n\x12_htlc_maximum_msat\"#\n\x10\x41\x64\x64gossipRequest\x12\x0f\n\x07message\x18\x01 \x01(\x0c\"\x13\n\x11\x41\x64\x64gossipResponse\"o\n\x17\x41utocleaninvoiceRequest\x12\x17\n\nexpired_by\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds\"\x81\x01\n\x18\x41utocleaninvoiceResponse\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\nexpired_by\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1a\n\rcycle_seconds\x18\x03 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_expired_byB\x10\n\x0e_cycle_seconds\"U\n\x13\x43heckmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05zbase\x18\x02 \x01(\t\x12\x13\n\x06pubkey\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\t\n\x07_pubkey\"8\n\x14\x43heckmessageResponse\x12\x10\n\x08verified\x18\x01 \x01(\x08\x12\x0e\n\x06pubkey\x18\x02 \x01(\x0c\"\xcb\x02\n\x0c\x43loseRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1e\n\x11unilateraltimeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\tH\x01\x88\x01\x01\x12!\n\x14\x66\x65\x65_negotiation_step\x18\x04 \x01(\tH\x02\x88\x01\x01\x12)\n\rwrong_funding\x18\x05 \x01(\x0b\x32\r.cln.OutpointH\x03\x88\x01\x01\x12\x1f\n\x12\x66orce_lease_closed\x18\x06 \x01(\x08H\x04\x88\x01\x01\x12\x1e\n\x08\x66\x65\x65range\x18\x07 \x03(\x0b\x32\x0c.cln.FeerateB\x14\n\x12_unilateraltimeoutB\x0e\n\x0c_destinationB\x17\n\x15_fee_negotiation_stepB\x10\n\x0e_wrong_fundingB\x15\n\x13_force_lease_closed\"\xab\x01\n\rCloseResponse\x12/\n\titem_type\x18\x01 \x01(\x0e\x32\x1c.cln.CloseResponse.CloseType\x12\x0f\n\x02tx\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04txid\x18\x03 \x01(\x0cH\x01\x88\x01\x01\"5\n\tCloseType\x12\n\n\x06MUTUAL\x10\x00\x12\x0e\n\nUNILATERAL\x10\x01\x12\x0c\n\x08UNOPENED\x10\x02\x42\x05\n\x03_txB\x07\n\x05_txid\"T\n\x0e\x43onnectRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\x04host\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x11\n\x04port\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_hostB\x07\n\x05_port\"\xb4\x01\n\x0f\x43onnectResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0c\x12\x38\n\tdirection\x18\x03 \x01(\x0e\x32%.cln.ConnectResponse.ConnectDirection\x12$\n\x07\x61\x64\x64ress\x18\x04 \x01(\x0b\x32\x13.cln.ConnectAddress\"#\n\x10\x43onnectDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\"\xfb\x01\n\x0e\x43onnectAddress\x12\x39\n\titem_type\x18\x01 \x01(\x0e\x32&.cln.ConnectAddress.ConnectAddressType\x12\x13\n\x06socket\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x11\n\x04port\x18\x04 \x01(\rH\x02\x88\x01\x01\"P\n\x12\x43onnectAddressType\x12\x10\n\x0cLOCAL_SOCKET\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\t\n\x07_socketB\n\n\x08_addressB\x07\n\x05_port\"J\n\x14\x43reateinvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x10\n\x08preimage\x18\x03 \x01(\x0c\"\xfe\x05\n\x15\x43reateinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12>\n\x06status\x18\x06 \x01(\x0e\x32..cln.CreateinvoiceResponse.CreateinvoiceStatus\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x03\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x04\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x06\x88\x01\x01\x12;\n\rpaid_outpoint\x18\x11 \x01(\x0b\x32\x1f.cln.CreateinvoicePaid_outpointH\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\x08\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\r \x01(\x0cH\t\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\n\x88\x01\x01\"8\n\x13\x43reateinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x10\n\x0e_created_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimageB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_note\"X\n\x1a\x43reateinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\xb4\x02\n\x10\x44\x61tastoreRequest\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x13\n\x06string\x18\x06 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x36\n\x04mode\x18\x03 \x01(\x0e\x32#.cln.DatastoreRequest.DatastoreModeH\x02\x88\x01\x01\x12\x17\n\ngeneration\x18\x04 \x01(\x04H\x03\x88\x01\x01\"p\n\rDatastoreMode\x12\x0f\n\x0bMUST_CREATE\x10\x00\x12\x10\n\x0cMUST_REPLACE\x10\x01\x12\x15\n\x11\x43REATE_OR_REPLACE\x10\x02\x12\x0f\n\x0bMUST_APPEND\x10\x03\x12\x14\n\x10\x43REATE_OR_APPEND\x10\x04\x42\t\n\x07_stringB\x06\n\x04_hexB\x07\n\x05_modeB\r\n\x0b_generation\"\x82\x01\n\x11\x44\x61tastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\x17\n\x15\x44\x61tastoreusageRequest\"k\n\x16\x44\x61tastoreusageResponse\x12>\n\x0e\x64\x61tastoreusage\x18\x01 \x01(\x0b\x32!.cln.DatastoreusageDatastoreusageH\x00\x88\x01\x01\x42\x11\n\x0f_datastoreusage\"b\n\x1c\x44\x61tastoreusageDatastoreusage\x12\x10\n\x03key\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0btotal_bytes\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x06\n\x04_keyB\x0e\n\x0c_total_bytes\"\x9d\x01\n\x12\x43reateonionRequest\x12\"\n\x04hops\x18\x01 \x03(\x0b\x32\x14.cln.CreateonionHops\x12\x11\n\tassocdata\x18\x02 \x01(\x0c\x12\x18\n\x0bsession_key\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x17\n\nonion_size\x18\x04 \x01(\rH\x01\x88\x01\x01\x42\x0e\n\x0c_session_keyB\r\n\x0b_onion_size\"<\n\x13\x43reateonionResponse\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12\x16\n\x0eshared_secrets\x18\x02 \x03(\x0c\"2\n\x0f\x43reateonionHops\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"J\n\x13\x44\x65ldatastoreRequest\x12\x0b\n\x03key\x18\x03 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x42\r\n\x0b_generation\"\x85\x01\n\x14\x44\x65ldatastoreResponse\x12\x0b\n\x03key\x18\x05 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"H\n\x18\x44\x65lexpiredinvoiceRequest\x12\x1a\n\rmaxexpirytime\x18\x01 \x01(\x04H\x00\x88\x01\x01\x42\x10\n\x0e_maxexpirytime\"\x1b\n\x19\x44\x65lexpiredinvoiceResponse\"\xb6\x01\n\x11\x44\x65linvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\x12\x37\n\x06status\x18\x02 \x01(\x0e\x32\'.cln.DelinvoiceRequest.DelinvoiceStatus\x12\x15\n\x08\x64\x65sconly\x18\x03 \x01(\x08H\x00\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\x0b\n\t_desconly\"\xa1\x04\n\x12\x44\x65linvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x06\x62olt11\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x03 \x01(\tH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x04\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x05\x88\x01\x01\x12\x38\n\x06status\x18\x07 \x01(\x0e\x32(.cln.DelinvoiceResponse.DelinvoiceStatus\x12\x12\n\nexpires_at\x18\x08 \x01(\x04\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x06\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0b \x01(\tH\x07\x88\x01\x01\"5\n\x10\x44\x65linvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x12\n\n\x06UNPAID\x10\x02\x42\t\n\x07_bolt11B\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_note\"\xfa\x01\n\x0eInvoiceRequest\x12%\n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x10.cln.AmountOrAny\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\r\n\x05label\x18\x03 \x01(\t\x12\x13\n\x06\x65xpiry\x18\x07 \x01(\x04H\x00\x88\x01\x01\x12\x11\n\tfallbacks\x18\x04 \x03(\t\x12\x15\n\x08preimage\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x11\n\x04\x63ltv\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x19\n\x0c\x64\x65schashonly\x18\t \x01(\x08H\x03\x88\x01\x01\x42\t\n\x07_expiryB\x0b\n\t_preimageB\x07\n\x05_cltvB\x0f\n\r_deschashonly\"\x95\x03\n\x0fInvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x16\n\x0epayment_secret\x18\x03 \x01(\x0c\x12\x12\n\nexpires_at\x18\x04 \x01(\x04\x12\x1a\n\rcreated_index\x18\n \x01(\x04H\x00\x88\x01\x01\x12\x1d\n\x10warning_capacity\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1c\n\x0fwarning_offline\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x1d\n\x10warning_deadends\x18\x07 \x01(\tH\x03\x88\x01\x01\x12#\n\x16warning_private_unused\x18\x08 \x01(\tH\x04\x88\x01\x01\x12\x18\n\x0bwarning_mpp\x18\t \x01(\tH\x05\x88\x01\x01\x42\x10\n\x0e_created_indexB\x13\n\x11_warning_capacityB\x12\n\x10_warning_offlineB\x13\n\x11_warning_deadendsB\x19\n\x17_warning_private_unusedB\x0e\n\x0c_warning_mpp\"#\n\x14ListdatastoreRequest\x12\x0b\n\x03key\x18\x02 \x03(\t\"G\n\x15ListdatastoreResponse\x12.\n\tdatastore\x18\x01 \x03(\x0b\x32\x1b.cln.ListdatastoreDatastore\"\x87\x01\n\x16ListdatastoreDatastore\x12\x0b\n\x03key\x18\x01 \x03(\t\x12\x17\n\ngeneration\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x03hex\x18\x03 \x01(\x0cH\x01\x88\x01\x01\x12\x13\n\x06string\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\r\n\x0b_generationB\x06\n\x04_hexB\t\n\x07_string\"\xde\x02\n\x13ListinvoicesRequest\x12\x12\n\x05label\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tinvstring\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x03 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08offer_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12>\n\x05index\x18\x05 \x01(\x0e\x32*.cln.ListinvoicesRequest.ListinvoicesIndexH\x04\x88\x01\x01\x12\x12\n\x05start\x18\x06 \x01(\x04H\x05\x88\x01\x01\x12\x12\n\x05limit\x18\x07 \x01(\rH\x06\x88\x01\x01\"-\n\x11ListinvoicesIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\x08\n\x06_labelB\x0c\n\n_invstringB\x0f\n\r_payment_hashB\x0b\n\t_offer_idB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListinvoicesResponse\x12+\n\x08invoices\x18\x01 \x03(\x0b\x32\x19.cln.ListinvoicesInvoices\"\xd4\x06\n\x14ListinvoicesInvoices\x12\r\n\x05label\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListinvoicesInvoices.ListinvoicesInvoicesStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x1b\n\x0elocal_offer_id\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x0f \x01(\tH\x05\x88\x01\x01\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x07\x88\x01\x01\x12\x16\n\tpay_index\x18\x0b \x01(\x04H\x08\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\t\x88\x01\x01\x12\x14\n\x07paid_at\x18\r \x01(\x04H\n\x88\x01\x01\x12\x42\n\rpaid_outpoint\x18\x12 \x01(\x0b\x32&.cln.ListinvoicesInvoicesPaid_outpointH\x0b\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0e \x01(\x0cH\x0c\x88\x01\x01\"?\n\x1aListinvoicesInvoicesStatus\x12\n\n\x06UNPAID\x10\x00\x12\x08\n\x04PAID\x10\x01\x12\x0b\n\x07\x45XPIRED\x10\x02\x42\x0e\n\x0c_descriptionB\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x11\n\x0f_local_offer_idB\x14\n\x12_invreq_payer_noteB\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"_\n!ListinvoicesInvoicesPaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\x8a\x03\n\x10SendonionRequest\x12\r\n\x05onion\x18\x01 \x01(\x0c\x12*\n\tfirst_hop\x18\x02 \x01(\x0b\x32\x17.cln.SendonionFirst_hop\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\x05label\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x16\n\x0eshared_secrets\x18\x05 \x03(\x0c\x12\x13\n\x06partid\x18\x06 \x01(\rH\x01\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x02\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x0c \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\t \x01(\x0cH\x04\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\r \x01(\x0cH\x05\x88\x01\x01\x12\x14\n\x07groupid\x18\x0b \x01(\x04H\x06\x88\x01\x01\x42\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x10\n\x0e_localinvreqidB\n\n\x08_groupid\"\xe7\x04\n\x11SendonionResponse\x12\x1a\n\rcreated_index\x18\x0e \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0cpayment_hash\x18\x02 \x01(\x0c\x12\x36\n\x06status\x18\x03 \x01(\x0e\x32&.cln.SendonionResponse.SendonionStatus\x12%\n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x05 \x01(\x0cH\x02\x88\x01\x01\x12\x12\n\ncreated_at\x18\x06 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x08 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\t \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\n \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06partid\x18\r \x01(\x04H\x06\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0f \x01(\x04H\x07\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0b \x01(\x0cH\x08\x88\x01\x01\x12\x14\n\x07message\x18\x0c \x01(\tH\t\x88\x01\x01\",\n\x0fSendonionStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x42\x10\n\x0e_created_indexB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\t\n\x07_bolt12B\t\n\x07_partidB\x10\n\x0e_updated_indexB\x13\n\x11_payment_preimageB\n\n\x08_message\"Q\n\x12SendonionFirst_hop\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x03 \x01(\r\"\xa0\x03\n\x13ListsendpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12@\n\x06status\x18\x03 \x01(\x0e\x32+.cln.ListsendpaysRequest.ListsendpaysStatusH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListsendpaysRequest.ListsendpaysIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\";\n\x12ListsendpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\"-\n\x11ListsendpaysIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_statusB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListsendpaysResponse\x12+\n\x08payments\x18\x01 \x03(\x0b\x32\x19.cln.ListsendpaysPayments\"\xd0\x05\n\x14ListsendpaysPayments\x12\x1a\n\rcreated_index\x18\x10 \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07groupid\x18\x02 \x01(\x04\x12\x13\n\x06partid\x18\x0f \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x1a\n\rupdated_index\x18\x11 \x01(\x04H\x02\x88\x01\x01\x12\x44\n\x06status\x18\x04 \x01(\x0e\x32\x34.cln.ListsendpaysPayments.ListsendpaysPaymentsStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x04\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x05\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\n \x01(\tH\x06\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0e \x01(\tH\x07\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\x12\x17\n\nerroronion\x18\r \x01(\x0cH\n\x88\x01\x01\"C\n\x1aListsendpaysPaymentsStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x10\n\x0e_created_indexB\t\n\x07_partidB\x10\n\x0e_updated_indexB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x13\n\x11_payment_preimageB\r\n\x0b_erroronion\"\x19\n\x17ListtransactionsRequest\"S\n\x18ListtransactionsResponse\x12\x37\n\x0ctransactions\x18\x01 \x03(\x0b\x32!.cln.ListtransactionsTransactions\"\xf8\x01\n\x1cListtransactionsTransactions\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12\r\n\x05rawtx\x18\x02 \x01(\x0c\x12\x13\n\x0b\x62lockheight\x18\x03 \x01(\r\x12\x0f\n\x07txindex\x18\x04 \x01(\r\x12\x10\n\x08locktime\x18\x07 \x01(\r\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x37\n\x06inputs\x18\t \x03(\x0b\x32\'.cln.ListtransactionsTransactionsInputs\x12\x39\n\x07outputs\x18\n \x03(\x0b\x32(.cln.ListtransactionsTransactionsOutputs\"S\n\"ListtransactionsTransactionsInputs\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\r\n\x05index\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\"l\n#ListtransactionsTransactionsOutputs\x12\r\n\x05index\x18\x01 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12\x14\n\x0cscriptPubKey\x18\x03 \x01(\x0c\"\xda\x03\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\nriskfactor\x18\x08 \x01(\x01H\x02\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x03\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x05\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1a\n\rlocalinvreqid\x18\x0e \x01(\x0cH\x07\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\n \x03(\t\x12 \n\x06maxfee\x18\x0b \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0c \x01(\tH\t\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x08\n\x06_labelB\r\n\x0b_riskfactorB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\x10\n\x0e_localinvreqidB\t\n\x07_maxfeeB\x0e\n\x0c_description\"\xfb\x02\n\x0bPayResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12*\n\x06status\x18\t \x01(\x0e\x32\x1a.cln.PayResponse.PayStatus\"2\n\tPayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"*\n\x10ListnodesRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListnodesResponse\x12\"\n\x05nodes\x18\x01 \x03(\x0b\x32\x13.cln.ListnodesNodes\"\xe1\x01\n\x0eListnodesNodes\x12\x0e\n\x06nodeid\x18\x01 \x01(\x0c\x12\x1b\n\x0elast_timestamp\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05\x61lias\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05\x63olor\x18\x04 \x01(\x0cH\x02\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x05 \x01(\x0cH\x03\x88\x01\x01\x12/\n\taddresses\x18\x06 \x03(\x0b\x32\x1c.cln.ListnodesNodesAddressesB\x11\n\x0f_last_timestampB\x08\n\x06_aliasB\x08\n\x06_colorB\x0b\n\t_features\"\xe8\x01\n\x17ListnodesNodesAddresses\x12K\n\titem_type\x18\x01 \x01(\x0e\x32\x38.cln.ListnodesNodesAddresses.ListnodesNodesAddressesType\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\"P\n\x1bListnodesNodesAddressesType\x12\x07\n\x03\x44NS\x10\x00\x12\x08\n\x04IPV4\x10\x01\x12\x08\n\x04IPV6\x10\x02\x12\t\n\x05TORV2\x10\x03\x12\t\n\x05TORV3\x10\x04\x42\n\n\x08_address\"g\n\x15WaitanyinvoiceRequest\x12\x1a\n\rlastpay_index\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07timeout\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\x10\n\x0e_lastpay_indexB\n\n\x08_timeout\"\xbf\x05\n\x16WaitanyinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12@\n\x06status\x18\x04 \x01(\x0e\x32\x30.cln.WaitanyinvoiceResponse.WaitanyinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x07\x88\x01\x01\x12<\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32 .cln.WaitanyinvoicePaid_outpointH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\"-\n\x14WaitanyinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"Y\n\x1bWaitanyinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"#\n\x12WaitinvoiceRequest\x12\r\n\x05label\x18\x01 \x01(\t\"\xb0\x05\n\x13WaitinvoiceResponse\x12\r\n\x05label\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitinvoiceResponse.WaitinvoiceStatus\x12\x12\n\nexpires_at\x18\x05 \x01(\x04\x12%\n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x07 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x1a\n\rcreated_index\x18\r \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\x0e \x01(\x04H\x04\x88\x01\x01\x12\x16\n\tpay_index\x18\t \x01(\x04H\x05\x88\x01\x01\x12.\n\x14\x61mount_received_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x14\n\x07paid_at\x18\x0b \x01(\x04H\x07\x88\x01\x01\x12\x39\n\rpaid_outpoint\x18\x0f \x01(\x0b\x32\x1d.cln.WaitinvoicePaid_outpointH\x08\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\x0c \x01(\x0cH\t\x88\x01\x01\"*\n\x11WaitinvoiceStatus\x12\x08\n\x04PAID\x10\x00\x12\x0b\n\x07\x45XPIRED\x10\x01\x42\x0e\n\x0c_amount_msatB\t\n\x07_bolt11B\t\n\x07_bolt12B\x10\n\x0e_created_indexB\x10\n\x0e_updated_indexB\x0c\n\n_pay_indexB\x17\n\x15_amount_received_msatB\n\n\x08_paid_atB\x10\n\x0e_paid_outpointB\x13\n\x11_payment_preimage\"V\n\x18WaitinvoicePaid_outpoint\x12\x11\n\x04txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x13\n\x06outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x07\n\x05_txidB\t\n\x07_outnum\"\x8e\x01\n\x12WaitsendpayRequest\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x14\n\x07timeout\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06partid\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07groupid\x18\x04 \x01(\x04H\x02\x88\x01\x01\x42\n\n\x08_timeoutB\t\n\x07_partidB\n\n\x08_groupid\"\x8e\x05\n\x13WaitsendpayResponse\x12\x1a\n\rcreated_index\x18\x0f \x01(\x04H\x00\x88\x01\x01\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x07groupid\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12:\n\x06status\x18\x04 \x01(\x0e\x32*.cln.WaitsendpayResponse.WaitsendpayStatus\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x18\n\x0b\x64\x65stination\x18\x06 \x01(\x0cH\x03\x88\x01\x01\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x12\x1a\n\rupdated_index\x18\x10 \x01(\x04H\x04\x88\x01\x01\x12\x19\n\x0c\x63ompleted_at\x18\x0e \x01(\x01H\x05\x88\x01\x01\x12%\n\x10\x61mount_sent_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\t \x01(\tH\x06\x88\x01\x01\x12\x13\n\x06partid\x18\n \x01(\x04H\x07\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x0b \x01(\tH\x08\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x0c \x01(\tH\t\x88\x01\x01\x12\x1d\n\x10payment_preimage\x18\r \x01(\x0cH\n\x88\x01\x01\"!\n\x11WaitsendpayStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x10\n\x0e_created_indexB\n\n\x08_groupidB\x0e\n\x0c_amount_msatB\x0e\n\x0c_destinationB\x10\n\x0e_updated_indexB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_partidB\t\n\x07_bolt11B\t\n\x07_bolt12B\x13\n\x11_payment_preimage\"\x97\x01\n\x0eNewaddrRequest\x12@\n\x0b\x61\x64\x64resstype\x18\x01 \x01(\x0e\x32&.cln.NewaddrRequest.NewaddrAddresstypeH\x00\x88\x01\x01\"3\n\x12NewaddrAddresstype\x12\n\n\x06\x42\x45\x43H32\x10\x00\x12\x08\n\x04P2TR\x10\x03\x12\x07\n\x03\x41LL\x10\x02\x42\x0e\n\x0c_addresstype\"w\n\x0fNewaddrResponse\x12\x11\n\x04p2tr\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06\x62\x65\x63h32\x18\x01 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bp2sh_segwit\x18\x02 \x01(\tH\x02\x88\x01\x01\x42\x07\n\x05_p2trB\t\n\x07_bech32B\x0e\n\x0c_p2sh_segwit\"\xca\x01\n\x0fWithdrawRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\t\x12&\n\x07satoshi\x18\x02 \x01(\x0b\x32\x10.cln.AmountOrAllH\x00\x88\x01\x01\x12\"\n\x07\x66\x65\x65rate\x18\x05 \x01(\x0b\x32\x0c.cln.FeerateH\x01\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_satoshiB\n\n\x08_feerateB\n\n\x08_minconf\":\n\x10WithdrawResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0c\n\x04psbt\x18\x03 \x01(\t\"\x82\x03\n\x0eKeysendRequest\x12\x13\n\x0b\x64\x65stination\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\n \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\x05label\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x1a\n\rmaxfeepercent\x18\x04 \x01(\x01H\x01\x88\x01\x01\x12\x16\n\tretry_for\x18\x05 \x01(\rH\x02\x88\x01\x01\x12\x15\n\x08maxdelay\x18\x06 \x01(\rH\x03\x88\x01\x01\x12#\n\texemptfee\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12+\n\nroutehints\x18\x08 \x01(\x0b\x32\x12.cln.RoutehintListH\x05\x88\x01\x01\x12&\n\textratlvs\x18\t \x01(\x0b\x32\x0e.cln.TlvStreamH\x06\x88\x01\x01\x42\x08\n\x06_labelB\x10\n\x0e_maxfeepercentB\x0c\n\n_retry_forB\x0b\n\t_maxdelayB\x0c\n\n_exemptfeeB\r\n\x0b_routehintsB\x0c\n\n_extratlvs\"\xf2\x02\n\x0fKeysendResponse\x12\x18\n\x10payment_preimage\x18\x01 \x01(\x0c\x12\x18\n\x0b\x64\x65stination\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\x0c\x12\x12\n\ncreated_at\x18\x04 \x01(\x01\x12\r\n\x05parts\x18\x05 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x61mount_sent_msat\x18\x07 \x01(\x0b\x32\x0b.cln.Amount\x12\'\n\x1awarning_partial_completion\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x32\n\x06status\x18\t \x01(\x0e\x32\".cln.KeysendResponse.KeysendStatus\"\x1d\n\rKeysendStatus\x12\x0c\n\x08\x43OMPLETE\x10\x00\x42\x0e\n\x0c_destinationB\x1d\n\x1b_warning_partial_completion\"\xa4\x03\n\x0f\x46undpsbtRequest\x12!\n\x07satoshi\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x14\n\x07minconf\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\x08 \x01(\x08H\x04\x88\x01\x01\x12\x17\n\nnonwrapped\x18\t \x01(\x08H\x05\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_minconfB\n\n\x08_reserveB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\r\n\x0b_nonwrappedB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10\x46undpsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.FundpsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14\x46undpsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\"A\n\x0fSendpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x14\n\x07reserve\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\n\n\x08_reserve\",\n\x10SendpsbtResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"1\n\x0fSignpsbtRequest\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x10\n\x08signonly\x18\x02 \x03(\r\"\'\n\x10SignpsbtResponse\x12\x13\n\x0bsigned_psbt\x18\x01 \x01(\t\"\x9b\x03\n\x0fUtxopsbtRequest\x12\x1c\n\x07satoshi\x18\x01 \x01(\x0b\x32\x0b.cln.Amount\x12\x1d\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.Feerate\x12\x13\n\x0bstartweight\x18\x03 \x01(\r\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.Outpoint\x12\x14\n\x07reserve\x18\x05 \x01(\rH\x00\x88\x01\x01\x12\x17\n\nreservedok\x18\x08 \x01(\x08H\x01\x88\x01\x01\x12\x15\n\x08locktime\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12min_witness_weight\x18\x07 \x01(\rH\x03\x88\x01\x01\x12\x1d\n\x10\x65xcess_as_change\x18\t \x01(\x08H\x04\x88\x01\x01\x12#\n\x16opening_anchor_channel\x18\n \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_reserveB\r\n\x0b_reservedokB\x0b\n\t_locktimeB\x15\n\x13_min_witness_weightB\x13\n\x11_excess_as_changeB\x19\n\x17_opening_anchor_channel\"\xd9\x01\n\x10UtxopsbtResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x16\n\x0e\x66\x65\x65rate_per_kw\x18\x02 \x01(\r\x12\x1e\n\x16\x65stimated_final_weight\x18\x03 \x01(\r\x12 \n\x0b\x65xcess_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\x1a\n\rchange_outnum\x18\x05 \x01(\rH\x00\x88\x01\x01\x12/\n\x0creservations\x18\x06 \x03(\x0b\x32\x19.cln.UtxopsbtReservationsB\x10\n\x0e_change_outnum\"u\n\x14UtxopsbtReservations\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\x12\x0c\n\x04vout\x18\x02 \x01(\r\x12\x14\n\x0cwas_reserved\x18\x03 \x01(\x08\x12\x10\n\x08reserved\x18\x04 \x01(\x08\x12\x19\n\x11reserved_to_block\x18\x05 \x01(\r\" \n\x10TxdiscardRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"6\n\x11TxdiscardResponse\x12\x13\n\x0bunsigned_tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\"\xa4\x01\n\x10TxprepareRequest\x12 \n\x07outputs\x18\x05 \x03(\x0b\x32\x0f.cln.OutputDesc\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x14\n\x07minconf\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x05utxos\x18\x04 \x03(\x0b\x32\r.cln.OutpointB\n\n\x08_feerateB\n\n\x08_minconf\"D\n\x11TxprepareResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\x13\n\x0bunsigned_tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"\x1d\n\rTxsendRequest\x12\x0c\n\x04txid\x18\x01 \x01(\x0c\"8\n\x0eTxsendResponse\x12\x0c\n\x04psbt\x18\x01 \x01(\t\x12\n\n\x02tx\x18\x02 \x01(\x0c\x12\x0c\n\x04txid\x18\x03 \x01(\x0c\"1\n\x17ListpeerchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"K\n\x18ListpeerchannelsResponse\x12/\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1d.cln.ListpeerchannelsChannels\"\xa2\x1a\n\x18ListpeerchannelsChannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x1b\n\x0epeer_connected\x18\x02 \x01(\x08H\x01\x88\x01\x01\x12O\n\x05state\x18\x03 \x01(\x0e\x32;.cln.ListpeerchannelsChannels.ListpeerchannelsChannelsStateH\x02\x88\x01\x01\x12\x19\n\x0cscratch_txid\x18\x04 \x01(\x0cH\x03\x88\x01\x01\x12:\n\x07updates\x18\x37 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsUpdatesH\x04\x88\x01\x01\x12\x1e\n\x11ignore_fee_limits\x18\x36 \x01(\x08H\x05\x88\x01\x01\x12:\n\x07\x66\x65\x65rate\x18\x06 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFeerateH\x06\x88\x01\x01\x12\x12\n\x05owner\x18\x07 \x01(\tH\x07\x88\x01\x01\x12\x1d\n\x10short_channel_id\x18\x08 \x01(\tH\x08\x88\x01\x01\x12\x17\n\nchannel_id\x18\t \x01(\x0cH\t\x88\x01\x01\x12\x19\n\x0c\x66unding_txid\x18\n \x01(\x0cH\n\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x0b \x01(\rH\x0b\x88\x01\x01\x12\x1c\n\x0finitial_feerate\x18\x0c \x01(\tH\x0c\x88\x01\x01\x12\x19\n\x0clast_feerate\x18\r \x01(\tH\r\x88\x01\x01\x12\x19\n\x0cnext_feerate\x18\x0e \x01(\tH\x0e\x88\x01\x01\x12\x1a\n\rnext_fee_step\x18\x0f \x01(\rH\x0f\x88\x01\x01\x12\x37\n\x08inflight\x18\x10 \x03(\x0b\x32%.cln.ListpeerchannelsChannelsInflight\x12\x15\n\x08\x63lose_to\x18\x11 \x01(\x0cH\x10\x88\x01\x01\x12\x14\n\x07private\x18\x12 \x01(\x08H\x11\x88\x01\x01\x12%\n\x06opener\x18\x13 \x01(\x0e\x32\x10.cln.ChannelSideH\x12\x88\x01\x01\x12%\n\x06\x63loser\x18\x14 \x01(\x0e\x32\x10.cln.ChannelSideH\x13\x88\x01\x01\x12:\n\x07\x66unding\x18\x16 \x01(\x0b\x32$.cln.ListpeerchannelsChannelsFundingH\x14\x88\x01\x01\x12$\n\nto_us_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12(\n\x0emin_to_us_msat\x18\x18 \x01(\x0b\x32\x0b.cln.AmountH\x16\x88\x01\x01\x12(\n\x0emax_to_us_msat\x18\x19 \x01(\x0b\x32\x0b.cln.AmountH\x17\x88\x01\x01\x12$\n\ntotal_msat\x18\x1a \x01(\x0b\x32\x0b.cln.AmountH\x18\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x1b \x01(\x0b\x32\x0b.cln.AmountH\x19\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x1c \x01(\rH\x1a\x88\x01\x01\x12)\n\x0f\x64ust_limit_msat\x18\x1d \x01(\x0b\x32\x0b.cln.AmountH\x1b\x88\x01\x01\x12\x30\n\x16max_total_htlc_in_msat\x18\x1e \x01(\x0b\x32\x0b.cln.AmountH\x1c\x88\x01\x01\x12,\n\x12their_reserve_msat\x18\x1f \x01(\x0b\x32\x0b.cln.AmountH\x1d\x88\x01\x01\x12*\n\x10our_reserve_msat\x18 \x01(\x0b\x32\x0b.cln.AmountH\x1e\x88\x01\x01\x12(\n\x0espendable_msat\x18! \x01(\x0b\x32\x0b.cln.AmountH\x1f\x88\x01\x01\x12)\n\x0freceivable_msat\x18\" \x01(\x0b\x32\x0b.cln.AmountH \x88\x01\x01\x12.\n\x14minimum_htlc_in_msat\x18# \x01(\x0b\x32\x0b.cln.AmountH!\x88\x01\x01\x12/\n\x15minimum_htlc_out_msat\x18$ \x01(\x0b\x32\x0b.cln.AmountH\"\x88\x01\x01\x12/\n\x15maximum_htlc_out_msat\x18% \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12 \n\x13their_to_self_delay\x18& \x01(\rH$\x88\x01\x01\x12\x1e\n\x11our_to_self_delay\x18\' \x01(\rH%\x88\x01\x01\x12\x1f\n\x12max_accepted_htlcs\x18( \x01(\rH&\x88\x01\x01\x12\x36\n\x05\x61lias\x18) \x01(\x0b\x32\".cln.ListpeerchannelsChannelsAliasH\'\x88\x01\x01\x12\x0e\n\x06status\x18+ \x03(\t\x12 \n\x13in_payments_offered\x18, \x01(\x04H(\x88\x01\x01\x12)\n\x0fin_offered_msat\x18- \x01(\x0b\x32\x0b.cln.AmountH)\x88\x01\x01\x12\"\n\x15in_payments_fulfilled\x18. \x01(\x04H*\x88\x01\x01\x12+\n\x11in_fulfilled_msat\x18/ \x01(\x0b\x32\x0b.cln.AmountH+\x88\x01\x01\x12!\n\x14out_payments_offered\x18\x30 \x01(\x04H,\x88\x01\x01\x12*\n\x10out_offered_msat\x18\x31 \x01(\x0b\x32\x0b.cln.AmountH-\x88\x01\x01\x12#\n\x16out_payments_fulfilled\x18\x32 \x01(\x04H.\x88\x01\x01\x12,\n\x12out_fulfilled_msat\x18\x33 \x01(\x0b\x32\x0b.cln.AmountH/\x88\x01\x01\x12\x31\n\x05htlcs\x18\x34 \x03(\x0b\x32\".cln.ListpeerchannelsChannelsHtlcs\x12\x1a\n\rclose_to_addr\x18\x35 \x01(\tH0\x88\x01\x01\"\x80\x03\n\x1dListpeerchannelsChannelsState\x12\x0c\n\x08OPENINGD\x10\x00\x12\x1c\n\x18\x43HANNELD_AWAITING_LOCKIN\x10\x01\x12\x13\n\x0f\x43HANNELD_NORMAL\x10\x02\x12\x1a\n\x16\x43HANNELD_SHUTTING_DOWN\x10\x03\x12\x18\n\x14\x43LOSINGD_SIGEXCHANGE\x10\x04\x12\x15\n\x11\x43LOSINGD_COMPLETE\x10\x05\x12\x17\n\x13\x41WAITING_UNILATERAL\x10\x06\x12\x16\n\x12\x46UNDING_SPEND_SEEN\x10\x07\x12\x0b\n\x07ONCHAIN\x10\x08\x12\x17\n\x13\x44UALOPEND_OPEN_INIT\x10\t\x12\x1d\n\x19\x44UALOPEND_AWAITING_LOCKIN\x10\n\x12\x1c\n\x18\x43HANNELD_AWAITING_SPLICE\x10\x0b\x12\x1c\n\x18\x44UALOPEND_OPEN_COMMITTED\x10\x0c\x12\x1f\n\x1b\x44UALOPEND_OPEN_COMMIT_READY\x10\rB\n\n\x08_peer_idB\x11\n\x0f_peer_connectedB\x08\n\x06_stateB\x0f\n\r_scratch_txidB\n\n\x08_updatesB\x14\n\x12_ignore_fee_limitsB\n\n\x08_feerateB\x08\n\x06_ownerB\x13\n\x11_short_channel_idB\r\n\x0b_channel_idB\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\x12\n\x10_initial_feerateB\x0f\n\r_last_feerateB\x0f\n\r_next_feerateB\x10\n\x0e_next_fee_stepB\x0b\n\t_close_toB\n\n\x08_privateB\t\n\x07_openerB\t\n\x07_closerB\n\n\x08_fundingB\r\n\x0b_to_us_msatB\x11\n\x0f_min_to_us_msatB\x11\n\x0f_max_to_us_msatB\r\n\x0b_total_msatB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionthsB\x12\n\x10_dust_limit_msatB\x19\n\x17_max_total_htlc_in_msatB\x15\n\x13_their_reserve_msatB\x13\n\x11_our_reserve_msatB\x11\n\x0f_spendable_msatB\x12\n\x10_receivable_msatB\x17\n\x15_minimum_htlc_in_msatB\x18\n\x16_minimum_htlc_out_msatB\x18\n\x16_maximum_htlc_out_msatB\x16\n\x14_their_to_self_delayB\x14\n\x12_our_to_self_delayB\x15\n\x13_max_accepted_htlcsB\x08\n\x06_aliasB\x16\n\x14_in_payments_offeredB\x12\n\x10_in_offered_msatB\x18\n\x16_in_payments_fulfilledB\x14\n\x12_in_fulfilled_msatB\x17\n\x15_out_payments_offeredB\x13\n\x11_out_offered_msatB\x19\n\x17_out_payments_fulfilledB\x15\n\x13_out_fulfilled_msatB\x10\n\x0e_close_to_addr\"\xb6\x01\n\x1fListpeerchannelsChannelsUpdates\x12=\n\x05local\x18\x01 \x01(\x0b\x32).cln.ListpeerchannelsChannelsUpdatesLocalH\x00\x88\x01\x01\x12?\n\x06remote\x18\x02 \x01(\x0b\x32*.cln.ListpeerchannelsChannelsUpdatesRemoteH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xe7\x02\n$ListpeerchannelsChannelsUpdatesLocal\x12+\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12+\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x1e\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x14\n\x12_cltv_expiry_deltaB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionths\"\xe8\x02\n%ListpeerchannelsChannelsUpdatesRemote\x12+\n\x11htlc_minimum_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12+\n\x11htlc_maximum_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12\x1e\n\x11\x63ltv_expiry_delta\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\'\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12(\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x14\n\x12_htlc_minimum_msatB\x14\n\x12_htlc_maximum_msatB\x14\n\x12_cltv_expiry_deltaB\x10\n\x0e_fee_base_msatB\x1e\n\x1c_fee_proportional_millionths\"]\n\x1fListpeerchannelsChannelsFeerate\x12\x12\n\x05perkw\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x12\n\x05perkb\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\x08\n\x06_perkwB\x08\n\x06_perkb\"\x80\x03\n ListpeerchannelsChannelsInflight\x12\x19\n\x0c\x66unding_txid\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x1b\n\x0e\x66unding_outnum\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x03 \x01(\tH\x02\x88\x01\x01\x12,\n\x12total_funding_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x1a\n\rsplice_amount\x18\x07 \x01(\x12H\x04\x88\x01\x01\x12*\n\x10our_funding_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x19\n\x0cscratch_txid\x18\x06 \x01(\x0cH\x06\x88\x01\x01\x42\x0f\n\r_funding_txidB\x11\n\x0f_funding_outnumB\n\n\x08_feerateB\x15\n\x13_total_funding_msatB\x10\n\x0e_splice_amountB\x13\n\x11_our_funding_msatB\x0f\n\r_scratch_txid\"\xd2\x02\n\x1fListpeerchannelsChannelsFunding\x12%\n\x0bpushed_msat\x18\x01 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12*\n\x10local_funds_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x01\x88\x01\x01\x12+\n\x11remote_funds_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\'\n\rfee_paid_msat\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\'\n\rfee_rcvd_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x0e\n\x0c_pushed_msatB\x13\n\x11_local_funds_msatB\x14\n\x12_remote_funds_msatB\x10\n\x0e_fee_paid_msatB\x10\n\x0e_fee_rcvd_msat\"]\n\x1dListpeerchannelsChannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"\xe2\x03\n\x1dListpeerchannelsChannelsHtlcs\x12\x61\n\tdirection\x18\x01 \x01(\x0e\x32I.cln.ListpeerchannelsChannelsHtlcs.ListpeerchannelsChannelsHtlcsDirectionH\x00\x88\x01\x01\x12\x0f\n\x02id\x18\x02 \x01(\x04H\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x05 \x01(\x0cH\x04\x88\x01\x01\x12\x1a\n\rlocal_trimmed\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x13\n\x06status\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\"\n\x05state\x18\x08 \x01(\x0e\x32\x0e.cln.HtlcStateH\x07\x88\x01\x01\"9\n&ListpeerchannelsChannelsHtlcsDirection\x12\x06\n\x02IN\x10\x00\x12\x07\n\x03OUT\x10\x01\x42\x0c\n\n_directionB\x05\n\x03_idB\x0e\n\x0c_amount_msatB\t\n\x07_expiryB\x0f\n\r_payment_hashB\x10\n\x0e_local_trimmedB\t\n\x07_statusB\x08\n\x06_state\"3\n\x19ListclosedchannelsRequest\x12\x0f\n\x02id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x05\n\x03_id\"[\n\x1aListclosedchannelsResponse\x12=\n\x0e\x63losedchannels\x18\x01 \x03(\x0b\x32%.cln.ListclosedchannelsClosedchannels\"\xb2\t\n ListclosedchannelsClosedchannels\x12\x14\n\x07peer_id\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x01\x88\x01\x01\x12>\n\x05\x61lias\x18\x04 \x01(\x0b\x32*.cln.ListclosedchannelsClosedchannelsAliasH\x02\x88\x01\x01\x12 \n\x06opener\x18\x05 \x01(\x0e\x32\x10.cln.ChannelSide\x12%\n\x06\x63loser\x18\x06 \x01(\x0e\x32\x10.cln.ChannelSideH\x03\x88\x01\x01\x12\x0f\n\x07private\x18\x07 \x01(\x08\x12\x1f\n\x17total_local_commitments\x18\t \x01(\x04\x12 \n\x18total_remote_commitments\x18\n \x01(\x04\x12\x18\n\x10total_htlcs_sent\x18\x0b \x01(\x04\x12\x14\n\x0c\x66unding_txid\x18\x0c \x01(\x0c\x12\x16\n\x0e\x66unding_outnum\x18\r \x01(\r\x12\x0e\n\x06leased\x18\x0e \x01(\x08\x12/\n\x15\x66unding_fee_paid_msat\x18\x0f \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x12/\n\x15\x66unding_fee_rcvd_msat\x18\x10 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12-\n\x13\x66unding_pushed_msat\x18\x11 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1f\n\ntotal_msat\x18\x12 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x10\x66inal_to_us_msat\x18\x13 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emin_to_us_msat\x18\x14 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x0emax_to_us_msat\x18\x15 \x01(\x0b\x32\x0b.cln.Amount\x12!\n\x14last_commitment_txid\x18\x16 \x01(\x0cH\x07\x88\x01\x01\x12\x32\n\x18last_commitment_fee_msat\x18\x17 \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x12\x66\n\x0b\x63lose_cause\x18\x18 \x01(\x0e\x32Q.cln.ListclosedchannelsClosedchannels.ListclosedchannelsClosedchannelsClose_cause\"v\n+ListclosedchannelsClosedchannelsClose_cause\x12\x0b\n\x07UNKNOWN\x10\x00\x12\t\n\x05LOCAL\x10\x01\x12\x08\n\x04USER\x10\x02\x12\n\n\x06REMOTE\x10\x03\x12\x0c\n\x08PROTOCOL\x10\x04\x12\x0b\n\x07ONCHAIN\x10\x05\x42\n\n\x08_peer_idB\x13\n\x11_short_channel_idB\x08\n\x06_aliasB\t\n\x07_closerB\x18\n\x16_funding_fee_paid_msatB\x18\n\x16_funding_fee_rcvd_msatB\x16\n\x14_funding_pushed_msatB\x17\n\x15_last_commitment_txidB\x1b\n\x19_last_commitment_fee_msat\"e\n%ListclosedchannelsClosedchannelsAlias\x12\x12\n\x05local\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x13\n\x06remote\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x08\n\x06_localB\t\n\x07_remote\"L\n\x10\x44\x65\x63odepayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x04\n\x11\x44\x65\x63odepayResponse\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\x12\n\ncreated_at\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\x04\x12\r\n\x05payee\x18\x04 \x01(\x0c\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x11\n\tsignature\x18\x07 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x08 \x01(\tH\x01\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18\t \x01(\x0cH\x02\x88\x01\x01\x12\x1d\n\x15min_final_cltv_expiry\x18\n \x01(\r\x12\x1b\n\x0epayment_secret\x18\x0b \x01(\x0cH\x03\x88\x01\x01\x12\x15\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0cH\x04\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\r \x01(\x0cH\x05\x88\x01\x01\x12*\n\tfallbacks\x18\x0e \x03(\x0b\x32\x17.cln.DecodepayFallbacks\x12\"\n\x05\x65xtra\x18\x10 \x03(\x0b\x32\x13.cln.DecodepayExtraB\x0e\n\x0c_amount_msatB\x0e\n\x0c_descriptionB\x13\n\x11_description_hashB\x11\n\x0f_payment_secretB\x0b\n\t_featuresB\x13\n\x11_payment_metadata\"\xd0\x01\n\x12\x44\x65\x63odepayFallbacks\x12\x41\n\titem_type\x18\x01 \x01(\x0e\x32..cln.DecodepayFallbacks.DecodepayFallbacksType\x12\x11\n\x04\x61\x64\x64r\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x0b\n\x03hex\x18\x03 \x01(\x0c\"N\n\x16\x44\x65\x63odepayFallbacksType\x12\t\n\x05P2PKH\x10\x00\x12\x08\n\x04P2SH\x10\x01\x12\n\n\x06P2WPKH\x10\x02\x12\t\n\x05P2WSH\x10\x03\x12\x08\n\x04P2TR\x10\x04\x42\x07\n\x05_addr\"+\n\x0e\x44\x65\x63odepayExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"\x1f\n\rDecodeRequest\x12\x0e\n\x06string\x18\x01 \x01(\t\"\xe8!\n\x0e\x44\x65\x63odeResponse\x12\x31\n\titem_type\x18\x01 \x01(\x0e\x32\x1e.cln.DecodeResponse.DecodeType\x12\r\n\x05valid\x18\x02 \x01(\x08\x12\x15\n\x08offer_id\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x14\n\x0coffer_chains\x18\x04 \x03(\x0c\x12\x1b\n\x0eoffer_metadata\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x1b\n\x0eoffer_currency\x18\x06 \x01(\tH\x02\x88\x01\x01\x12+\n\x1ewarning_unknown_offer_currency\x18\x07 \x01(\tH\x03\x88\x01\x01\x12 \n\x13\x63urrency_minor_unit\x18\x08 \x01(\rH\x04\x88\x01\x01\x12\x19\n\x0coffer_amount\x18\t \x01(\x04H\x05\x88\x01\x01\x12+\n\x11offer_amount_msat\x18\n \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\x1e\n\x11offer_description\x18\x0b \x01(\tH\x07\x88\x01\x01\x12\x19\n\x0coffer_issuer\x18\x0c \x01(\tH\x08\x88\x01\x01\x12\x1b\n\x0eoffer_features\x18\r \x01(\x0cH\t\x88\x01\x01\x12\"\n\x15offer_absolute_expiry\x18\x0e \x01(\x04H\n\x88\x01\x01\x12\x1f\n\x12offer_quantity_max\x18\x0f \x01(\x04H\x0b\x88\x01\x01\x12+\n\x0boffer_paths\x18\x10 \x03(\x0b\x32\x16.cln.DecodeOffer_paths\x12\x1a\n\roffer_node_id\x18\x11 \x01(\x0cH\x0c\x88\x01\x01\x12*\n\x1dwarning_missing_offer_node_id\x18\x14 \x01(\tH\r\x88\x01\x01\x12.\n!warning_invalid_offer_description\x18\x15 \x01(\tH\x0e\x88\x01\x01\x12.\n!warning_missing_offer_description\x18\x16 \x01(\tH\x0f\x88\x01\x01\x12+\n\x1ewarning_invalid_offer_currency\x18\x17 \x01(\tH\x10\x88\x01\x01\x12)\n\x1cwarning_invalid_offer_issuer\x18\x18 \x01(\tH\x11\x88\x01\x01\x12\x1c\n\x0finvreq_metadata\x18\x19 \x01(\x0cH\x12\x88\x01\x01\x12\x1c\n\x0finvreq_payer_id\x18\x1a \x01(\x0cH\x13\x88\x01\x01\x12\x19\n\x0cinvreq_chain\x18\x1b \x01(\x0cH\x14\x88\x01\x01\x12,\n\x12invreq_amount_msat\x18\x1c \x01(\x0b\x32\x0b.cln.AmountH\x15\x88\x01\x01\x12\x1c\n\x0finvreq_features\x18\x1d \x01(\x0cH\x16\x88\x01\x01\x12\x1c\n\x0finvreq_quantity\x18\x1e \x01(\x04H\x17\x88\x01\x01\x12\x1e\n\x11invreq_payer_note\x18\x1f \x01(\tH\x18\x88\x01\x01\x12&\n\x19invreq_recurrence_counter\x18 \x01(\rH\x19\x88\x01\x01\x12$\n\x17invreq_recurrence_start\x18! \x01(\rH\x1a\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_metadata\x18# \x01(\tH\x1b\x88\x01\x01\x12,\n\x1fwarning_missing_invreq_payer_id\x18$ \x01(\tH\x1c\x88\x01\x01\x12.\n!warning_invalid_invreq_payer_note\x18% \x01(\tH\x1d\x88\x01\x01\x12\x36\n)warning_missing_invoice_request_signature\x18& \x01(\tH\x1e\x88\x01\x01\x12\x36\n)warning_invalid_invoice_request_signature\x18\' \x01(\tH\x1f\x88\x01\x01\x12\x1f\n\x12invoice_created_at\x18) \x01(\x04H \x88\x01\x01\x12$\n\x17invoice_relative_expiry\x18* \x01(\rH!\x88\x01\x01\x12!\n\x14invoice_payment_hash\x18+ \x01(\x0cH\"\x88\x01\x01\x12-\n\x13invoice_amount_msat\x18, \x01(\x0b\x32\x0b.cln.AmountH#\x88\x01\x01\x12\x37\n\x11invoice_fallbacks\x18- \x03(\x0b\x32\x1c.cln.DecodeInvoice_fallbacks\x12\x1d\n\x10invoice_features\x18. \x01(\x0cH$\x88\x01\x01\x12\x1c\n\x0finvoice_node_id\x18/ \x01(\x0cH%\x88\x01\x01\x12(\n\x1binvoice_recurrence_basetime\x18\x30 \x01(\x04H&\x88\x01\x01\x12*\n\x1dwarning_missing_invoice_paths\x18\x32 \x01(\tH\'\x88\x01\x01\x12/\n\"warning_missing_invoice_blindedpay\x18\x33 \x01(\tH(\x88\x01\x01\x12/\n\"warning_missing_invoice_created_at\x18\x34 \x01(\tH)\x88\x01\x01\x12\x31\n$warning_missing_invoice_payment_hash\x18\x35 \x01(\tH*\x88\x01\x01\x12+\n\x1ewarning_missing_invoice_amount\x18\x36 \x01(\tH+\x88\x01\x01\x12\x38\n+warning_missing_invoice_recurrence_basetime\x18\x37 \x01(\tH,\x88\x01\x01\x12,\n\x1fwarning_missing_invoice_node_id\x18\x38 \x01(\tH-\x88\x01\x01\x12.\n!warning_missing_invoice_signature\x18\x39 \x01(\tH.\x88\x01\x01\x12.\n!warning_invalid_invoice_signature\x18: \x01(\tH/\x88\x01\x01\x12\'\n\tfallbacks\x18; \x03(\x0b\x32\x14.cln.DecodeFallbacks\x12\x17\n\ncreated_at\x18< \x01(\x04H0\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18= \x01(\x04H1\x88\x01\x01\x12\x12\n\x05payee\x18> \x01(\x0cH2\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18? \x01(\x0cH3\x88\x01\x01\x12\x1d\n\x10\x64\x65scription_hash\x18@ \x01(\x0cH4\x88\x01\x01\x12\"\n\x15min_final_cltv_expiry\x18\x41 \x01(\rH5\x88\x01\x01\x12\x1b\n\x0epayment_secret\x18\x42 \x01(\x0cH6\x88\x01\x01\x12\x1d\n\x10payment_metadata\x18\x43 \x01(\x0cH7\x88\x01\x01\x12\x1f\n\x05\x65xtra\x18\x45 \x03(\x0b\x32\x10.cln.DecodeExtra\x12\x16\n\tunique_id\x18\x46 \x01(\tH8\x88\x01\x01\x12\x14\n\x07version\x18G \x01(\tH9\x88\x01\x01\x12\x13\n\x06string\x18H \x01(\tH:\x88\x01\x01\x12-\n\x0crestrictions\x18I \x03(\x0b\x32\x17.cln.DecodeRestrictions\x12&\n\x19warning_rune_invalid_utf8\x18J \x01(\tH;\x88\x01\x01\x12\x10\n\x03hex\x18K \x01(\x0cH<\x88\x01\x01\x12\x16\n\tdecrypted\x18L \x01(\x0cH=\x88\x01\x01\"\x83\x01\n\nDecodeType\x12\x10\n\x0c\x42OLT12_OFFER\x10\x00\x12\x12\n\x0e\x42OLT12_INVOICE\x10\x01\x12\x1a\n\x16\x42OLT12_INVOICE_REQUEST\x10\x02\x12\x12\n\x0e\x42OLT11_INVOICE\x10\x03\x12\x08\n\x04RUNE\x10\x04\x12\x15\n\x11\x45MERGENCY_RECOVER\x10\x05\x42\x0b\n\t_offer_idB\x11\n\x0f_offer_metadataB\x11\n\x0f_offer_currencyB!\n\x1f_warning_unknown_offer_currencyB\x16\n\x14_currency_minor_unitB\x0f\n\r_offer_amountB\x14\n\x12_offer_amount_msatB\x14\n\x12_offer_descriptionB\x0f\n\r_offer_issuerB\x11\n\x0f_offer_featuresB\x18\n\x16_offer_absolute_expiryB\x15\n\x13_offer_quantity_maxB\x10\n\x0e_offer_node_idB \n\x1e_warning_missing_offer_node_idB$\n\"_warning_invalid_offer_descriptionB$\n\"_warning_missing_offer_descriptionB!\n\x1f_warning_invalid_offer_currencyB\x1f\n\x1d_warning_invalid_offer_issuerB\x12\n\x10_invreq_metadataB\x12\n\x10_invreq_payer_idB\x0f\n\r_invreq_chainB\x15\n\x13_invreq_amount_msatB\x12\n\x10_invreq_featuresB\x12\n\x10_invreq_quantityB\x14\n\x12_invreq_payer_noteB\x1c\n\x1a_invreq_recurrence_counterB\x1a\n\x18_invreq_recurrence_startB\"\n _warning_missing_invreq_metadataB\"\n _warning_missing_invreq_payer_idB$\n\"_warning_invalid_invreq_payer_noteB,\n*_warning_missing_invoice_request_signatureB,\n*_warning_invalid_invoice_request_signatureB\x15\n\x13_invoice_created_atB\x1a\n\x18_invoice_relative_expiryB\x17\n\x15_invoice_payment_hashB\x16\n\x14_invoice_amount_msatB\x13\n\x11_invoice_featuresB\x12\n\x10_invoice_node_idB\x1e\n\x1c_invoice_recurrence_basetimeB \n\x1e_warning_missing_invoice_pathsB%\n#_warning_missing_invoice_blindedpayB%\n#_warning_missing_invoice_created_atB\'\n%_warning_missing_invoice_payment_hashB!\n\x1f_warning_missing_invoice_amountB.\n,_warning_missing_invoice_recurrence_basetimeB\"\n _warning_missing_invoice_node_idB$\n\"_warning_missing_invoice_signatureB$\n\"_warning_invalid_invoice_signatureB\r\n\x0b_created_atB\t\n\x07_expiryB\x08\n\x06_payeeB\x0f\n\r_payment_hashB\x13\n\x11_description_hashB\x18\n\x16_min_final_cltv_expiryB\x11\n\x0f_payment_secretB\x13\n\x11_payment_metadataB\x0c\n\n_unique_idB\n\n\x08_versionB\t\n\x07_stringB\x1c\n\x1a_warning_rune_invalid_utf8B\x06\n\x04_hexB\x0c\n\n_decrypted\"<\n\x11\x44\x65\x63odeOffer_paths\x12\x15\n\rfirst_node_id\x18\x01 \x01(\x0c\x12\x10\n\x08\x62linding\x18\x02 \x01(\x0c\"\x8a\x01\n\x1f\x44\x65\x63odeOffer_recurrencePaywindow\x12\x16\n\x0eseconds_before\x18\x01 \x01(\r\x12\x15\n\rseconds_after\x18\x02 \x01(\r\x12 \n\x13proportional_amount\x18\x03 \x01(\x08H\x00\x88\x01\x01\x42\x16\n\x14_proportional_amount\"T\n\x17\x44\x65\x63odeInvoice_pathsPath\x12\x17\n\x0f\x62linded_node_id\x18\x01 \x01(\x0c\x12 \n\x18\x65ncrypted_recipient_data\x18\x02 \x01(\x0c\"Y\n\x17\x44\x65\x63odeInvoice_fallbacks\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0b\n\x03hex\x18\x02 \x01(\x0c\x12\x14\n\x07\x61\x64\x64ress\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_address\"w\n\x0f\x44\x65\x63odeFallbacks\x12\x36\n)warning_invoice_fallbacks_version_invalid\x18\x01 \x01(\tH\x00\x88\x01\x01\x42,\n*_warning_invoice_fallbacks_version_invalid\"(\n\x0b\x44\x65\x63odeExtra\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\";\n\x12\x44\x65\x63odeRestrictions\x12\x14\n\x0c\x61lternatives\x18\x01 \x03(\t\x12\x0f\n\x07summary\x18\x02 \x01(\t\"=\n\x11\x44isconnectRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x12\n\x05\x66orce\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x08\n\x06_force\"\x14\n\x12\x44isconnectResponse\"k\n\x0f\x46\x65\x65ratesRequest\x12\x31\n\x05style\x18\x01 \x01(\x0e\x32\".cln.FeeratesRequest.FeeratesStyle\"%\n\rFeeratesStyle\x12\t\n\x05PERKB\x10\x00\x12\t\n\x05PERKW\x10\x01\"\x9c\x02\n\x10\x46\x65\x65ratesResponse\x12%\n\x18warning_missing_feerates\x18\x01 \x01(\tH\x00\x88\x01\x01\x12&\n\x05perkb\x18\x02 \x01(\x0b\x32\x12.cln.FeeratesPerkbH\x01\x88\x01\x01\x12&\n\x05perkw\x18\x03 \x01(\x0b\x32\x12.cln.FeeratesPerkwH\x02\x88\x01\x01\x12\x46\n\x15onchain_fee_estimates\x18\x04 \x01(\x0b\x32\".cln.FeeratesOnchain_fee_estimatesH\x03\x88\x01\x01\x42\x1b\n\x19_warning_missing_feeratesB\x08\n\x06_perkbB\x08\n\x06_perkwB\x18\n\x16_onchain_fee_estimates\"\xd3\x03\n\rFeeratesPerkb\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x00\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkbEstimates\x12\x14\n\x07opening\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x07\x88\x01\x01\x42\x08\n\x06_floorB\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x1a\n\x18_unilateral_anchor_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty\"\x96\x01\n\x16\x46\x65\x65ratesPerkbEstimates\x12\x17\n\nblockcount\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10smoothed_feerate\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\r\n\x0b_blockcountB\n\n\x08_feerateB\x13\n\x11_smoothed_feerate\"\xd3\x03\n\rFeeratesPerkw\x12\x16\n\x0emin_acceptable\x18\x01 \x01(\r\x12\x16\n\x0emax_acceptable\x18\x02 \x01(\r\x12\x12\n\x05\x66loor\x18\n \x01(\rH\x00\x88\x01\x01\x12.\n\testimates\x18\t \x03(\x0b\x32\x1b.cln.FeeratesPerkwEstimates\x12\x14\n\x07opening\x18\x03 \x01(\rH\x01\x88\x01\x01\x12\x19\n\x0cmutual_close\x18\x04 \x01(\rH\x02\x88\x01\x01\x12\x1d\n\x10unilateral_close\x18\x05 \x01(\rH\x03\x88\x01\x01\x12$\n\x17unilateral_anchor_close\x18\x0b \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rdelayed_to_us\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1c\n\x0fhtlc_resolution\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x14\n\x07penalty\x18\x08 \x01(\rH\x07\x88\x01\x01\x42\x08\n\x06_floorB\n\n\x08_openingB\x0f\n\r_mutual_closeB\x13\n\x11_unilateral_closeB\x1a\n\x18_unilateral_anchor_closeB\x10\n\x0e_delayed_to_usB\x12\n\x10_htlc_resolutionB\n\n\x08_penalty\"\x96\x01\n\x16\x46\x65\x65ratesPerkwEstimates\x12\x17\n\nblockcount\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07\x66\x65\x65rate\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1d\n\x10smoothed_feerate\x18\x03 \x01(\rH\x02\x88\x01\x01\x42\r\n\x0b_blockcountB\n\n\x08_feerateB\x13\n\x11_smoothed_feerate\"\x9b\x02\n\x1d\x46\x65\x65ratesOnchain_fee_estimates\x12 \n\x18opening_channel_satoshis\x18\x01 \x01(\x04\x12\x1d\n\x15mutual_close_satoshis\x18\x02 \x01(\x04\x12!\n\x19unilateral_close_satoshis\x18\x03 \x01(\x04\x12\x30\n#unilateral_close_nonanchor_satoshis\x18\x06 \x01(\x04H\x00\x88\x01\x01\x12\x1d\n\x15htlc_timeout_satoshis\x18\x04 \x01(\x04\x12\x1d\n\x15htlc_success_satoshis\x18\x05 \x01(\x04\x42&\n$_unilateral_close_nonanchor_satoshis\"\xe9\x02\n\x13\x46\x65tchinvoiceRequest\x12\r\n\x05offer\x18\x01 \x01(\t\x12%\n\x0b\x61mount_msat\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x15\n\x08quantity\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x1f\n\x12recurrence_counter\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x1d\n\x10recurrence_start\x18\x05 \x01(\x01H\x03\x88\x01\x01\x12\x1d\n\x10recurrence_label\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x14\n\x07timeout\x18\x07 \x01(\x01H\x05\x88\x01\x01\x12\x17\n\npayer_note\x18\x08 \x01(\tH\x06\x88\x01\x01\x42\x0e\n\x0c_amount_msatB\x0b\n\t_quantityB\x15\n\x13_recurrence_counterB\x13\n\x11_recurrence_startB\x13\n\x11_recurrence_labelB\n\n\x08_timeoutB\r\n\x0b_payer_note\"\x9a\x01\n\x14\x46\x65tchinvoiceResponse\x12\x0f\n\x07invoice\x18\x01 \x01(\t\x12)\n\x07\x63hanges\x18\x02 \x01(\x0b\x32\x18.cln.FetchinvoiceChanges\x12\x36\n\x0bnext_period\x18\x03 \x01(\x0b\x32\x1c.cln.FetchinvoiceNext_periodH\x00\x88\x01\x01\x42\x0e\n\x0c_next_period\"\x82\x02\n\x13\x46\x65tchinvoiceChanges\x12!\n\x14\x64\x65scription_appended\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0evendor_removed\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06vendor\x18\x04 \x01(\tH\x03\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x04\x88\x01\x01\x42\x17\n\x15_description_appendedB\x0e\n\x0c_descriptionB\x11\n\x0f_vendor_removedB\t\n\x07_vendorB\x0e\n\x0c_amount_msat\"~\n\x17\x46\x65tchinvoiceNext_period\x12\x0f\n\x07\x63ounter\x18\x01 \x01(\x04\x12\x11\n\tstarttime\x18\x02 \x01(\x04\x12\x0f\n\x07\x65ndtime\x18\x03 \x01(\x04\x12\x17\n\x0fpaywindow_start\x18\x04 \x01(\x04\x12\x15\n\rpaywindow_end\x18\x05 \x01(\x04\"\xe5\x03\n\x12\x46undchannelRequest\x12\n\n\x02id\x18\t \x01(\x0c\x12 \n\x06\x61mount\x18\x01 \x01(\x0b\x32\x10.cln.AmountOrAll\x12\"\n\x07\x66\x65\x65rate\x18\x02 \x01(\x0b\x32\x0c.cln.FeerateH\x00\x88\x01\x01\x12\x15\n\x08\x61nnounce\x18\x03 \x01(\x08H\x01\x88\x01\x01\x12\x14\n\x07minconf\x18\n \x01(\rH\x02\x88\x01\x01\x12#\n\tpush_msat\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x15\n\x08\x63lose_to\x18\x06 \x01(\tH\x04\x88\x01\x01\x12%\n\x0brequest_amt\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x05\x88\x01\x01\x12\x1a\n\rcompact_lease\x18\x08 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x05utxos\x18\x0b \x03(\x0b\x32\r.cln.Outpoint\x12\x15\n\x08mindepth\x18\x0c \x01(\rH\x07\x88\x01\x01\x12!\n\x07reserve\x18\r \x01(\x0b\x32\x0b.cln.AmountH\x08\x88\x01\x01\x42\n\n\x08_feerateB\x0b\n\t_announceB\n\n\x08_minconfB\x0c\n\n_push_msatB\x0b\n\t_close_toB\x0e\n\x0c_request_amtB\x10\n\x0e_compact_leaseB\x0b\n\t_mindepthB\n\n\x08_reserve\"\x9b\x01\n\x13\x46undchannelResponse\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12\x0c\n\x04txid\x18\x02 \x01(\x0c\x12\x0e\n\x06outnum\x18\x03 \x01(\r\x12\x12\n\nchannel_id\x18\x04 \x01(\x0c\x12\x15\n\x08\x63lose_to\x18\x05 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08mindepth\x18\x06 \x01(\rH\x01\x88\x01\x01\x42\x0b\n\t_close_toB\x0b\n\t_mindepth\"\xec\x01\n\x0fGetrouteRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12 \n\x0b\x61mount_msat\x18\t \x01(\x0b\x32\x0b.cln.Amount\x12\x12\n\nriskfactor\x18\x03 \x01(\x04\x12\x11\n\x04\x63ltv\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x13\n\x06\x66romid\x18\x05 \x01(\x0cH\x01\x88\x01\x01\x12\x18\n\x0b\x66uzzpercent\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x0f\n\x07\x65xclude\x18\x07 \x03(\t\x12\x14\n\x07maxhops\x18\x08 \x01(\rH\x03\x88\x01\x01\x42\x07\n\x05_cltvB\t\n\x07_fromidB\x0e\n\x0c_fuzzpercentB\n\n\x08_maxhops\"5\n\x10GetrouteResponse\x12!\n\x05route\x18\x01 \x03(\x0b\x32\x12.cln.GetrouteRoute\"\xc5\x01\n\rGetrouteRoute\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\t\x12\x11\n\tdirection\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12\r\n\x05\x64\x65lay\x18\x05 \x01(\r\x12\x34\n\x05style\x18\x06 \x01(\x0e\x32%.cln.GetrouteRoute.GetrouteRouteStyle\"\x1d\n\x12GetrouteRouteStyle\x12\x07\n\x03TLV\x10\x00\"\xb7\x03\n\x13ListforwardsRequest\x12@\n\x06status\x18\x01 \x01(\x0e\x32+.cln.ListforwardsRequest.ListforwardsStatusH\x00\x88\x01\x01\x12\x17\n\nin_channel\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bout_channel\x18\x03 \x01(\tH\x02\x88\x01\x01\x12>\n\x05index\x18\x04 \x01(\x0e\x32*.cln.ListforwardsRequest.ListforwardsIndexH\x03\x88\x01\x01\x12\x12\n\x05start\x18\x05 \x01(\x04H\x04\x88\x01\x01\x12\x12\n\x05limit\x18\x06 \x01(\rH\x05\x88\x01\x01\"L\n\x12ListforwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"-\n\x11ListforwardsIndex\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x42\t\n\x07_statusB\r\n\x0b_in_channelB\x0e\n\x0c_out_channelB\x08\n\x06_indexB\x08\n\x06_startB\x08\n\x06_limit\"C\n\x14ListforwardsResponse\x12+\n\x08\x66orwards\x18\x01 \x03(\x0b\x32\x19.cln.ListforwardsForwards\"\xba\x05\n\x14ListforwardsForwards\x12\x1a\n\rcreated_index\x18\x0c \x01(\x04H\x00\x88\x01\x01\x12\x12\n\nin_channel\x18\x01 \x01(\t\x12\x17\n\nin_htlc_id\x18\n \x01(\x04H\x01\x88\x01\x01\x12\x1c\n\x07in_msat\x18\x02 \x01(\x0b\x32\x0b.cln.Amount\x12\x44\n\x06status\x18\x03 \x01(\x0e\x32\x34.cln.ListforwardsForwards.ListforwardsForwardsStatus\x12\x15\n\rreceived_time\x18\x04 \x01(\x01\x12\x18\n\x0bout_channel\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x18\n\x0bout_htlc_id\x18\x0b \x01(\x04H\x03\x88\x01\x01\x12\x1a\n\rupdated_index\x18\r \x01(\x04H\x04\x88\x01\x01\x12G\n\x05style\x18\t \x01(\x0e\x32\x33.cln.ListforwardsForwards.ListforwardsForwardsStyleH\x05\x88\x01\x01\x12\"\n\x08\x66\x65\x65_msat\x18\x07 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12\"\n\x08out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\"T\n\x1aListforwardsForwardsStatus\x12\x0b\n\x07OFFERED\x10\x00\x12\x0b\n\x07SETTLED\x10\x01\x12\x10\n\x0cLOCAL_FAILED\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"0\n\x19ListforwardsForwardsStyle\x12\n\n\x06LEGACY\x10\x00\x12\x07\n\x03TLV\x10\x01\x42\x10\n\x0e_created_indexB\r\n\x0b_in_htlc_idB\x0e\n\x0c_out_channelB\x0e\n\x0c_out_htlc_idB\x10\n\x0e_updated_indexB\x08\n\x06_styleB\x0b\n\t_fee_msatB\x0b\n\t_out_msat\"\xdb\x01\n\x0fListpaysRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12\x38\n\x06status\x18\x03 \x01(\x0e\x32#.cln.ListpaysRequest.ListpaysStatusH\x02\x88\x01\x01\"7\n\x0eListpaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\x0c\n\x08\x43OMPLETE\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x42\t\n\x07_bolt11B\x0f\n\r_payment_hashB\t\n\x07_status\"3\n\x10ListpaysResponse\x12\x1f\n\x04pays\x18\x01 \x03(\x0b\x32\x11.cln.ListpaysPays\"\xff\x04\n\x0cListpaysPays\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\x0c\x12\x34\n\x06status\x18\x02 \x01(\x0e\x32$.cln.ListpaysPays.ListpaysPaysStatus\x12\x18\n\x0b\x64\x65stination\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x12\x12\n\ncreated_at\x18\x04 \x01(\x04\x12\x19\n\x0c\x63ompleted_at\x18\x0c \x01(\x04H\x01\x88\x01\x01\x12\x12\n\x05label\x18\x05 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x06\x62olt11\x18\x06 \x01(\tH\x03\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x0b \x01(\tH\x04\x88\x01\x01\x12\x13\n\x06\x62olt12\x18\x07 \x01(\tH\x05\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x08 \x01(\x0b\x32\x0b.cln.AmountH\x06\x88\x01\x01\x12*\n\x10\x61mount_sent_msat\x18\t \x01(\x0b\x32\x0b.cln.AmountH\x07\x88\x01\x01\x12\x15\n\x08preimage\x18\r \x01(\x0cH\x08\x88\x01\x01\x12\x1c\n\x0fnumber_of_parts\x18\x0e \x01(\x04H\t\x88\x01\x01\x12\x17\n\nerroronion\x18\n \x01(\x0cH\n\x88\x01\x01\";\n\x12ListpaysPaysStatus\x12\x0b\n\x07PENDING\x10\x00\x12\n\n\x06\x46\x41ILED\x10\x01\x12\x0c\n\x08\x43OMPLETE\x10\x02\x42\x0e\n\x0c_destinationB\x0f\n\r_completed_atB\x08\n\x06_labelB\t\n\x07_bolt11B\x0e\n\x0c_descriptionB\t\n\x07_bolt12B\x0e\n\x0c_amount_msatB\x13\n\x11_amount_sent_msatB\x0b\n\t_preimageB\x12\n\x10_number_of_partsB\r\n\x0b_erroronion\"*\n\x10ListhtlcsRequest\x12\x0f\n\x02id\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x05\n\x03_id\"7\n\x11ListhtlcsResponse\x12\"\n\x05htlcs\x18\x01 \x03(\x0b\x32\x13.cln.ListhtlcsHtlcs\"\x89\x02\n\x0eListhtlcsHtlcs\x12\x18\n\x10short_channel_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\x04\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\r\x12 \n\x0b\x61mount_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12>\n\tdirection\x18\x05 \x01(\x0e\x32+.cln.ListhtlcsHtlcs.ListhtlcsHtlcsDirection\x12\x14\n\x0cpayment_hash\x18\x06 \x01(\x0c\x12\x1d\n\x05state\x18\x07 \x01(\x0e\x32\x0e.cln.HtlcState\"*\n\x17ListhtlcsHtlcsDirection\x12\x07\n\x03OUT\x10\x00\x12\x06\n\x02IN\x10\x01\"Y\n\x0bPingRequest\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x10\n\x03len\x18\x02 \x01(\rH\x00\x88\x01\x01\x12\x16\n\tpongbytes\x18\x03 \x01(\rH\x01\x88\x01\x01\x42\x06\n\x04_lenB\x0c\n\n_pongbytes\"\x1e\n\x0cPingResponse\x12\x0e\n\x06totlen\x18\x01 \x01(\r\"4\n\x14SendcustommsgRequest\x12\x0f\n\x07node_id\x18\x01 \x01(\x0c\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"\'\n\x15SendcustommsgResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\"\xaa\x02\n\x11SetchannelRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12!\n\x07\x66\x65\x65\x62\x61se\x18\x02 \x01(\x0b\x32\x0b.cln.AmountH\x00\x88\x01\x01\x12\x13\n\x06\x66\x65\x65ppm\x18\x03 \x01(\rH\x01\x88\x01\x01\x12!\n\x07htlcmin\x18\x04 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x12!\n\x07htlcmax\x18\x05 \x01(\x0b\x32\x0b.cln.AmountH\x03\x88\x01\x01\x12\x19\n\x0c\x65nforcedelay\x18\x06 \x01(\rH\x04\x88\x01\x01\x12\x1c\n\x0fignorefeelimits\x18\x07 \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_feebaseB\t\n\x07_feeppmB\n\n\x08_htlcminB\n\n\x08_htlcmaxB\x0f\n\r_enforcedelayB\x12\n\x10_ignorefeelimits\"?\n\x12SetchannelResponse\x12)\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x17.cln.SetchannelChannels\"\xca\x03\n\x12SetchannelChannels\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x1d\n\x10short_channel_id\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\"\n\rfee_base_msat\x18\x04 \x01(\x0b\x32\x0b.cln.Amount\x12#\n\x1b\x66\x65\x65_proportional_millionths\x18\x05 \x01(\r\x12\x1e\n\x11ignore_fee_limits\x18\n \x01(\x08H\x01\x88\x01\x01\x12*\n\x15minimum_htlc_out_msat\x18\x06 \x01(\x0b\x32\x0b.cln.Amount\x12$\n\x17warning_htlcmin_too_low\x18\x07 \x01(\tH\x02\x88\x01\x01\x12*\n\x15maximum_htlc_out_msat\x18\x08 \x01(\x0b\x32\x0b.cln.Amount\x12%\n\x18warning_htlcmax_too_high\x18\t \x01(\tH\x03\x88\x01\x01\x42\x13\n\x11_short_channel_idB\x14\n\x12_ignore_fee_limitsB\x1a\n\x18_warning_htlcmin_too_lowB\x1b\n\x19_warning_htlcmax_too_high\"\'\n\x12SigninvoiceRequest\x12\x11\n\tinvstring\x18\x01 \x01(\t\"%\n\x13SigninvoiceResponse\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\"%\n\x12SignmessageRequest\x12\x0f\n\x07message\x18\x01 \x01(\t\"F\n\x13SignmessageResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\x12\r\n\x05recid\x18\x02 \x01(\x0c\x12\r\n\x05zbase\x18\x03 \x01(\t\"O\n\x16WaitblockheightRequest\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\x12\x14\n\x07timeout\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\n\n\x08_timeout\".\n\x17WaitblockheightResponse\x12\x13\n\x0b\x62lockheight\x18\x01 \x01(\r\"\xf9\x01\n\x0bWaitRequest\x12\x31\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitSubsystem\x12\x31\n\tindexname\x18\x02 \x01(\x0e\x32\x1e.cln.WaitRequest.WaitIndexname\x12\x11\n\tnextvalue\x18\x03 \x01(\x04\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\"6\n\rWaitIndexname\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0b\n\x07UPDATED\x10\x01\x12\x0b\n\x07\x44\x45LETED\x10\x02\"\xe3\x01\n\x0cWaitResponse\x12\x32\n\tsubsystem\x18\x01 \x01(\x0e\x32\x1f.cln.WaitResponse.WaitSubsystem\x12\x14\n\x07\x63reated\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x14\n\x07updated\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07\x64\x65leted\x18\x04 \x01(\x04H\x02\x88\x01\x01\"9\n\rWaitSubsystem\x12\x0c\n\x08INVOICES\x10\x00\x12\x0c\n\x08\x46ORWARDS\x10\x01\x12\x0c\n\x08SENDPAYS\x10\x02\x42\n\n\x08_createdB\n\n\x08_updatedB\n\n\x08_deleted\"\r\n\x0bStopRequest\"\x0e\n\x0cStopResponse\"\xa7\x01\n\x18PreapprovekeysendRequest\x12\x18\n\x0b\x64\x65stination\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x19\n\x0cpayment_hash\x18\x02 \x01(\x0cH\x01\x88\x01\x01\x12%\n\x0b\x61mount_msat\x18\x03 \x01(\x0b\x32\x0b.cln.AmountH\x02\x88\x01\x01\x42\x0e\n\x0c_destinationB\x0f\n\r_payment_hashB\x0e\n\x0c_amount_msat\"\x1b\n\x19PreapprovekeysendResponse\":\n\x18PreapproveinvoiceRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_bolt11\"\x1b\n\x19PreapproveinvoiceResponse\"\x15\n\x13StaticbackupRequest\"#\n\x14StaticbackupResponse\x12\x0b\n\x03scb\x18\x01 \x03(\x0c\x32\xa2\x1f\n\x04Node\x12\x36\n\x07Getinfo\x12\x13.cln.GetinfoRequest\x1a\x14.cln.GetinfoResponse\"\x00\x12<\n\tListPeers\x12\x15.cln.ListpeersRequest\x1a\x16.cln.ListpeersResponse\"\x00\x12<\n\tListFunds\x12\x15.cln.ListfundsRequest\x1a\x16.cln.ListfundsResponse\"\x00\x12\x36\n\x07SendPay\x12\x13.cln.SendpayRequest\x1a\x14.cln.SendpayResponse\"\x00\x12\x45\n\x0cListChannels\x12\x18.cln.ListchannelsRequest\x1a\x19.cln.ListchannelsResponse\"\x00\x12<\n\tAddGossip\x12\x15.cln.AddgossipRequest\x1a\x16.cln.AddgossipResponse\"\x00\x12Q\n\x10\x41utoCleanInvoice\x12\x1c.cln.AutocleaninvoiceRequest\x1a\x1d.cln.AutocleaninvoiceResponse\"\x00\x12\x45\n\x0c\x43heckMessage\x12\x18.cln.CheckmessageRequest\x1a\x19.cln.CheckmessageResponse\"\x00\x12\x30\n\x05\x43lose\x12\x11.cln.CloseRequest\x1a\x12.cln.CloseResponse\"\x00\x12:\n\x0b\x43onnectPeer\x12\x13.cln.ConnectRequest\x1a\x14.cln.ConnectResponse\"\x00\x12H\n\rCreateInvoice\x12\x19.cln.CreateinvoiceRequest\x1a\x1a.cln.CreateinvoiceResponse\"\x00\x12<\n\tDatastore\x12\x15.cln.DatastoreRequest\x1a\x16.cln.DatastoreResponse\"\x00\x12K\n\x0e\x44\x61tastoreUsage\x12\x1a.cln.DatastoreusageRequest\x1a\x1b.cln.DatastoreusageResponse\"\x00\x12\x42\n\x0b\x43reateOnion\x12\x17.cln.CreateonionRequest\x1a\x18.cln.CreateonionResponse\"\x00\x12\x45\n\x0c\x44\x65lDatastore\x12\x18.cln.DeldatastoreRequest\x1a\x19.cln.DeldatastoreResponse\"\x00\x12T\n\x11\x44\x65lExpiredInvoice\x12\x1d.cln.DelexpiredinvoiceRequest\x1a\x1e.cln.DelexpiredinvoiceResponse\"\x00\x12?\n\nDelInvoice\x12\x16.cln.DelinvoiceRequest\x1a\x17.cln.DelinvoiceResponse\"\x00\x12\x36\n\x07Invoice\x12\x13.cln.InvoiceRequest\x1a\x14.cln.InvoiceResponse\"\x00\x12H\n\rListDatastore\x12\x19.cln.ListdatastoreRequest\x1a\x1a.cln.ListdatastoreResponse\"\x00\x12\x45\n\x0cListInvoices\x12\x18.cln.ListinvoicesRequest\x1a\x19.cln.ListinvoicesResponse\"\x00\x12<\n\tSendOnion\x12\x15.cln.SendonionRequest\x1a\x16.cln.SendonionResponse\"\x00\x12\x45\n\x0cListSendPays\x12\x18.cln.ListsendpaysRequest\x1a\x19.cln.ListsendpaysResponse\"\x00\x12Q\n\x10ListTransactions\x12\x1c.cln.ListtransactionsRequest\x1a\x1d.cln.ListtransactionsResponse\"\x00\x12*\n\x03Pay\x12\x0f.cln.PayRequest\x1a\x10.cln.PayResponse\"\x00\x12<\n\tListNodes\x12\x15.cln.ListnodesRequest\x1a\x16.cln.ListnodesResponse\"\x00\x12K\n\x0eWaitAnyInvoice\x12\x1a.cln.WaitanyinvoiceRequest\x1a\x1b.cln.WaitanyinvoiceResponse\"\x00\x12\x42\n\x0bWaitInvoice\x12\x17.cln.WaitinvoiceRequest\x1a\x18.cln.WaitinvoiceResponse\"\x00\x12\x42\n\x0bWaitSendPay\x12\x17.cln.WaitsendpayRequest\x1a\x18.cln.WaitsendpayResponse\"\x00\x12\x36\n\x07NewAddr\x12\x13.cln.NewaddrRequest\x1a\x14.cln.NewaddrResponse\"\x00\x12\x39\n\x08Withdraw\x12\x14.cln.WithdrawRequest\x1a\x15.cln.WithdrawResponse\"\x00\x12\x36\n\x07KeySend\x12\x13.cln.KeysendRequest\x1a\x14.cln.KeysendResponse\"\x00\x12\x39\n\x08\x46undPsbt\x12\x14.cln.FundpsbtRequest\x1a\x15.cln.FundpsbtResponse\"\x00\x12\x39\n\x08SendPsbt\x12\x14.cln.SendpsbtRequest\x1a\x15.cln.SendpsbtResponse\"\x00\x12\x39\n\x08SignPsbt\x12\x14.cln.SignpsbtRequest\x1a\x15.cln.SignpsbtResponse\"\x00\x12\x39\n\x08UtxoPsbt\x12\x14.cln.UtxopsbtRequest\x1a\x15.cln.UtxopsbtResponse\"\x00\x12<\n\tTxDiscard\x12\x15.cln.TxdiscardRequest\x1a\x16.cln.TxdiscardResponse\"\x00\x12<\n\tTxPrepare\x12\x15.cln.TxprepareRequest\x1a\x16.cln.TxprepareResponse\"\x00\x12\x33\n\x06TxSend\x12\x12.cln.TxsendRequest\x1a\x13.cln.TxsendResponse\"\x00\x12Q\n\x10ListPeerChannels\x12\x1c.cln.ListpeerchannelsRequest\x1a\x1d.cln.ListpeerchannelsResponse\"\x00\x12W\n\x12ListClosedChannels\x12\x1e.cln.ListclosedchannelsRequest\x1a\x1f.cln.ListclosedchannelsResponse\"\x00\x12<\n\tDecodePay\x12\x15.cln.DecodepayRequest\x1a\x16.cln.DecodepayResponse\"\x00\x12\x33\n\x06\x44\x65\x63ode\x12\x12.cln.DecodeRequest\x1a\x13.cln.DecodeResponse\"\x00\x12?\n\nDisconnect\x12\x16.cln.DisconnectRequest\x1a\x17.cln.DisconnectResponse\"\x00\x12\x39\n\x08\x46\x65\x65rates\x12\x14.cln.FeeratesRequest\x1a\x15.cln.FeeratesResponse\"\x00\x12\x45\n\x0c\x46\x65tchInvoice\x12\x18.cln.FetchinvoiceRequest\x1a\x19.cln.FetchinvoiceResponse\"\x00\x12\x42\n\x0b\x46undChannel\x12\x17.cln.FundchannelRequest\x1a\x18.cln.FundchannelResponse\"\x00\x12\x39\n\x08GetRoute\x12\x14.cln.GetrouteRequest\x1a\x15.cln.GetrouteResponse\"\x00\x12\x45\n\x0cListForwards\x12\x18.cln.ListforwardsRequest\x1a\x19.cln.ListforwardsResponse\"\x00\x12\x39\n\x08ListPays\x12\x14.cln.ListpaysRequest\x1a\x15.cln.ListpaysResponse\"\x00\x12<\n\tListHtlcs\x12\x15.cln.ListhtlcsRequest\x1a\x16.cln.ListhtlcsResponse\"\x00\x12-\n\x04Ping\x12\x10.cln.PingRequest\x1a\x11.cln.PingResponse\"\x00\x12H\n\rSendCustomMsg\x12\x19.cln.SendcustommsgRequest\x1a\x1a.cln.SendcustommsgResponse\"\x00\x12?\n\nSetChannel\x12\x16.cln.SetchannelRequest\x1a\x17.cln.SetchannelResponse\"\x00\x12\x42\n\x0bSignInvoice\x12\x17.cln.SigninvoiceRequest\x1a\x18.cln.SigninvoiceResponse\"\x00\x12\x42\n\x0bSignMessage\x12\x17.cln.SignmessageRequest\x1a\x18.cln.SignmessageResponse\"\x00\x12N\n\x0fWaitBlockHeight\x12\x1b.cln.WaitblockheightRequest\x1a\x1c.cln.WaitblockheightResponse\"\x00\x12-\n\x04Wait\x12\x10.cln.WaitRequest\x1a\x11.cln.WaitResponse\"\x00\x12-\n\x04Stop\x12\x10.cln.StopRequest\x1a\x11.cln.StopResponse\"\x00\x12T\n\x11PreApproveKeysend\x12\x1d.cln.PreapprovekeysendRequest\x1a\x1e.cln.PreapprovekeysendResponse\"\x00\x12T\n\x11PreApproveInvoice\x12\x1d.cln.PreapproveinvoiceRequest\x1a\x1e.cln.PreapproveinvoiceResponse\"\x00\x12\x45\n\x0cStaticBackup\x12\x18.cln.StaticbackupRequest\x1a\x19.cln.StaticbackupResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -298,185 +298,191 @@ _globals['_LISTPEERCHANNELSRESPONSE']._serialized_start=25764 _globals['_LISTPEERCHANNELSRESPONSE']._serialized_end=25839 _globals['_LISTPEERCHANNELSCHANNELS']._serialized_start=25842 - _globals['_LISTPEERCHANNELSCHANNELS']._serialized_end=29132 - _globals['_LISTPEERCHANNELSCHANNELS_LISTPEERCHANNELSCHANNELSSTATE']._serialized_start=27833 - _globals['_LISTPEERCHANNELSCHANNELS_LISTPEERCHANNELSCHANNELSSTATE']._serialized_end=28217 - _globals['_LISTPEERCHANNELSCHANNELSFEERATE']._serialized_start=29134 - _globals['_LISTPEERCHANNELSCHANNELSFEERATE']._serialized_end=29227 - _globals['_LISTPEERCHANNELSCHANNELSINFLIGHT']._serialized_start=29230 - _globals['_LISTPEERCHANNELSCHANNELSINFLIGHT']._serialized_end=29614 - _globals['_LISTPEERCHANNELSCHANNELSFUNDING']._serialized_start=29617 - _globals['_LISTPEERCHANNELSCHANNELSFUNDING']._serialized_end=29955 - _globals['_LISTPEERCHANNELSCHANNELSALIAS']._serialized_start=29957 - _globals['_LISTPEERCHANNELSCHANNELSALIAS']._serialized_end=30050 - _globals['_LISTPEERCHANNELSCHANNELSHTLCS']._serialized_start=30053 - _globals['_LISTPEERCHANNELSCHANNELSHTLCS']._serialized_end=30535 - _globals['_LISTPEERCHANNELSCHANNELSHTLCS_LISTPEERCHANNELSCHANNELSHTLCSDIRECTION']._serialized_start=30374 - _globals['_LISTPEERCHANNELSCHANNELSHTLCS_LISTPEERCHANNELSCHANNELSHTLCSDIRECTION']._serialized_end=30431 - _globals['_LISTCLOSEDCHANNELSREQUEST']._serialized_start=30537 - _globals['_LISTCLOSEDCHANNELSREQUEST']._serialized_end=30588 - _globals['_LISTCLOSEDCHANNELSRESPONSE']._serialized_start=30590 - _globals['_LISTCLOSEDCHANNELSRESPONSE']._serialized_end=30681 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS']._serialized_start=30684 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS']._serialized_end=31886 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS_LISTCLOSEDCHANNELSCLOSEDCHANNELSCLOSE_CAUSE']._serialized_start=31584 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS_LISTCLOSEDCHANNELSCLOSEDCHANNELSCLOSE_CAUSE']._serialized_end=31702 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELSALIAS']._serialized_start=31888 - _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELSALIAS']._serialized_end=31989 - _globals['_DECODEPAYREQUEST']._serialized_start=31991 - _globals['_DECODEPAYREQUEST']._serialized_end=32067 - _globals['_DECODEPAYRESPONSE']._serialized_start=32070 - _globals['_DECODEPAYRESPONSE']._serialized_end=32595 - _globals['_DECODEPAYFALLBACKS']._serialized_start=32598 - _globals['_DECODEPAYFALLBACKS']._serialized_end=32806 - _globals['_DECODEPAYFALLBACKS_DECODEPAYFALLBACKSTYPE']._serialized_start=32719 - _globals['_DECODEPAYFALLBACKS_DECODEPAYFALLBACKSTYPE']._serialized_end=32797 - _globals['_DECODEPAYEXTRA']._serialized_start=32808 - _globals['_DECODEPAYEXTRA']._serialized_end=32851 - _globals['_DECODEREQUEST']._serialized_start=32853 - _globals['_DECODEREQUEST']._serialized_end=32884 - _globals['_DECODERESPONSE']._serialized_start=32887 - _globals['_DECODERESPONSE']._serialized_end=37215 - _globals['_DECODERESPONSE_DECODETYPE']._serialized_start=35480 - _globals['_DECODERESPONSE_DECODETYPE']._serialized_end=35611 - _globals['_DECODEOFFER_PATHS']._serialized_start=37217 - _globals['_DECODEOFFER_PATHS']._serialized_end=37277 - _globals['_DECODEOFFER_RECURRENCEPAYWINDOW']._serialized_start=37280 - _globals['_DECODEOFFER_RECURRENCEPAYWINDOW']._serialized_end=37418 - _globals['_DECODEINVOICE_PATHSPATH']._serialized_start=37420 - _globals['_DECODEINVOICE_PATHSPATH']._serialized_end=37504 - _globals['_DECODEINVOICE_FALLBACKS']._serialized_start=37506 - _globals['_DECODEINVOICE_FALLBACKS']._serialized_end=37595 - _globals['_DECODEFALLBACKS']._serialized_start=37597 - _globals['_DECODEFALLBACKS']._serialized_end=37716 - _globals['_DECODEEXTRA']._serialized_start=37718 - _globals['_DECODEEXTRA']._serialized_end=37758 - _globals['_DECODERESTRICTIONS']._serialized_start=37760 - _globals['_DECODERESTRICTIONS']._serialized_end=37819 - _globals['_DISCONNECTREQUEST']._serialized_start=37821 - _globals['_DISCONNECTREQUEST']._serialized_end=37882 - _globals['_DISCONNECTRESPONSE']._serialized_start=37884 - _globals['_DISCONNECTRESPONSE']._serialized_end=37904 - _globals['_FEERATESREQUEST']._serialized_start=37906 - _globals['_FEERATESREQUEST']._serialized_end=38013 - _globals['_FEERATESREQUEST_FEERATESSTYLE']._serialized_start=37976 - _globals['_FEERATESREQUEST_FEERATESSTYLE']._serialized_end=38013 - _globals['_FEERATESRESPONSE']._serialized_start=38016 - _globals['_FEERATESRESPONSE']._serialized_end=38300 - _globals['_FEERATESPERKB']._serialized_start=38303 - _globals['_FEERATESPERKB']._serialized_end=38770 - _globals['_FEERATESPERKBESTIMATES']._serialized_start=38773 - _globals['_FEERATESPERKBESTIMATES']._serialized_end=38923 - _globals['_FEERATESPERKW']._serialized_start=38926 - _globals['_FEERATESPERKW']._serialized_end=39393 - _globals['_FEERATESPERKWESTIMATES']._serialized_start=39396 - _globals['_FEERATESPERKWESTIMATES']._serialized_end=39546 - _globals['_FEERATESONCHAIN_FEE_ESTIMATES']._serialized_start=39549 - _globals['_FEERATESONCHAIN_FEE_ESTIMATES']._serialized_end=39832 - _globals['_FETCHINVOICEREQUEST']._serialized_start=39835 - _globals['_FETCHINVOICEREQUEST']._serialized_end=40196 - _globals['_FETCHINVOICERESPONSE']._serialized_start=40199 - _globals['_FETCHINVOICERESPONSE']._serialized_end=40353 - _globals['_FETCHINVOICECHANGES']._serialized_start=40356 - _globals['_FETCHINVOICECHANGES']._serialized_end=40614 - _globals['_FETCHINVOICENEXT_PERIOD']._serialized_start=40616 - _globals['_FETCHINVOICENEXT_PERIOD']._serialized_end=40742 - _globals['_FUNDCHANNELREQUEST']._serialized_start=40745 - _globals['_FUNDCHANNELREQUEST']._serialized_end=41230 - _globals['_FUNDCHANNELRESPONSE']._serialized_start=41233 - _globals['_FUNDCHANNELRESPONSE']._serialized_end=41388 - _globals['_GETROUTEREQUEST']._serialized_start=41391 - _globals['_GETROUTEREQUEST']._serialized_end=41627 - _globals['_GETROUTERESPONSE']._serialized_start=41629 - _globals['_GETROUTERESPONSE']._serialized_end=41682 - _globals['_GETROUTEROUTE']._serialized_start=41685 - _globals['_GETROUTEROUTE']._serialized_end=41882 - _globals['_GETROUTEROUTE_GETROUTEROUTESTYLE']._serialized_start=41853 - _globals['_GETROUTEROUTE_GETROUTEROUTESTYLE']._serialized_end=41882 - _globals['_LISTFORWARDSREQUEST']._serialized_start=41885 - _globals['_LISTFORWARDSREQUEST']._serialized_end=42324 - _globals['_LISTFORWARDSREQUEST_LISTFORWARDSSTATUS']._serialized_start=42129 - _globals['_LISTFORWARDSREQUEST_LISTFORWARDSSTATUS']._serialized_end=42205 - _globals['_LISTFORWARDSREQUEST_LISTFORWARDSINDEX']._serialized_start=42207 - _globals['_LISTFORWARDSREQUEST_LISTFORWARDSINDEX']._serialized_end=42252 - _globals['_LISTFORWARDSRESPONSE']._serialized_start=42326 - _globals['_LISTFORWARDSRESPONSE']._serialized_end=42393 - _globals['_LISTFORWARDSFORWARDS']._serialized_start=42396 - _globals['_LISTFORWARDSFORWARDS']._serialized_end=43094 - _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS']._serialized_start=42841 - _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS']._serialized_end=42925 - _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE']._serialized_start=42927 - _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE']._serialized_end=42975 - _globals['_LISTPAYSREQUEST']._serialized_start=43097 - _globals['_LISTPAYSREQUEST']._serialized_end=43316 - _globals['_LISTPAYSREQUEST_LISTPAYSSTATUS']._serialized_start=43222 - _globals['_LISTPAYSREQUEST_LISTPAYSSTATUS']._serialized_end=43277 - _globals['_LISTPAYSRESPONSE']._serialized_start=43318 - _globals['_LISTPAYSRESPONSE']._serialized_end=43369 - _globals['_LISTPAYSPAYS']._serialized_start=43372 - _globals['_LISTPAYSPAYS']._serialized_end=44011 - _globals['_LISTPAYSPAYS_LISTPAYSPAYSSTATUS']._serialized_start=43786 - _globals['_LISTPAYSPAYS_LISTPAYSPAYSSTATUS']._serialized_end=43845 - _globals['_LISTHTLCSREQUEST']._serialized_start=44013 - _globals['_LISTHTLCSREQUEST']._serialized_end=44055 - _globals['_LISTHTLCSRESPONSE']._serialized_start=44057 - _globals['_LISTHTLCSRESPONSE']._serialized_end=44112 - _globals['_LISTHTLCSHTLCS']._serialized_start=44115 - _globals['_LISTHTLCSHTLCS']._serialized_end=44380 - _globals['_LISTHTLCSHTLCS_LISTHTLCSHTLCSDIRECTION']._serialized_start=44338 - _globals['_LISTHTLCSHTLCS_LISTHTLCSHTLCSDIRECTION']._serialized_end=44380 - _globals['_PINGREQUEST']._serialized_start=44382 - _globals['_PINGREQUEST']._serialized_end=44471 - _globals['_PINGRESPONSE']._serialized_start=44473 - _globals['_PINGRESPONSE']._serialized_end=44503 - _globals['_SENDCUSTOMMSGREQUEST']._serialized_start=44505 - _globals['_SENDCUSTOMMSGREQUEST']._serialized_end=44557 - _globals['_SENDCUSTOMMSGRESPONSE']._serialized_start=44559 - _globals['_SENDCUSTOMMSGRESPONSE']._serialized_end=44598 - _globals['_SETCHANNELREQUEST']._serialized_start=44601 - _globals['_SETCHANNELREQUEST']._serialized_end=44899 - _globals['_SETCHANNELRESPONSE']._serialized_start=44901 - _globals['_SETCHANNELRESPONSE']._serialized_end=44964 - _globals['_SETCHANNELCHANNELS']._serialized_start=44967 - _globals['_SETCHANNELCHANNELS']._serialized_end=45425 - _globals['_SIGNINVOICEREQUEST']._serialized_start=45427 - _globals['_SIGNINVOICEREQUEST']._serialized_end=45466 - _globals['_SIGNINVOICERESPONSE']._serialized_start=45468 - _globals['_SIGNINVOICERESPONSE']._serialized_end=45505 - _globals['_SIGNMESSAGEREQUEST']._serialized_start=45507 - _globals['_SIGNMESSAGEREQUEST']._serialized_end=45544 - _globals['_SIGNMESSAGERESPONSE']._serialized_start=45546 - _globals['_SIGNMESSAGERESPONSE']._serialized_end=45616 - _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_start=45618 - _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_end=45697 - _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_start=45699 - _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_end=45745 - _globals['_WAITREQUEST']._serialized_start=45748 - _globals['_WAITREQUEST']._serialized_end=45997 - _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_start=45884 - _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_end=45941 - _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_start=45943 - _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_end=45997 - _globals['_WAITRESPONSE']._serialized_start=46000 - _globals['_WAITRESPONSE']._serialized_end=46227 - _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_start=45884 - _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_end=45941 - _globals['_STOPREQUEST']._serialized_start=46229 - _globals['_STOPREQUEST']._serialized_end=46242 - _globals['_STOPRESPONSE']._serialized_start=46244 - _globals['_STOPRESPONSE']._serialized_end=46258 - _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_start=46261 - _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_end=46428 - _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_start=46430 - _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_end=46457 - _globals['_PREAPPROVEINVOICEREQUEST']._serialized_start=46459 - _globals['_PREAPPROVEINVOICEREQUEST']._serialized_end=46517 - _globals['_PREAPPROVEINVOICERESPONSE']._serialized_start=46519 - _globals['_PREAPPROVEINVOICERESPONSE']._serialized_end=46546 - _globals['_STATICBACKUPREQUEST']._serialized_start=46548 - _globals['_STATICBACKUPREQUEST']._serialized_end=46569 - _globals['_STATICBACKUPRESPONSE']._serialized_start=46571 - _globals['_STATICBACKUPRESPONSE']._serialized_end=46606 - _globals['_NODE']._serialized_start=46609 - _globals['_NODE']._serialized_end=50611 + _globals['_LISTPEERCHANNELSCHANNELS']._serialized_end=29204 + _globals['_LISTPEERCHANNELSCHANNELS_LISTPEERCHANNELSCHANNELSSTATE']._serialized_start=27893 + _globals['_LISTPEERCHANNELSCHANNELS_LISTPEERCHANNELSCHANNELSSTATE']._serialized_end=28277 + _globals['_LISTPEERCHANNELSCHANNELSUPDATES']._serialized_start=29207 + _globals['_LISTPEERCHANNELSCHANNELSUPDATES']._serialized_end=29389 + _globals['_LISTPEERCHANNELSCHANNELSUPDATESLOCAL']._serialized_start=29392 + _globals['_LISTPEERCHANNELSCHANNELSUPDATESLOCAL']._serialized_end=29751 + _globals['_LISTPEERCHANNELSCHANNELSUPDATESREMOTE']._serialized_start=29754 + _globals['_LISTPEERCHANNELSCHANNELSUPDATESREMOTE']._serialized_end=30114 + _globals['_LISTPEERCHANNELSCHANNELSFEERATE']._serialized_start=30116 + _globals['_LISTPEERCHANNELSCHANNELSFEERATE']._serialized_end=30209 + _globals['_LISTPEERCHANNELSCHANNELSINFLIGHT']._serialized_start=30212 + _globals['_LISTPEERCHANNELSCHANNELSINFLIGHT']._serialized_end=30596 + _globals['_LISTPEERCHANNELSCHANNELSFUNDING']._serialized_start=30599 + _globals['_LISTPEERCHANNELSCHANNELSFUNDING']._serialized_end=30937 + _globals['_LISTPEERCHANNELSCHANNELSALIAS']._serialized_start=30939 + _globals['_LISTPEERCHANNELSCHANNELSALIAS']._serialized_end=31032 + _globals['_LISTPEERCHANNELSCHANNELSHTLCS']._serialized_start=31035 + _globals['_LISTPEERCHANNELSCHANNELSHTLCS']._serialized_end=31517 + _globals['_LISTPEERCHANNELSCHANNELSHTLCS_LISTPEERCHANNELSCHANNELSHTLCSDIRECTION']._serialized_start=31356 + _globals['_LISTPEERCHANNELSCHANNELSHTLCS_LISTPEERCHANNELSCHANNELSHTLCSDIRECTION']._serialized_end=31413 + _globals['_LISTCLOSEDCHANNELSREQUEST']._serialized_start=31519 + _globals['_LISTCLOSEDCHANNELSREQUEST']._serialized_end=31570 + _globals['_LISTCLOSEDCHANNELSRESPONSE']._serialized_start=31572 + _globals['_LISTCLOSEDCHANNELSRESPONSE']._serialized_end=31663 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS']._serialized_start=31666 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS']._serialized_end=32868 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS_LISTCLOSEDCHANNELSCLOSEDCHANNELSCLOSE_CAUSE']._serialized_start=32566 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELS_LISTCLOSEDCHANNELSCLOSEDCHANNELSCLOSE_CAUSE']._serialized_end=32684 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELSALIAS']._serialized_start=32870 + _globals['_LISTCLOSEDCHANNELSCLOSEDCHANNELSALIAS']._serialized_end=32971 + _globals['_DECODEPAYREQUEST']._serialized_start=32973 + _globals['_DECODEPAYREQUEST']._serialized_end=33049 + _globals['_DECODEPAYRESPONSE']._serialized_start=33052 + _globals['_DECODEPAYRESPONSE']._serialized_end=33577 + _globals['_DECODEPAYFALLBACKS']._serialized_start=33580 + _globals['_DECODEPAYFALLBACKS']._serialized_end=33788 + _globals['_DECODEPAYFALLBACKS_DECODEPAYFALLBACKSTYPE']._serialized_start=33701 + _globals['_DECODEPAYFALLBACKS_DECODEPAYFALLBACKSTYPE']._serialized_end=33779 + _globals['_DECODEPAYEXTRA']._serialized_start=33790 + _globals['_DECODEPAYEXTRA']._serialized_end=33833 + _globals['_DECODEREQUEST']._serialized_start=33835 + _globals['_DECODEREQUEST']._serialized_end=33866 + _globals['_DECODERESPONSE']._serialized_start=33869 + _globals['_DECODERESPONSE']._serialized_end=38197 + _globals['_DECODERESPONSE_DECODETYPE']._serialized_start=36462 + _globals['_DECODERESPONSE_DECODETYPE']._serialized_end=36593 + _globals['_DECODEOFFER_PATHS']._serialized_start=38199 + _globals['_DECODEOFFER_PATHS']._serialized_end=38259 + _globals['_DECODEOFFER_RECURRENCEPAYWINDOW']._serialized_start=38262 + _globals['_DECODEOFFER_RECURRENCEPAYWINDOW']._serialized_end=38400 + _globals['_DECODEINVOICE_PATHSPATH']._serialized_start=38402 + _globals['_DECODEINVOICE_PATHSPATH']._serialized_end=38486 + _globals['_DECODEINVOICE_FALLBACKS']._serialized_start=38488 + _globals['_DECODEINVOICE_FALLBACKS']._serialized_end=38577 + _globals['_DECODEFALLBACKS']._serialized_start=38579 + _globals['_DECODEFALLBACKS']._serialized_end=38698 + _globals['_DECODEEXTRA']._serialized_start=38700 + _globals['_DECODEEXTRA']._serialized_end=38740 + _globals['_DECODERESTRICTIONS']._serialized_start=38742 + _globals['_DECODERESTRICTIONS']._serialized_end=38801 + _globals['_DISCONNECTREQUEST']._serialized_start=38803 + _globals['_DISCONNECTREQUEST']._serialized_end=38864 + _globals['_DISCONNECTRESPONSE']._serialized_start=38866 + _globals['_DISCONNECTRESPONSE']._serialized_end=38886 + _globals['_FEERATESREQUEST']._serialized_start=38888 + _globals['_FEERATESREQUEST']._serialized_end=38995 + _globals['_FEERATESREQUEST_FEERATESSTYLE']._serialized_start=38958 + _globals['_FEERATESREQUEST_FEERATESSTYLE']._serialized_end=38995 + _globals['_FEERATESRESPONSE']._serialized_start=38998 + _globals['_FEERATESRESPONSE']._serialized_end=39282 + _globals['_FEERATESPERKB']._serialized_start=39285 + _globals['_FEERATESPERKB']._serialized_end=39752 + _globals['_FEERATESPERKBESTIMATES']._serialized_start=39755 + _globals['_FEERATESPERKBESTIMATES']._serialized_end=39905 + _globals['_FEERATESPERKW']._serialized_start=39908 + _globals['_FEERATESPERKW']._serialized_end=40375 + _globals['_FEERATESPERKWESTIMATES']._serialized_start=40378 + _globals['_FEERATESPERKWESTIMATES']._serialized_end=40528 + _globals['_FEERATESONCHAIN_FEE_ESTIMATES']._serialized_start=40531 + _globals['_FEERATESONCHAIN_FEE_ESTIMATES']._serialized_end=40814 + _globals['_FETCHINVOICEREQUEST']._serialized_start=40817 + _globals['_FETCHINVOICEREQUEST']._serialized_end=41178 + _globals['_FETCHINVOICERESPONSE']._serialized_start=41181 + _globals['_FETCHINVOICERESPONSE']._serialized_end=41335 + _globals['_FETCHINVOICECHANGES']._serialized_start=41338 + _globals['_FETCHINVOICECHANGES']._serialized_end=41596 + _globals['_FETCHINVOICENEXT_PERIOD']._serialized_start=41598 + _globals['_FETCHINVOICENEXT_PERIOD']._serialized_end=41724 + _globals['_FUNDCHANNELREQUEST']._serialized_start=41727 + _globals['_FUNDCHANNELREQUEST']._serialized_end=42212 + _globals['_FUNDCHANNELRESPONSE']._serialized_start=42215 + _globals['_FUNDCHANNELRESPONSE']._serialized_end=42370 + _globals['_GETROUTEREQUEST']._serialized_start=42373 + _globals['_GETROUTEREQUEST']._serialized_end=42609 + _globals['_GETROUTERESPONSE']._serialized_start=42611 + _globals['_GETROUTERESPONSE']._serialized_end=42664 + _globals['_GETROUTEROUTE']._serialized_start=42667 + _globals['_GETROUTEROUTE']._serialized_end=42864 + _globals['_GETROUTEROUTE_GETROUTEROUTESTYLE']._serialized_start=42835 + _globals['_GETROUTEROUTE_GETROUTEROUTESTYLE']._serialized_end=42864 + _globals['_LISTFORWARDSREQUEST']._serialized_start=42867 + _globals['_LISTFORWARDSREQUEST']._serialized_end=43306 + _globals['_LISTFORWARDSREQUEST_LISTFORWARDSSTATUS']._serialized_start=43111 + _globals['_LISTFORWARDSREQUEST_LISTFORWARDSSTATUS']._serialized_end=43187 + _globals['_LISTFORWARDSREQUEST_LISTFORWARDSINDEX']._serialized_start=43189 + _globals['_LISTFORWARDSREQUEST_LISTFORWARDSINDEX']._serialized_end=43234 + _globals['_LISTFORWARDSRESPONSE']._serialized_start=43308 + _globals['_LISTFORWARDSRESPONSE']._serialized_end=43375 + _globals['_LISTFORWARDSFORWARDS']._serialized_start=43378 + _globals['_LISTFORWARDSFORWARDS']._serialized_end=44076 + _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS']._serialized_start=43823 + _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTATUS']._serialized_end=43907 + _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE']._serialized_start=43909 + _globals['_LISTFORWARDSFORWARDS_LISTFORWARDSFORWARDSSTYLE']._serialized_end=43957 + _globals['_LISTPAYSREQUEST']._serialized_start=44079 + _globals['_LISTPAYSREQUEST']._serialized_end=44298 + _globals['_LISTPAYSREQUEST_LISTPAYSSTATUS']._serialized_start=44204 + _globals['_LISTPAYSREQUEST_LISTPAYSSTATUS']._serialized_end=44259 + _globals['_LISTPAYSRESPONSE']._serialized_start=44300 + _globals['_LISTPAYSRESPONSE']._serialized_end=44351 + _globals['_LISTPAYSPAYS']._serialized_start=44354 + _globals['_LISTPAYSPAYS']._serialized_end=44993 + _globals['_LISTPAYSPAYS_LISTPAYSPAYSSTATUS']._serialized_start=44768 + _globals['_LISTPAYSPAYS_LISTPAYSPAYSSTATUS']._serialized_end=44827 + _globals['_LISTHTLCSREQUEST']._serialized_start=44995 + _globals['_LISTHTLCSREQUEST']._serialized_end=45037 + _globals['_LISTHTLCSRESPONSE']._serialized_start=45039 + _globals['_LISTHTLCSRESPONSE']._serialized_end=45094 + _globals['_LISTHTLCSHTLCS']._serialized_start=45097 + _globals['_LISTHTLCSHTLCS']._serialized_end=45362 + _globals['_LISTHTLCSHTLCS_LISTHTLCSHTLCSDIRECTION']._serialized_start=45320 + _globals['_LISTHTLCSHTLCS_LISTHTLCSHTLCSDIRECTION']._serialized_end=45362 + _globals['_PINGREQUEST']._serialized_start=45364 + _globals['_PINGREQUEST']._serialized_end=45453 + _globals['_PINGRESPONSE']._serialized_start=45455 + _globals['_PINGRESPONSE']._serialized_end=45485 + _globals['_SENDCUSTOMMSGREQUEST']._serialized_start=45487 + _globals['_SENDCUSTOMMSGREQUEST']._serialized_end=45539 + _globals['_SENDCUSTOMMSGRESPONSE']._serialized_start=45541 + _globals['_SENDCUSTOMMSGRESPONSE']._serialized_end=45580 + _globals['_SETCHANNELREQUEST']._serialized_start=45583 + _globals['_SETCHANNELREQUEST']._serialized_end=45881 + _globals['_SETCHANNELRESPONSE']._serialized_start=45883 + _globals['_SETCHANNELRESPONSE']._serialized_end=45946 + _globals['_SETCHANNELCHANNELS']._serialized_start=45949 + _globals['_SETCHANNELCHANNELS']._serialized_end=46407 + _globals['_SIGNINVOICEREQUEST']._serialized_start=46409 + _globals['_SIGNINVOICEREQUEST']._serialized_end=46448 + _globals['_SIGNINVOICERESPONSE']._serialized_start=46450 + _globals['_SIGNINVOICERESPONSE']._serialized_end=46487 + _globals['_SIGNMESSAGEREQUEST']._serialized_start=46489 + _globals['_SIGNMESSAGEREQUEST']._serialized_end=46526 + _globals['_SIGNMESSAGERESPONSE']._serialized_start=46528 + _globals['_SIGNMESSAGERESPONSE']._serialized_end=46598 + _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_start=46600 + _globals['_WAITBLOCKHEIGHTREQUEST']._serialized_end=46679 + _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_start=46681 + _globals['_WAITBLOCKHEIGHTRESPONSE']._serialized_end=46727 + _globals['_WAITREQUEST']._serialized_start=46730 + _globals['_WAITREQUEST']._serialized_end=46979 + _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_start=46866 + _globals['_WAITREQUEST_WAITSUBSYSTEM']._serialized_end=46923 + _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_start=46925 + _globals['_WAITREQUEST_WAITINDEXNAME']._serialized_end=46979 + _globals['_WAITRESPONSE']._serialized_start=46982 + _globals['_WAITRESPONSE']._serialized_end=47209 + _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_start=46866 + _globals['_WAITRESPONSE_WAITSUBSYSTEM']._serialized_end=46923 + _globals['_STOPREQUEST']._serialized_start=47211 + _globals['_STOPREQUEST']._serialized_end=47224 + _globals['_STOPRESPONSE']._serialized_start=47226 + _globals['_STOPRESPONSE']._serialized_end=47240 + _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_start=47243 + _globals['_PREAPPROVEKEYSENDREQUEST']._serialized_end=47410 + _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_start=47412 + _globals['_PREAPPROVEKEYSENDRESPONSE']._serialized_end=47439 + _globals['_PREAPPROVEINVOICEREQUEST']._serialized_start=47441 + _globals['_PREAPPROVEINVOICEREQUEST']._serialized_end=47499 + _globals['_PREAPPROVEINVOICERESPONSE']._serialized_start=47501 + _globals['_PREAPPROVEINVOICERESPONSE']._serialized_end=47528 + _globals['_STATICBACKUPREQUEST']._serialized_start=47530 + _globals['_STATICBACKUPREQUEST']._serialized_end=47551 + _globals['_STATICBACKUPRESPONSE']._serialized_start=47553 + _globals['_STATICBACKUPRESPONSE']._serialized_end=47588 + _globals['_NODE']._serialized_start=47591 + _globals['_NODE']._serialized_end=51593 # @@protoc_insertion_point(module_scope) diff --git a/contrib/pyln-testing/pyln/testing/grpc2py.py b/contrib/pyln-testing/pyln/testing/grpc2py.py index 8c00b2a27087..086a859bc040 100644 --- a/contrib/pyln-testing/pyln/testing/grpc2py.py +++ b/contrib/pyln-testing/pyln/testing/grpc2py.py @@ -785,6 +785,31 @@ def listpeerchannels_channels_channel_type2py(m): }) +def listpeerchannels_channels_updates_local2py(m): + return remove_default({ + "htlc_minimum_msat": amount2msat(m.htlc_minimum_msat), # PrimitiveField in generate_composite + "htlc_maximum_msat": amount2msat(m.htlc_maximum_msat), # PrimitiveField in generate_composite + "cltv_expiry_delta": m.cltv_expiry_delta, # PrimitiveField in generate_composite + "fee_base_msat": amount2msat(m.fee_base_msat), # PrimitiveField in generate_composite + "fee_proportional_millionths": m.fee_proportional_millionths, # PrimitiveField in generate_composite + }) + + +def listpeerchannels_channels_updates_remote2py(m): + return remove_default({ + "htlc_minimum_msat": amount2msat(m.htlc_minimum_msat), # PrimitiveField in generate_composite + "htlc_maximum_msat": amount2msat(m.htlc_maximum_msat), # PrimitiveField in generate_composite + "cltv_expiry_delta": m.cltv_expiry_delta, # PrimitiveField in generate_composite + "fee_base_msat": amount2msat(m.fee_base_msat), # PrimitiveField in generate_composite + "fee_proportional_millionths": m.fee_proportional_millionths, # PrimitiveField in generate_composite + }) + + +def listpeerchannels_channels_updates2py(m): + return remove_default({ + }) + + def listpeerchannels_channels_feerate2py(m): return remove_default({ "perkw": m.perkw, # PrimitiveField in generate_composite diff --git a/doc/lightning-listpeerchannels.7.md b/doc/lightning-listpeerchannels.7.md index cfc0d33b101c..8e021fe237cb 100644 --- a/doc/lightning-listpeerchannels.7.md +++ b/doc/lightning-listpeerchannels.7.md @@ -36,6 +36,19 @@ On success, an object containing **channels** is returned. It is an array of ob - Bit number - **names** (array of strings): Feature name for each bit set in this channel\_type: - Name of feature bit (one of "static\_remotekey/even", "anchor\_outputs/even", "anchors\_zero\_fee\_htlc\_tx/even", "scid\_alias/even", "zeroconf/even") +- **updates** (object, optional): Latest gossip updates sent/received *(added v24.02)*: + - **local** (object): Our gossip for channel *(added v24.02)*: + - **htlc\_minimum\_msat** (msat): Minimum msat amount we allow *(added v24.02)* + - **htlc\_maximum\_msat** (msat): Maximum msat amount we allow *(added v24.02)* + - **cltv\_expiry\_delta** (u32): Blocks delay required between incoming and outgoing HTLCs *(added v24.02)* + - **fee\_base\_msat** (msat): Amount we charge to use the channel *(added v24.02)* + - **fee\_proportional\_millionths** (u32): Amount we charge to use the channel in parts-per-million *(added v24.02)* + - **remote** (object, optional): Peer's gossip for channel *(added v24.02)*: + - **htlc\_minimum\_msat** (msat): Minimum msat amount they allow *(added v24.02)* + - **htlc\_maximum\_msat** (msat): Maximum msat amount they allow *(added v24.02)* + - **cltv\_expiry\_delta** (u32): Blocks delay required between incoming and outgoing HTLCs *(added v24.02)* + - **fee\_base\_msat** (msat): Amount they charge to use the channel *(added v24.02)* + - **fee\_proportional\_millionths** (u32): Amount they charge to use the channel in parts-per-million *(added v24.02)* - **ignore\_fee\_limits** (boolean, optional): set if we allow this peer to set fees to anything they want *(added v23.08)* - **feerate** (object, optional): Feerates for the current tx: - **perkw** (u32): Feerate per 1000 weight (i.e kSipa) @@ -202,4 +215,4 @@ Main web site: Lightning RFC site (BOLT \#9): -[comment]: # ( SHA256STAMP:c4507febb0d592ac386f2e8bedbc88ab77d93f780e2d534d6c8d8064afbd6ee6) +[comment]: # ( SHA256STAMP:fac5201293041a7875d78c0f7acc0067ba34d5ad4b809307ea334afde7563aaf) diff --git a/doc/lightning-sql.7.md b/doc/lightning-sql.7.md index f751fcdc7e0c..dd2aef8d2d98 100644 --- a/doc/lightning-sql.7.md +++ b/doc/lightning-sql.7.md @@ -256,6 +256,16 @@ The following tables are currently supported: - `row` (reference to `peerchannels_channel_type.rowid`, sqltype `INTEGER`) - `arrindex` (index within array, sqltype `INTEGER`) - `names` (type `string`, sqltype `TEXT`) + - `local_htlc_minimum_msat` (type `msat`, sqltype `INTEGER`, from JSON object `local`) + - `local_htlc_maximum_msat` (type `msat`, sqltype `INTEGER`, from JSON object `local`) + - `local_cltv_expiry_delta` (type `u32`, sqltype `INTEGER`, from JSON object `local`) + - `local_fee_base_msat` (type `msat`, sqltype `INTEGER`, from JSON object `local`) + - `local_fee_proportional_millionths` (type `u32`, sqltype `INTEGER`, from JSON object `local`) + - `remote_htlc_minimum_msat` (type `msat`, sqltype `INTEGER`, from JSON object `remote`) + - `remote_htlc_maximum_msat` (type `msat`, sqltype `INTEGER`, from JSON object `remote`) + - `remote_cltv_expiry_delta` (type `u32`, sqltype `INTEGER`, from JSON object `remote`) + - `remote_fee_base_msat` (type `msat`, sqltype `INTEGER`, from JSON object `remote`) + - `remote_fee_proportional_millionths` (type `u32`, sqltype `INTEGER`, from JSON object `remote`) - `ignore_fee_limits` (type `boolean`, sqltype `INTEGER`) - `feerate_perkw` (type `u32`, sqltype `INTEGER`, from JSON object `feerate`) - `feerate_perkb` (type `u32`, sqltype `INTEGER`, from JSON object `feerate`) @@ -520,4 +530,4 @@ RESOURCES --------- Main web site: -[comment]: # ( SHA256STAMP:f1434805992a6d428e96c93e2acde932d99da9cfbc91c9b543b3553b1af39c9b) +[comment]: # ( SHA256STAMP:5c5e14f8fde75b877080c0c10feb786f1d2fefbb61a62aecb8d003d1d54627e9) diff --git a/doc/schemas/listpeerchannels.schema.json b/doc/schemas/listpeerchannels.schema.json index 64dc2a4ff283..e731f6c2cc21 100644 --- a/doc/schemas/listpeerchannels.schema.json +++ b/doc/schemas/listpeerchannels.schema.json @@ -87,6 +87,97 @@ } } }, + "updates": { + "type": "object", + "added": "v24.02", + "description": "Latest gossip updates sent/received", + "additionalProperties": false, + "required": [ + "local" + ], + "properties": { + "local": { + "type": "object", + "description": "Our gossip for channel", + "additionalProperties": false, + "added": "v24.02", + "required": [ + "htlc_minimum_msat", + "htlc_maximum_msat", + "cltv_expiry_delta", + "fee_base_msat", + "fee_proportional_millionths" + ], + "properties": { + "htlc_minimum_msat": { + "type": "msat", + "added": "v24.02", + "description": "Minimum msat amount we allow" + }, + "htlc_maximum_msat": { + "type": "msat", + "added": "v24.02", + "description": "Maximum msat amount we allow" + }, + "cltv_expiry_delta": { + "type": "u32", + "added": "v24.02", + "description": "Blocks delay required between incoming and outgoing HTLCs" + }, + "fee_base_msat": { + "type": "msat", + "added": "v24.02", + "description": "Amount we charge to use the channel" + }, + "fee_proportional_millionths": { + "type": "u32", + "added": "v24.02", + "description": "Amount we charge to use the channel in parts-per-million" + } + } + }, + "remote": { + "type": "object", + "added": "v24.02", + "description": "Peer's gossip for channel", + "additionalProperties": false, + "required": [ + "htlc_minimum_msat", + "htlc_maximum_msat", + "cltv_expiry_delta", + "fee_base_msat", + "fee_proportional_millionths" + ], + "properties": { + "htlc_minimum_msat": { + "type": "msat", + "added": "v24.02", + "description": "Minimum msat amount they allow" + }, + "htlc_maximum_msat": { + "type": "msat", + "added": "v24.02", + "description": "Maximum msat amount they allow" + }, + "cltv_expiry_delta": { + "type": "u32", + "added": "v24.02", + "description": "Blocks delay required between incoming and outgoing HTLCs" + }, + "fee_base_msat": { + "type": "msat", + "added": "v24.02", + "description": "Amount they charge to use the channel" + }, + "fee_proportional_millionths": { + "type": "u32", + "added": "v24.02", + "description": "Amount they charge to use the channel in parts-per-million" + } + } + } + } + }, "ignore_fee_limits": { "type": "boolean", "added": "v23.08", @@ -632,6 +723,7 @@ "owner": {}, "short_channel_id": {}, "channel_id": {}, + "updates": {}, "funding_txid": {}, "funding_outnum": {}, "close_to": {}, @@ -723,6 +815,7 @@ "owner": {}, "short_channel_id": {}, "channel_id": {}, + "updates": {}, "funding_txid": {}, "funding_outnum": {}, "inflight": {}, @@ -813,6 +906,7 @@ "owner": {}, "short_channel_id": {}, "channel_id": {}, + "updates": {}, "funding_txid": {}, "funding_outnum": {}, "inflight": {}, @@ -905,6 +999,7 @@ "alias": {}, "short_channel_id": {}, "channel_id": {}, + "updates": {}, "funding_txid": {}, "funding_outnum": {}, "close_to": {}, diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index cabac68dc439..195eefab5662 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -848,7 +848,39 @@ static void json_add_channel(struct lightningd *ld, if (channel->ignore_fee_limits) { json_add_bool(response, "ignore_fee_limits", channel->ignore_fee_limits); } + /* This reflects current gossip */ + json_object_start(response, "updates"); + json_object_start(response, "local"); + json_add_amount_msat(response, + "htlc_minimum_msat", + channel->htlc_minimum_msat); + json_add_amount_msat(response, + "htlc_maximum_msat", + channel->htlc_maximum_msat); + json_add_u32(response, "cltv_expiry_delta", ld->config.cltv_expiry_delta); + json_add_amount_msat(response, "fee_base_msat", + amount_msat(channel->feerate_base)); + json_add_u32(response, "fee_proportional_millionths", + channel->feerate_ppm); + json_object_end(response); + if (channel->peer_update) { + json_object_start(response, "remote"); + json_add_amount_msat(response, + "htlc_minimum_msat", + channel->peer_update->htlc_minimum_msat); + json_add_amount_msat(response, + "htlc_maximum_msat", + channel->peer_update->htlc_maximum_msat); + json_add_u32(response, "cltv_expiry_delta", channel->peer_update->cltv_delta); + json_add_amount_msat(response, "fee_base_msat", + amount_msat(channel->peer_update->fee_base)); + json_add_u32(response, "fee_proportional_millionths", + channel->peer_update->fee_ppm); + json_object_end(response); + } + json_object_end(response); } + json_add_string(response, "state", channel_state_name(channel)); if (channel->last_tx && !invalid_last_tx(channel->last_tx)) { struct bitcoin_txid txid; diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 7ec59adebc2f..894b85992832 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -3713,6 +3713,26 @@ def test_sql(node_factory, bitcoind): 'type': 'string'}, {'name': 'scratch_txid', 'type': 'txid'}, + {'name': 'local_htlc_minimum_msat', + 'type': 'msat'}, + {'name': 'local_htlc_maximum_msat', + 'type': 'msat'}, + {'name': 'local_cltv_expiry_delta', + 'type': 'u32'}, + {'name': 'local_fee_base_msat', + 'type': 'msat'}, + {'name': 'local_fee_proportional_millionths', + 'type': 'u32'}, + {'name': 'remote_htlc_minimum_msat', + 'type': 'msat'}, + {'name': 'remote_htlc_maximum_msat', + 'type': 'msat'}, + {'name': 'remote_cltv_expiry_delta', + 'type': 'u32'}, + {'name': 'remote_fee_base_msat', + 'type': 'msat'}, + {'name': 'remote_fee_proportional_millionths', + 'type': 'u32'}, {'name': 'ignore_fee_limits', 'type': 'boolean'}, {'name': 'feerate_perkw', From c0bc986901f692c6fe8d3735fae6017c148d799f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 09/29] pyln-testing: when waiting for active channel, make sure remote has sent fee info. Signed-off-by: Rusty Russell --- contrib/pyln-testing/pyln/testing/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index 7f39637d2c76..968aea657034 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -1132,7 +1132,7 @@ def get_channel_id(self, other): def is_local_channel_active(self, scid): """Is the local channel @scid usable?""" channels = self.rpc.listpeerchannels()['channels'] - return [c['state'] in ('CHANNELD_NORMAL', 'CHANNELD_AWAITING_SPLICE') for c in channels if c.get('short_channel_id') == scid] == [True] + return [c['state'] in ('CHANNELD_NORMAL', 'CHANNELD_AWAITING_SPLICE') and 'remote' in c.get('updates', {}) for c in channels if c.get('short_channel_id') == scid] == [True] def wait_local_channel_active(self, scid): wait_for(lambda: self.is_local_channel_active(scid)) From 9cb6644de54242b4a959a9490cc35f54e307158c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 10/29] gossmap: insert temporary per-caller flag to turn off private gossip. This lets us convert one user at a time. Signed-off-by: Rusty Russell --- common/gossmap.c | 6 ++++-- common/gossmap.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/common/gossmap.c b/common/gossmap.c index 4495574cf824..5c54dd835d9d 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -17,6 +17,8 @@ #include #include +bool gossmap_public_only; + /* We need this global to decode indexes for hash functions */ static struct gossmap *map; @@ -636,11 +638,11 @@ static bool map_catchup(struct gossmap *map, size_t *num_rejected) type = map_be16(map, off); if (type == WIRE_CHANNEL_ANNOUNCEMENT) add_channel(map, off, false); - else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL) + else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL && !gossmap_public_only) add_channel(map, off + 2 + 8 + 2, true); else if (type == WIRE_CHANNEL_UPDATE) num_bad += !update_channel(map, off); - else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE) + else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE && !gossmap_public_only) num_bad += !update_channel(map, off + 2 + 2); else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN) remove_channel_by_deletemsg(map, off); diff --git a/common/gossmap.h b/common/gossmap.h index b173c9bd5515..19f87d0e4d36 100644 --- a/common/gossmap.h +++ b/common/gossmap.h @@ -40,6 +40,9 @@ struct gossmap_chan { } half[2]; }; +/* Temporary flag for testing: don't load private gossip info! */ +extern bool gossmap_public_only; + /* If num_channel_updates_rejected is not NULL, indicates how many channels we * marked inactive because their values were too high to be represented. */ struct gossmap *gossmap_load(const tal_t *ctx, const char *filename, From adf5758142fb088e58dda070124d0da0db07ab46 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 11/29] common: generic routine to turn listpeerchannels into gossmap local updates. This is more thorough than the minimal one required for getroute(), including the feerates and cltv deltas. Signed-off-by: Rusty Russell --- common/Makefile | 1 + common/gossmods_listpeerchannels.c | 158 +++++++++++++++++++++++++++++ common/gossmods_listpeerchannels.h | 74 ++++++++++++++ plugins/topology.c | 88 +--------------- 4 files changed, 238 insertions(+), 83 deletions(-) create mode 100644 common/gossmods_listpeerchannels.c create mode 100644 common/gossmods_listpeerchannels.h diff --git a/common/Makefile b/common/Makefile index 3e6a5e167bc0..d37acb4c90fc 100644 --- a/common/Makefile +++ b/common/Makefile @@ -39,6 +39,7 @@ COMMON_SRC_NOGEN := \ common/fp16.c \ common/gossip_store.c \ common/gossmap.c \ + common/gossmods_listpeerchannels.c \ common/hash_u5.c \ common/hmac.c \ common/hsm_encryption.c \ diff --git a/common/gossmods_listpeerchannels.c b/common/gossmods_listpeerchannels.c new file mode 100644 index 000000000000..297e28a25ac9 --- /dev/null +++ b/common/gossmods_listpeerchannels.c @@ -0,0 +1,158 @@ +#include "config.h" +#include +#include +#include +#include +#include + +void gossmod_add_localchan(struct gossmap_localmods *mods, + const struct node_id *self, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf UNUSED, + const jsmntok_t *chantok UNUSED, + void *cbarg UNUSED) +{ + /* FIXME: features? */ + gossmap_local_addchan(mods, self, peer, &scidd->scid, NULL); + + gossmap_local_updatechan(mods, &scidd->scid, min, max, + fee_base.millisatoshis, /* Raw: gossmap */ + fee_proportional, + cltv_delta, + enabled, + scidd->dir); +} + +struct gossmap_localmods * +gossmods_from_listpeerchannels_(const tal_t *ctx, + const struct node_id *self, + const char *buf, + const jsmntok_t *toks, + void (*cb)(struct gossmap_localmods *mods, + const struct node_id *self, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf, + const jsmntok_t *chantok, + void *cbarg), + void *cbarg) +{ + struct gossmap_localmods *mods = gossmap_localmods_new(ctx); + const jsmntok_t *channels, *channel; + size_t i; + + channels = json_get_member(buf, toks, "channels"); + json_for_each_arr(i, channel, channels) { + struct short_channel_id_dir scidd; + struct short_channel_id alias; + bool enabled; + struct node_id dst; + struct amount_msat spendable, receivable, fee_base[NUM_SIDES], htlc_min[NUM_SIDES], htlc_max[NUM_SIDES]; + u32 fee_proportional[NUM_SIDES], cltv_delta[NUM_SIDES]; + const char *state, *err; + + /* scid/direction and alias may not exist. */ + scidd.scid.u64 = 0; + alias.u64 = 0; + + /* We do this to note if we have no remote update. */ + fee_proportional[REMOTE] = -1U; + + err = json_scan(tmpctx, buf, channel, + "{short_channel_id?:%," + "direction?:%," + "spendable_msat?:%," + "receivable_msat?:%," + "peer_connected:%," + "state:%," + "peer_id:%," + "updates?:{" + "local" + ":{fee_base_msat:%," + "fee_proportional_millionths:%," + "htlc_minimum_msat:%," + "htlc_maximum_msat:%," + "cltv_expiry_delta:%}," + "remote?" + ":{fee_base_msat:%," + "fee_proportional_millionths:%," + "htlc_minimum_msat:%," + "htlc_maximum_msat:%," + "cltv_expiry_delta:%}}," + "alias?:{local:%}}", + JSON_SCAN(json_to_short_channel_id, &scidd.scid), + JSON_SCAN(json_to_int, &scidd.dir), + JSON_SCAN(json_to_msat, &spendable), + JSON_SCAN(json_to_msat, &receivable), + JSON_SCAN(json_to_bool, &enabled), + JSON_SCAN_TAL(tmpctx, json_strdup, &state), + JSON_SCAN(json_to_node_id, &dst), + JSON_SCAN(json_to_msat, &fee_base[LOCAL]), + JSON_SCAN(json_to_u32, &fee_proportional[LOCAL]), + JSON_SCAN(json_to_msat, &htlc_min[LOCAL]), + JSON_SCAN(json_to_msat, &htlc_max[LOCAL]), + JSON_SCAN(json_to_u32, &cltv_delta[LOCAL]), + JSON_SCAN(json_to_msat, &fee_base[REMOTE]), + JSON_SCAN(json_to_u32, &fee_proportional[REMOTE]), + JSON_SCAN(json_to_msat, &htlc_min[REMOTE]), + JSON_SCAN(json_to_msat, &htlc_max[REMOTE]), + JSON_SCAN(json_to_u32, &cltv_delta[REMOTE]), + JSON_SCAN(json_to_short_channel_id, &alias)); + if (err) { + errx(1, "Bad listpeerchannels.channels %zu: %s", + i, err); + } + + /* Use alias if no scid. Note: if alias is set, direction is present */ + if (scidd.scid.u64 == 0 && alias.u64 != 0) + scidd.scid = alias; + + /* Unusable if no scid (yet) */ + if (scidd.scid.u64 == 0) + continue; + + /* Disable if in bad state (it's already false if not connected) */ + if (!streq(state, "CHANNELD_NORMAL") + && !streq(state, "CHANNELD_AWAITING_SPLICE")) + enabled = false; + + /* Cut htlc max to spendable. */ + if (amount_msat_less(spendable, htlc_max[LOCAL])) + htlc_max[LOCAL] = spendable; + + /* We add both directions */ + cb(mods, self, &dst, &scidd, htlc_min[LOCAL], htlc_max[LOCAL], + fee_base[LOCAL], fee_proportional[LOCAL], cltv_delta[LOCAL], + enabled, buf, channel, cbarg); + + /* If we didn't have a remote update, it's not usable yet */ + if (fee_proportional[REMOTE] == -1U) + continue; + + scidd.dir = !scidd.dir; + + /* Cut htlc max to receivable. */ + if (amount_msat_less(receivable, htlc_max[REMOTE])) + htlc_max[REMOTE] = receivable; + + cb(mods, self, &dst, &scidd, htlc_min[REMOTE], htlc_max[REMOTE], + fee_base[REMOTE], fee_proportional[REMOTE], cltv_delta[REMOTE], + enabled, buf, channel, cbarg); + } + + return mods; +} + diff --git a/common/gossmods_listpeerchannels.h b/common/gossmods_listpeerchannels.h new file mode 100644 index 000000000000..f60d125e9094 --- /dev/null +++ b/common/gossmods_listpeerchannels.h @@ -0,0 +1,74 @@ +#ifndef LIGHTNING_COMMON_GOSSMODS_LISTPEERCHANNELS_H +#define LIGHTNING_COMMON_GOSSMODS_LISTPEERCHANNELS_H +#include "config.h" +#include +#include +#include +#include + +struct node_id; + +/** + * gossmods_from_listpeerchannels: create gossmap_localmods from `listpeerchannels` + * @ctx: context to allocate return from + * @buf: the JSON buffer from listpeerchannels + * @toks: the JSON tokens + * @cb: optional per-channel callback. + * @cbarg: arg for @cb. + * + * This constructs a set of modifications you can apply to your gossmap to include + * local (esp. private) channels. You can also have an optional per-channel callback + * for special effects. + */ +struct gossmap_localmods *gossmods_from_listpeerchannels_(const tal_t *ctx, + const struct node_id *self, + const char *buf, + const jsmntok_t *toks, + void (*cb)(struct gossmap_localmods *mods, + const struct node_id *self_, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf_, + const jsmntok_t *chantok, + void *cbarg_), + void *cbarg); + +#define gossmods_from_listpeerchannels(ctx, self, buf, toks, cb, cbarg) \ + gossmods_from_listpeerchannels_((ctx), (self), (buf), (toks), \ + typesafe_cb_preargs(void, void *, (cb), (cbarg), \ + struct gossmap_localmods *, \ + const struct node_id *, \ + const struct node_id *, \ + const struct short_channel_id_dir *, \ + struct amount_msat, \ + struct amount_msat, \ + struct amount_msat, \ + u32, \ + u32, \ + bool, \ + const char *, \ + const jsmntok_t *), \ + (cbarg)) + +/* Callback which simply adds to gossmap. */ +void gossmod_add_localchan(struct gossmap_localmods *mods, + const struct node_id *self, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf UNUSED, + const jsmntok_t *chantok UNUSED, + void *cbarg UNUSED); + +#endif /* LIGHTNING_COMMON_GOSSMODS_LISTPEERCHANNELS_H */ diff --git a/plugins/topology.c b/plugins/topology.c index 296c615745ce..b7d24a9bd094 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -148,86 +149,6 @@ static struct command_result *try_route(struct command *cmd, return command_finished(cmd, js); } -static struct gossmap_localmods * -gossmods_from_listpeerchannels(const tal_t *ctx, - struct plugin *plugin, - struct gossmap *gossmap, - const char *buf, - const jsmntok_t *toks) -{ - struct gossmap_localmods *mods = gossmap_localmods_new(ctx); - const jsmntok_t *channels, *channel; - size_t i; - - channels = json_get_member(buf, toks, "channels"); - json_for_each_arr(i, channel, channels) { - struct short_channel_id scid; - int dir; - bool connected; - struct node_id dst; - struct amount_msat capacity; - const char *state, *err; - - /* scid/direction may not exist. */ - scid.u64 = 0; - capacity = AMOUNT_MSAT(0); - err = json_scan(tmpctx, buf, channel, - "{short_channel_id?:%," - "direction?:%," - "spendable_msat?:%," - "peer_connected:%," - "state:%," - "peer_id:%}", - JSON_SCAN(json_to_short_channel_id, &scid), - JSON_SCAN(json_to_int, &dir), - JSON_SCAN(json_to_msat, &capacity), - JSON_SCAN(json_to_bool, &connected), - JSON_SCAN_TAL(tmpctx, json_strdup, &state), - JSON_SCAN(json_to_node_id, &dst)); - if (err) { - plugin_err(plugin, - "Bad listpeerchannels.channels %zu: %s", - i, err); - } - - /* Unusable if no scid (yet) */ - if (scid.u64 == 0) - continue; - - /* Disable if in bad state, or disconnected */ - if (!streq(state, "CHANNELD_NORMAL") - && !streq(state, "CHANNELD_AWAITING_SPLICE")) { - goto disable; - } - - if (!connected) { - goto disable; - } - - /* FIXME: features? */ - gossmap_local_addchan(mods, &local_id, &dst, &scid, NULL); - gossmap_local_updatechan(mods, &scid, - AMOUNT_MSAT(0), capacity, - /* We don't charge ourselves fees */ - 0, 0, 0, - true, - dir); - continue; - - disable: - /* Only apply fake "disabled" if channel exists */ - if (gossmap_find_chan(gossmap, &scid)) { - gossmap_local_updatechan(mods, &scid, - AMOUNT_MSAT(0), AMOUNT_MSAT(0), - 0, 0, 0, - false, - dir); - } - } - - return mods; -} - static struct command_result * listpeerchannels_getroute_done(struct command *cmd, const char *buf, @@ -239,11 +160,12 @@ listpeerchannels_getroute_done(struct command *cmd, struct command_result *res; /* Get local knowledge */ - gossmap = get_gossmap(); - mods = gossmods_from_listpeerchannels(tmpctx, cmd->plugin, - gossmap, buf, result); + mods = gossmods_from_listpeerchannels(tmpctx, &local_id, + buf, result, + gossmod_add_localchan, NULL); /* Overlay local knowledge for dijkstra */ + gossmap = get_gossmap(); gossmap_apply_localmods(gossmap, mods); res = try_route(cmd, gossmap, info); gossmap_remove_localmods(gossmap, mods); From 53ffd08cc2137a2c27db79543ea6359daee498b1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2023 06:44:05 +1030 Subject: [PATCH 12/29] plugins/topology: temporary hack to allow per-access private gossmap suppression. We have multiple different routines here, and we want to wean them off private gossip one at a time. This converts `getroute`. Signed-off-by: Rusty Russell --- plugins/topology.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/topology.c b/plugins/topology.c index b7d24a9bd094..e1c19ddeeaf3 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -23,9 +23,14 @@ static struct node_id local_id; static struct plugin *plugin; /* We load this on demand, since we can start before gossipd. */ -static struct gossmap *get_gossmap(void) +static struct gossmap *get_gossmap(bool public_only) { - gossmap_refresh(global_gossmap, NULL); + /* Temporary hack so callers can individually exclude private gossip */ + tal_free(global_gossmap); + gossmap_public_only = public_only; + global_gossmap = gossmap_load(NULL, + GOSSIP_STORE_FILENAME, + NULL); return global_gossmap; } @@ -165,7 +170,7 @@ listpeerchannels_getroute_done(struct command *cmd, gossmod_add_localchan, NULL); /* Overlay local knowledge for dijkstra */ - gossmap = get_gossmap(); + gossmap = get_gossmap(true); gossmap_apply_localmods(gossmap, mods); res = try_route(cmd, gossmap, info); gossmap_remove_localmods(gossmap, mods); @@ -354,7 +359,7 @@ static struct command_result *listpeerchannels_done(struct command *cmd, struct node_map *connected; struct gossmap_chan *c; struct json_stream *js; - struct gossmap *gossmap = get_gossmap(); + struct gossmap *gossmap = get_gossmap(false); connected = local_connected(opts, buf, result); @@ -510,7 +515,7 @@ static struct command_result *json_listnodes(struct command *cmd, NULL)) return command_param_failed(); - gossmap = get_gossmap(); + gossmap = get_gossmap(false); js = jsonrpc_stream_success(cmd); json_array_start(js, "nodes"); if (id) { @@ -564,7 +569,7 @@ static struct command_result *json_listincoming(struct command *cmd, if (!param(cmd, buffer, params, NULL)) return command_param_failed(); - gossmap = get_gossmap(); + gossmap = get_gossmap(false); js = jsonrpc_stream_success(cmd); json_array_start(js, "incoming"); From 4a396e8539f4ef2a890e6ebd7c0709bc1b0e7ada Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:04:32 +1030 Subject: [PATCH 13/29] plugins/fetchinvoice: use gossmods_from_listpeerchannels instead of private gossip_store records. [ Includes use-after-free fix from Alex Myers ] Signed-off-by: Rusty Russell --- plugins/Makefile | 2 +- plugins/fetchinvoice.c | 115 +++++++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/plugins/Makefile b/plugins/Makefile index edc29a0f74e8..ed796d20d5bc 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -211,7 +211,7 @@ plugins/spenderp: bitcoin/block.o bitcoin/preimage.o bitcoin/psbt.o common/psbt_ plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/addr.o common/bolt12.o common/bolt12_merkle.o common/bolt11_json.o common/iso4217.o $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o common/blindedpath.o common/invoice_path_id.o common/blinding.o common/hmac.o $(JSMN_OBJS) -plugins/fetchinvoice: $(PLUGIN_FETCHINVOICE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/bolt12.o common/bolt12_merkle.o common/iso4217.o $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o $(JSMN_OBJS) common/gossmap.o common/fp16.o common/dijkstra.o common/route.o common/blindedpath.o common/hmac.o common/blinding.o +plugins/fetchinvoice: $(PLUGIN_FETCHINVOICE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/bolt12.o common/bolt12_merkle.o common/iso4217.o $(WIRE_OBJS) $(WIRE_BOLT12_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o $(JSMN_OBJS) common/gossmap.o common/fp16.o common/dijkstra.o common/route.o common/blindedpath.o common/hmac.o common/blinding.o common/gossmods_listpeerchannels.o plugins/funder: bitcoin/psbt.o common/psbt_open.o $(PLUGIN_FUNDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index 61e848bf875a..17bb8780c4b6 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -452,6 +453,8 @@ static bool can_carry_onionmsg(const struct gossmap *map, static struct pubkey *path_to_node(const tal_t *ctx, struct plugin *plugin, + const char *buf, + const jsmntok_t *listpeerchannels, const struct pubkey *node_id) { struct route_hop *r; @@ -460,25 +463,32 @@ static struct pubkey *path_to_node(const tal_t *ctx, const struct gossmap_node *dst; struct node_id dstid, local_nodeid; struct pubkey *nodes; - struct gossmap *gossmap = get_gossmap(plugin); + struct gossmap *gossmap; + struct gossmap_localmods *mods; + node_id_from_pubkey(&local_nodeid, &local_id); node_id_from_pubkey(&dstid, node_id); + + mods = gossmods_from_listpeerchannels(tmpctx, &local_nodeid, buf, listpeerchannels, + gossmod_add_localchan, NULL); + + gossmap = get_gossmap(plugin); + gossmap_apply_localmods(gossmap, mods); dst = gossmap_find_node(gossmap, &dstid); if (!dst) - return NULL; + goto fail; /* If we don't exist in gossip, routing can't happen. */ - node_id_from_pubkey(&local_nodeid, &local_id); src = gossmap_find_node(gossmap, &local_nodeid); if (!src) - return NULL; + goto fail; dij = dijkstra(tmpctx, gossmap, dst, AMOUNT_MSAT(0), 0, can_carry_onionmsg, route_score_shorter, NULL); r = route_from_dijkstra(tmpctx, gossmap, dij, src, AMOUNT_MSAT(0), 0); if (!r) - return NULL; + goto fail; nodes = tal_arr(ctx, struct pubkey, tal_count(r) + 1); nodes[0] = local_id; @@ -489,7 +499,13 @@ static struct pubkey *path_to_node(const tal_t *ctx, &r[i].node_id)); } } + + gossmap_remove_localmods(gossmap, mods); return nodes; + +fail: + gossmap_remove_localmods(gossmap, mods); + return NULL; } /* Marshal arguments for sending onion messages */ @@ -760,6 +776,20 @@ connect_direct(struct command *cmd, return send_outreq(cmd->plugin, req); } +static struct command_result *fetchinvoice_listpeerchannels_done(struct command *cmd, + const char *buf, + const jsmntok_t *result, + struct sent *sent) +{ + sent->path = path_to_node(sent, cmd->plugin, buf, result, + sent->invreq->offer_node_id); + if (!sent->path) + return connect_direct(cmd, sent->invreq->offer_node_id, + sendinvreq_after_connect, sent); + + return sendinvreq_after_connect(cmd, NULL, NULL, sent); +} + static struct command_result *invreq_done(struct command *cmd, const char *buf, const jsmntok_t *result, @@ -767,6 +797,7 @@ static struct command_result *invreq_done(struct command *cmd, { const jsmntok_t *t; char *fail; + struct out_req *req; /* Get invoice request */ t = json_get_member(buf, result, "bolt12"); @@ -859,13 +890,11 @@ static struct command_result *invreq_done(struct command *cmd, } } - sent->path = path_to_node(sent, cmd->plugin, - sent->invreq->offer_node_id); - if (!sent->path) - return connect_direct(cmd, sent->invreq->offer_node_id, - sendinvreq_after_connect, sent); - - return sendinvreq_after_connect(cmd, NULL, NULL, sent); + req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels", + fetchinvoice_listpeerchannels_done, + &forward_error, + sent); + return send_outreq(cmd->plugin, req); } /* Fetches an invoice for this offer, and makes sure it corresponds. */ @@ -1124,12 +1153,28 @@ sendinvoice_after_connect(struct command *cmd, return send_message(cmd, sent, payload, prepare_inv_timeout); } +static struct command_result *sendinvoice_listpeerchannels_done(struct command *cmd, + const char *buf, + const jsmntok_t *result, + struct sent *sent) +{ + + sent->path = path_to_node(sent, cmd->plugin, buf, result, + sent->invreq->invreq_payer_id); + if (!sent->path) + return connect_direct(cmd, sent->invreq->invreq_payer_id, + sendinvoice_after_connect, sent); + + return sendinvoice_after_connect(cmd, NULL, NULL, sent); +} + static struct command_result *createinvoice_done(struct command *cmd, const char *buf, const jsmntok_t *result, struct sent *sent) { const jsmntok_t *invtok = json_get_member(buf, result, "bolt12"); + struct out_req *req; char *fail; /* Replace invoice with signed one */ @@ -1161,13 +1206,11 @@ static struct command_result *createinvoice_done(struct command *cmd, "FIXME: support blinded paths!"); } - sent->path = path_to_node(sent, cmd->plugin, - sent->invreq->invreq_payer_id); - if (!sent->path) - return connect_direct(cmd, sent->invreq->invreq_payer_id, - sendinvoice_after_connect, sent); - - return sendinvoice_after_connect(cmd, NULL, NULL, sent); + req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels", + sendinvoice_listpeerchannels_done, + &forward_error, + sent); + return send_outreq(cmd->plugin, req); } static struct command_result *sign_invoice(struct command *cmd, @@ -1429,6 +1472,23 @@ static struct command_result *param_raw_invreq(struct command *cmd, return NULL; } +static struct command_result *rawrequest_listpeerchannels_done(struct command *cmd, + const char *buf, + const jsmntok_t *result, + struct sent *sent) +{ + struct pubkey node_id; + /* Hack to store node_id from cmd */ + node_id = *sent->path; + sent->path = path_to_node(sent, cmd->plugin, buf, result, &node_id); + if (!sent->path) { + return connect_direct(cmd, &node_id, + sendinvreq_after_connect, sent); + } + + return sendinvreq_after_connect(cmd, NULL, NULL, sent); +} + static struct command_result *json_dev_rawrequest(struct command *cmd, const char *buffer, const jsmntok_t *params) @@ -1436,6 +1496,7 @@ static struct command_result *json_dev_rawrequest(struct command *cmd, struct sent *sent = tal(cmd, struct sent); u32 *timeout; struct pubkey *node_id; + struct out_req *req; if (!param(cmd, buffer, params, p_req("invreq", param_raw_invreq, &sent->invreq), @@ -1449,13 +1510,13 @@ static struct command_result *json_dev_rawrequest(struct command *cmd, sent->cmd = cmd; sent->offer = NULL; - sent->path = path_to_node(sent, cmd->plugin, node_id); - if (!sent->path) { - return connect_direct(cmd, node_id, - sendinvreq_after_connect, sent); - } - - return sendinvreq_after_connect(cmd, NULL, NULL, sent); + /* We temporarily abuse ->path to store nodeid! */ + sent->path = node_id; + req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels", + rawrequest_listpeerchannels_done, + &forward_error, + sent); + return send_outreq(cmd->plugin, req); } static const struct plugin_command commands[] = { @@ -1516,6 +1577,8 @@ static const struct plugin_hook hooks[] = { int main(int argc, char *argv[]) { setup_locale(); + /* We are migrated, ready for public-only gossmap! */ + gossmap_public_only = true; plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands), /* No notifications */ From fcc1010056588ae730bc8e843ad82c03b8dec4c2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:01 +1030 Subject: [PATCH 14/29] libplugin-pay: make sure get_gossmap calls are balanced by put_gossmap. This will become important when we apply localmods to the gossmap at these points. Signed-off-by: Rusty Russell --- plugins/libplugin-pay.c | 32 ++++++++++++++++++++++++++----- plugins/libplugin-pay.h | 5 +++-- plugins/pay.c | 1 + plugins/test/run-route-overlong.c | 3 +++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 68c7ea05e73f..effee07f1466 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include static struct gossmap *global_gossmap; +static bool got_gossmap; static void init_gossmap(struct plugin *plugin) { @@ -33,15 +35,29 @@ static void init_gossmap(struct plugin *plugin) num_channel_updates_rejected); } -struct gossmap *get_gossmap(struct plugin *plugin) +static struct gossmap *get_gossmap(struct payment *payment) { + assert(!got_gossmap); if (!global_gossmap) - init_gossmap(plugin); + init_gossmap(payment->plugin); else gossmap_refresh(global_gossmap, NULL); + got_gossmap = true; return global_gossmap; } +static void put_gossmap(struct payment *payment) +{ + assert(got_gossmap); + got_gossmap = false; +} + +int libplugin_pay_poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + assert(!got_gossmap); + return daemon_poll(fds, nfds, timeout); +} + struct payment *payment_new(tal_t *ctx, struct command *cmd, struct payment *parent, struct payment_modifier **mods) @@ -832,10 +848,11 @@ static struct command_result *payment_getroute(struct payment *p) * free an eventual stale route. */ p->route = tal_free(p->route); - gossmap = get_gossmap(p->plugin); + gossmap = get_gossmap(p); dst = gossmap_find_node(gossmap, p->getroute->destination); if (!dst) { + put_gossmap(p); payment_fail( p, "Unknown destination %s", type_to_string(tmpctx, struct node_id, @@ -848,6 +865,7 @@ static struct command_result *payment_getroute(struct payment *p) /* If we don't exist in gossip, routing can't happen. */ src = gossmap_find_node(gossmap, p->local_id); if (!src) { + put_gossmap(p); payment_fail(p, "We don't have any channels"); /* Let payment_finished_ handle this, so we mark it as pending */ @@ -857,6 +875,8 @@ static struct command_result *payment_getroute(struct payment *p) p->route = route(p, gossmap, src, dst, p->getroute->amount, p->getroute->cltv, p->getroute->riskfactorppm / 1000000.0, p->getroute->max_hops, p, &errstr); + put_gossmap(p); + if (!p->route) { payment_fail(p, "%s", errstr); /* Let payment_finished_ handle this, so we mark it as pending */ @@ -2751,7 +2771,7 @@ static void routehint_pre_getroute(struct routehints_data *d, struct payment *p) static void routehint_check_reachable(struct payment *p) { const struct gossmap_node *dst, *src; - struct gossmap *gossmap = get_gossmap(p->plugin); + struct gossmap *gossmap = get_gossmap(p); const struct dijkstra *dij; struct route_hop *r; struct payment *root = payment_root(p); @@ -2811,6 +2831,7 @@ static void routehint_check_reachable(struct payment *p) } routehint_pre_getroute(d, p); + put_gossmap(p); paymod_log(p, LOG_DBG, "The destination is%s directly reachable %s attempts " @@ -2835,7 +2856,7 @@ static void routehint_step_cb(struct routehints_data *d, struct payment *p) * beginning, and every other payment will filter out the * exluded ones on the fly. */ if (p->parent == NULL) { - map = get_gossmap(p->plugin); + map = get_gossmap(p); d->routehints = filter_routehints( map, p, d, p->local_id, p->routes); /* filter_routehints modifies the array, but @@ -2858,6 +2879,7 @@ static void routehint_step_cb(struct routehints_data *d, struct payment *p) * in paymod, paymod should use (and mutate) the * p->routes array, and */ + put_gossmap(p); p->routes = d->routehints; paymod_log(p, LOG_DBG, diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index c31f7b2164fe..32eedcd69cd7 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -2,6 +2,7 @@ #define LIGHTNING_PLUGINS_LIBPLUGIN_PAY_H #include "config.h" +#include #include #include #include @@ -488,7 +489,7 @@ void json_add_payment_success(struct json_stream *js, const struct preimage *preimage, const struct payment_tree_result *result); -/* For special effects, like inspecting your own routes. */ -struct gossmap *get_gossmap(struct plugin *plugin); +/* Overriding io_poll for extra checks. */ +int libplugin_pay_poll(struct pollfd *fds, nfds_t nfds, int timeout); #endif /* LIGHTNING_PLUGINS_LIBPLUGIN_PAY_H */ diff --git a/plugins/pay.c b/plugins/pay.c index 3bd1a6cdaa8c..153d86a32ba7 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1307,4 +1307,5 @@ int main(int argc, char *argv[]) "Disable multi-part payments.", flag_option, &disablempp), NULL); + io_poll_override(libplugin_pay_poll); } diff --git a/plugins/test/run-route-overlong.c b/plugins/test/run-route-overlong.c index f78f0fa561ad..221fff0a539d 100644 --- a/plugins/test/run-route-overlong.c +++ b/plugins/test/run-route-overlong.c @@ -21,6 +21,9 @@ struct command_result *command_finished(struct command *cmd UNNEEDED, struct jso /* Generated stub for command_still_pending */ struct command_result *command_still_pending(struct command *cmd UNNEEDED) { fprintf(stderr, "command_still_pending called!\n"); abort(); } +/* Generated stub for daemon_poll */ +int daemon_poll(struct pollfd *fds UNNEEDED, nfds_t nfds UNNEEDED, int timeout UNNEEDED) +{ fprintf(stderr, "daemon_poll called!\n"); abort(); } /* Generated stub for feature_offered */ bool feature_offered(const u8 *features UNNEEDED, size_t f UNNEEDED) { fprintf(stderr, "feature_offered called!\n"); abort(); } From 2d0673838085dd6fcd56aaf2d06201d2e136b098 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:42 +1030 Subject: [PATCH 15/29] plugins/pay: use gossmods_from_listpeerchannels instead of private gossip_store records. Signed-off-by: Rusty Russell --- plugins/Makefile | 4 +-- plugins/keysend.c | 3 ++ plugins/libplugin-pay.c | 49 +++++++++++++++++++++++++++++-- plugins/libplugin-pay.h | 3 ++ plugins/pay.c | 2 ++ plugins/test/run-route-overlong.c | 35 ++++++++++++++++++++++ 6 files changed, 92 insertions(+), 4 deletions(-) diff --git a/plugins/Makefile b/plugins/Makefile index ed796d20d5bc..0e831f13356d 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -188,7 +188,7 @@ ALL_PROGRAMS += $(C_PLUGINS) # Make all plugins depend on all plugin headers, for simplicity. $(PLUGIN_ALL_OBJS): $(PLUGIN_ALL_HEADER) -plugins/pay: $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12_wiregen.o bitcoin/block.o common/blindedpay.o common/blindedpath.o common/hmac.o common/blinding.o common/onion_encode.o +plugins/pay: $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12_wiregen.o bitcoin/block.o common/blindedpay.o common/blindedpath.o common/hmac.o common/blinding.o common/onion_encode.o common/gossmods_listpeerchannels.o plugins/autoclean: $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) @@ -204,7 +204,7 @@ plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_O plugins/bcli: $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) -plugins/keysend: wire/tlvstream.o wire/onion_wiregen.o $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o common/blindedpay.o common/blindedpath.o common/hmac.o common/blinding.o common/onion_encode.o +plugins/keysend: wire/tlvstream.o wire/onion_wiregen.o $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o common/blindedpay.o common/blindedpath.o common/hmac.o common/blinding.o common/onion_encode.o common/gossmods_listpeerchannels.o $(PLUGIN_KEYSEND_OBJS): $(PLUGIN_PAY_LIB_HEADER) plugins/spenderp: bitcoin/block.o bitcoin/preimage.o bitcoin/psbt.o common/psbt_open.o wire/peer${EXP}_wiregen.o $(PLUGIN_SPENDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) diff --git a/plugins/keysend.c b/plugins/keysend.c index c74eb3ad290a..17e39fd026c7 100644 --- a/plugins/keysend.c +++ b/plugins/keysend.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -610,6 +611,8 @@ int main(int argc, char *argv[]) features->bits[i] = tal_arr(features, u8, 0); set_feature_bit(&features->bits[NODE_ANNOUNCE_FEATURE], KEYSEND_FEATUREBIT); + /* We are migrated, ready for public-only gossmap! */ + gossmap_public_only = true; plugin_main(argv, init, PLUGIN_STATIC, true, features, commands, ARRAY_SIZE(commands), NULL, 0, hooks, ARRAY_SIZE(hooks), notification_topics, ARRAY_SIZE(notification_topics), NULL); diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index effee07f1466..3bd5230b5fc9 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -43,13 +44,17 @@ static struct gossmap *get_gossmap(struct payment *payment) else gossmap_refresh(global_gossmap, NULL); got_gossmap = true; + assert(payment->mods); + gossmap_apply_localmods(global_gossmap, payment->mods); return global_gossmap; } + static void put_gossmap(struct payment *payment) { assert(got_gossmap); got_gossmap = false; + gossmap_remove_localmods(global_gossmap, payment->mods); } int libplugin_pay_poll(struct pollfd *fds, nfds_t nfds, int timeout) @@ -112,6 +117,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd, p->groupid = parent->groupid; p->invstring = parent->invstring; p->description = parent->description; + p->mods = parent->mods; } else { assert(cmd != NULL); p->partid = 0; @@ -125,6 +131,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd, p->local_id = NULL; p->local_invreq_id = NULL; p->groupid = 0; + p->mods = NULL; } /* Initialize all modifier data so we can point to the fields when @@ -331,6 +338,7 @@ void payment_start_at_blockheight(struct payment *p, u32 blockheight) json_add_u32(req->js, "blockheight", 0); send_outreq(p->plugin, req); } + void payment_start(struct payment *p) { payment_start_at_blockheight(p, INVALID_BLOCKHEIGHT); @@ -930,6 +938,33 @@ static struct command_result *payment_getroute(struct payment *p) return command_still_pending(p->cmd); } +static struct command_result * +payment_listpeerchannels_success(struct command *cmd, + const char *buffer, + const jsmntok_t *toks, + struct payment *p) +{ + p->mods = gossmods_from_listpeerchannels(p, p->local_id, + buffer, toks, + gossmod_add_localchan, + NULL); + return payment_getroute(p); +} + +static struct command_result *payment_getlocalmods(struct payment *p) +{ + struct out_req *req; + + /* Don't call listpeerchannels if we already have mods */ + if (p->mods) + return payment_getroute(p); + + req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", + &payment_listpeerchannels_success, + &payment_rpc_failure, p); + return send_outreq(p->plugin, req); +} + static struct payment_result *tal_sendpay_result_from_json(const tal_t *ctx, const char *buffer, const jsmntok_t *toks) @@ -2168,7 +2203,7 @@ void payment_continue(struct payment *p) switch (p->step) { case PAYMENT_STEP_INITIALIZED: case PAYMENT_STEP_RETRY_GETROUTE: - payment_getroute(p); + payment_getlocalmods(p); return; case PAYMENT_STEP_GOT_ROUTE: @@ -2827,6 +2862,7 @@ static void routehint_check_reachable(struct payment *p) "Destination %s is not reachable directly and " "all routehints were unusable.", type_to_string(tmpctx, struct node_id, p->destination)); + put_gossmap(p); return; } @@ -3309,6 +3345,9 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd, for (size_t i=0; iid, p->destination)) + continue; + if (!chan->connected) continue; @@ -3329,6 +3368,13 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd, d->chan->dir = chan->direction; } + /* We may still need local mods! */ + if (!p->mods) + p->mods = gossmods_from_listpeerchannels(p, p->local_id, + buffer, toks, + gossmod_add_localchan, + NULL); + direct_pay_override(p); return command_still_pending(cmd); @@ -3348,7 +3394,6 @@ static void direct_pay_cb(struct direct_pay_data *d, struct payment *p) direct_pay_listpeerchannels, direct_pay_listpeerchannels, p); - json_add_node_id(req->js, "id", p->destination); send_outreq(p->plugin, req); } diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 32eedcd69cd7..77783c6274b8 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -237,6 +237,9 @@ struct payment { struct short_channel_id *exclusions; + /* Local modifications, from listpeerchannels */ + struct gossmap_localmods *mods; + /* Tree structure of payments and subpayments. */ struct payment *parent, **children; diff --git a/plugins/pay.c b/plugins/pay.c index 153d86a32ba7..d162e70bf512 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1300,6 +1300,8 @@ static const char *notification_topics[] = { int main(int argc, char *argv[]) { setup_locale(); + /* We are migrated, ready for public-only gossmap! */ + gossmap_public_only = true; plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands), NULL, 0, NULL, 0, notification_topics, ARRAY_SIZE(notification_topics), diff --git a/plugins/test/run-route-overlong.c b/plugins/test/run-route-overlong.c index 221fff0a539d..881f20ba6be0 100644 --- a/plugins/test/run-route-overlong.c +++ b/plugins/test/run-route-overlong.c @@ -34,6 +34,41 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "fromwire_channel_id called!\n"); abort(); } +/* Generated stub for gossmod_add_localchan */ +void gossmod_add_localchan(struct gossmap_localmods *mods UNNEEDED, + const struct node_id *self UNNEEDED, + const struct node_id *peer UNNEEDED, + const struct short_channel_id_dir *scidd UNNEEDED, + struct amount_msat min UNNEEDED, + struct amount_msat max UNNEEDED, + struct amount_msat fee_base UNNEEDED, + u32 fee_proportional UNNEEDED, + u32 cltv_delta UNNEEDED, + bool enabled UNNEEDED, + const char *buf UNUSED UNNEEDED, + const jsmntok_t *chantok UNUSED UNNEEDED, + void *cbarg UNUSED UNNEEDED) +{ fprintf(stderr, "gossmod_add_localchan called!\n"); abort(); } +/* Generated stub for gossmods_from_listpeerchannels_ */ +struct gossmap_localmods *gossmods_from_listpeerchannels_(const tal_t *ctx UNNEEDED, + const struct node_id *self UNNEEDED, + const char *buf UNNEEDED, + const jsmntok_t *toks UNNEEDED, + void (*cb)(struct gossmap_localmods *mods UNNEEDED, + const struct node_id *self_ UNNEEDED, + const struct node_id *peer UNNEEDED, + const struct short_channel_id_dir *scidd UNNEEDED, + struct amount_msat min UNNEEDED, + struct amount_msat max UNNEEDED, + struct amount_msat fee_base UNNEEDED, + u32 fee_proportional UNNEEDED, + u32 cltv_delta UNNEEDED, + bool enabled UNNEEDED, + const char *buf_ UNNEEDED, + const jsmntok_t *chantok UNNEEDED, + void *cbarg_) UNNEEDED, + void *cbarg UNNEEDED) +{ fprintf(stderr, "gossmods_from_listpeerchannels_ called!\n"); abort(); } /* Generated stub for json_add_amount_msat */ void json_add_amount_msat(struct json_stream *result UNNEEDED, const char *msatfieldname UNNEEDED, From dd3b59432e81331b0367d2d6e3b1d4fc919f3b06 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 16/29] common: add tests that json_scan can omit an entire object member. We can, but I had a typo and thought we couldn't! Signed-off-by: Rusty Russell --- common/test/run-json_scan.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/common/test/run-json_scan.c b/common/test/run-json_scan.c index 56614e086fe4..46ccee8e9f99 100644 --- a/common/test/run-json_scan.c +++ b/common/test/run-json_scan.c @@ -219,5 +219,30 @@ int main(int argc, char *argv[]) JSON_SCAN(json_to_number, &u32val))); assert(u32val == 4); + /* You can have optional whole objects */ + u32val = -1U; + /* Missing */ + assert(!json_scan(tmpctx, buf, toks, "{5?:{deeper:%}}", + JSON_SCAN(json_to_number, &u32val))); + assert(u32val == -1U); + /* Missing */ + assert(!json_scan(tmpctx, buf, toks, "{3?:{not?:%}}", + JSON_SCAN(json_to_number, &u32val))); + assert(u32val == -1U); + /* Present */ + assert(!json_scan(tmpctx, buf, toks, "{3?:{three:{deeper:%}}}", + JSON_SCAN(json_to_number, &u32val))); + assert(u32val == 17); + /* Missing inside optional */ + err = json_scan(tmpctx, buf, toks, "{3?:{not:%}", + JSON_SCAN(json_to_number, &u32val)); + assert(streq(err, "Parsing '{3?:{not:': object does not have member not")); + + + buf = tal_strdup(tmpctx, "{\"1\":\"one\", \"2\":\"two\", \"3\":{\"three\": {\"deeper\": 17}}, \"arr\": [{\"1\": \"arrone\"}, 2, [3, 4]]}"); + toks = json_parse_simple(tmpctx, buf, strlen(buf)); + assert(toks); + assert(toks->size == 4); + common_shutdown(); } From 88b41fe4c8fce2f6d99827ba43d4755776c70fbf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 17/29] plugins/renepay: add localmods later. We will get localmods from gossmods_from_listpeerchannels in the next commit, so we need to save routehints to add to that later. Signed-off-by: Rusty Russell --- plugins/renepay/pay.c | 47 ++++++++++++++++++++------------------- plugins/renepay/payment.c | 47 +++++++++++++++++++++++---------------- plugins/renepay/payment.h | 4 ++++ 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/plugins/renepay/pay.c b/plugins/renepay/pay.c index aee7ab437bc8..bf81e4c97a1b 100644 --- a/plugins/renepay/pay.c +++ b/plugins/renepay/pay.c @@ -493,6 +493,10 @@ static struct command_result *listpeerchannels_done( // any gossmap local chan. The same way there aren't fees to pay for my // local channels. + // TODO(eduardo): are there route hints for B12? + // Add any extra hidden channel revealed by the routehints to the uncertainty network. + uncertainty_network_add_routehints(pay_plugin->chan_extra_map, payment->routes, payment); + /* From now on, we keep a record of the payment, so persist it beyond this cmd. */ tal_steal(pay_plugin->plugin, payment); /* When we terminate cmd for any reason, clear it from payment so we don't do it again. */ @@ -941,25 +945,26 @@ static struct command_result *json_pay(struct command *cmd, * actually started, it persists beyond the command, so we * tal_steal. */ struct payment *payment = payment_new(cmd, - cmd, - take(invstr), - take(label), - take(description), - take(local_offer_id), - take(payment_secret), - take(payment_metadata), - &destination, - &payment_hash, - *msat, - *maxfee, - *maxdelay, - *retryfor, - final_cltv, - *base_fee_penalty, - *prob_cost_factor, - *riskfactor_millionths, - *min_prob_success_millionths, - use_shadow); + cmd, + take(invstr), + take(label), + take(description), + take(local_offer_id), + take(payment_secret), + take(payment_metadata), + take(routes), + &destination, + &payment_hash, + *msat, + *maxfee, + *maxdelay, + *retryfor, + final_cltv, + *base_fee_penalty, + *prob_cost_factor, + *riskfactor_millionths, + *min_prob_success_millionths, + use_shadow); /* We immediately add this payment to the payment list. */ list_add_tail(&pay_plugin->payments, &payment->list); @@ -1006,10 +1011,6 @@ static struct command_result *json_pay(struct command *cmd, fraction); pay_plugin->last_time = now_sec; - // TODO(eduardo): are there route hints for B12? - // Add any extra hidden channel revealed by the routehints to the uncertainty network. - uncertainty_network_add_routehints(pay_plugin->chan_extra_map, routes, payment); - if(!uncertainty_network_check_invariants(pay_plugin->chan_extra_map)) plugin_log(pay_plugin->plugin, LOG_BROKEN, diff --git a/plugins/renepay/payment.c b/plugins/renepay/payment.c index 6535f09b7b50..38730a774956 100644 --- a/plugins/renepay/payment.c +++ b/plugins/renepay/payment.c @@ -10,25 +10,26 @@ struct payment *payment_new(const tal_t *ctx, struct command *cmd, - const char *invstr TAKES, - const char *label TAKES, - const char *description TAKES, - const struct sha256 *local_offer_id TAKES, - const struct secret *payment_secret TAKES, - const u8 *payment_metadata TAKES, - const struct node_id *destination, - const struct sha256 *payment_hash, - struct amount_msat amount, - struct amount_msat maxfee, - unsigned int maxdelay, - u64 retryfor, - u16 final_cltv, - /* Tweakable in --developer mode */ - u64 base_fee_penalty, - u64 prob_cost_factor, - u64 riskfactor_millionths, - u64 min_prob_success_millionths, - bool use_shadow) + const char *invstr TAKES, + const char *label TAKES, + const char *description TAKES, + const struct sha256 *local_offer_id TAKES, + const struct secret *payment_secret TAKES, + const u8 *payment_metadata TAKES, + const struct route_info **routes TAKES, + const struct node_id *destination, + const struct sha256 *payment_hash, + struct amount_msat amount, + struct amount_msat maxfee, + unsigned int maxdelay, + u64 retryfor, + u16 final_cltv, + /* Tweakable in --developer mode */ + u64 base_fee_penalty, + u64 prob_cost_factor, + u64 riskfactor_millionths, + u64 min_prob_success_millionths, + bool use_shadow) { struct payment *p = tal(ctx,struct payment); p->cmd = cmd; @@ -45,6 +46,14 @@ struct payment *payment_new(const tal_t *ctx, if (!amount_msat_add(&p->maxspend, amount, maxfee)) p->maxspend = AMOUNT_MSAT(UINT64_MAX); + if (taken(routes)) + p->routes = tal_steal(p, routes); + else { + /* Deep copy */ + p->routes = tal_dup_talarr(p, const struct route_info *, routes); + for (size_t i = 0; i < tal_count(p->routes); i++) + p->routes[i] = tal_steal(p->routes, p->routes[i]); + } p->maxdelay = maxdelay; p->start_time = time_now(); p->stop_time = timeabs_add(p->start_time, time_from_sec(retryfor)); diff --git a/plugins/renepay/payment.h b/plugins/renepay/payment.h index a4e98b259ea9..9f1bd07178a5 100644 --- a/plugins/renepay/payment.h +++ b/plugins/renepay/payment.h @@ -47,6 +47,9 @@ struct payment { /* invstring (bolt11 or bolt12) */ const char *invstr; + /* Extracted routehints */ + const struct route_info **routes; + /* How much, what, where */ struct amount_msat amount; struct node_id destination; @@ -123,6 +126,7 @@ struct payment *payment_new(const tal_t *ctx, const struct sha256 *local_offer_id TAKES, const struct secret *payment_secret TAKES, const u8 *payment_metadata TAKES, + const struct route_info **routes TAKES, const struct node_id *destination, const struct sha256 *payment_hash, struct amount_msat amount, From ccec35dae3587c0bca8ff49f5050f3b23ca2af5b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 18/29] plugins/renepay: use gossmods_from_listpeerchannels instead of private gossip_store records. Signed-off-by: Rusty Russell --- plugins/renepay/Makefile | 2 +- plugins/renepay/pay.c | 42 ++++++-- plugins/renepay/payment.c | 2 +- plugins/renepay/uncertainty_network.c | 148 ++++++-------------------- plugins/renepay/uncertainty_network.h | 13 +-- 5 files changed, 73 insertions(+), 134 deletions(-) diff --git a/plugins/renepay/Makefile b/plugins/renepay/Makefile index 2fea75e77851..9abbb3dc7b06 100644 --- a/plugins/renepay/Makefile +++ b/plugins/renepay/Makefile @@ -11,6 +11,6 @@ ALL_C_HEADERS += $(PLUGIN_RENEPAY_HDRS) # Make all plugins depend on all plugin headers, for simplicity. $(PLUGIN_RENEPAY_OBJS): $(PLUGIN_RENEPAY_HDRS) -plugins/cln-renepay: $(PLUGIN_RENEPAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) bitcoin/chainparams.o common/gossmap.o common/fp16.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12$(EXP)_wiregen.o +plugins/cln-renepay: $(PLUGIN_RENEPAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) bitcoin/chainparams.o common/gossmap.o common/gossmods_listpeerchannels.o common/fp16.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12$(EXP)_wiregen.o include plugins/renepay/test/Makefile diff --git a/plugins/renepay/pay.c b/plugins/renepay/pay.c index bf81e4c97a1b..3383be8a318d 100644 --- a/plugins/renepay/pay.c +++ b/plugins/renepay/pay.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -469,6 +470,30 @@ static void destroy_cmd_payment_ptr(struct command *cmd, payment->cmd = NULL; } +static void gossmod_cb(struct gossmap_localmods *mods, + const struct node_id *self, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf, + const jsmntok_t *chantok, + struct payment *payment) +{ + /* Add to gossmap like normal */ + gossmod_add_localchan(mods, self, peer, scidd, min, max, + fee_base, fee_proportional, cltv_delta, enabled, buf, chantok, NULL); + + /* Also update uncertainty map */ + uncertainty_network_update_from_listpeerchannels(payment, scidd, max, enabled, + buf, chantok, + pay_plugin->chan_extra_map); +} + static struct command_result *listpeerchannels_done( struct command *cmd, const char *buf, @@ -479,16 +504,10 @@ static struct command_result *listpeerchannels_done( const char *errmsg; enum jsonrpc_errcode ecode; - if (!uncertainty_network_update_from_listpeerchannels( - pay_plugin->chan_extra_map, - pay_plugin->my_id, - payment, - buf, - result)) - return command_fail(cmd, LIGHTNINGD, - "listpeerchannels malformed: %.*s", - json_tok_full_len(result), - json_tok_full(buf, result)); + payment->local_gossmods = gossmods_from_listpeerchannels(payment, &pay_plugin->my_id, + buf, result, + gossmod_cb, payment); + // TODO(eduardo): check that there won't be a prob. cost associated with // any gossmap local chan. The same way there aren't fees to pay for my // local channels. @@ -1320,6 +1339,9 @@ int main(int argc, char *argv[]) pay_plugin = tal(NULL, struct pay_plugin); pay_plugin->debug_mcf = pay_plugin->debug_payflow = false; + /* We are migrated, ready for public-only gossmap! */ + gossmap_public_only = true; + plugin_main( argv, init, diff --git a/plugins/renepay/payment.c b/plugins/renepay/payment.c index 38730a774956..6f610468019e 100644 --- a/plugins/renepay/payment.c +++ b/plugins/renepay/payment.c @@ -76,7 +76,7 @@ struct payment *payment_new(const tal_t *ctx, p->use_shadow = use_shadow; p->groupid=1; - p->local_gossmods = gossmap_localmods_new(p); + p->local_gossmods = NULL; p->disabled_scids = tal_arr(p,struct short_channel_id,0); p->next_partid=1; p->progress_deadline = NULL; diff --git a/plugins/renepay/uncertainty_network.c b/plugins/renepay/uncertainty_network.c index e335daaa752e..12f3dae6d5b5 100644 --- a/plugins/renepay/uncertainty_network.c +++ b/plugins/renepay/uncertainty_network.c @@ -1,5 +1,6 @@ #include "config.h" #include +#include #include #include @@ -216,129 +217,44 @@ void uncertainty_network_channel_can_send( } } -/* listpeerchannels gives us the certainty on local channels' capacity. Of course, - * this is racy and transient, but better than nothing! */ -bool uncertainty_network_update_from_listpeerchannels( - struct chan_extra_map * chan_extra_map, - struct node_id my_id, - struct payment *p, - const char *buf, - const jsmntok_t *toks) +void uncertainty_network_update_from_listpeerchannels(struct payment *p, + const struct short_channel_id_dir *scidd, + struct amount_msat max, + bool enabled, + const char *buf, + const jsmntok_t *chantok, + struct chan_extra_map *chan_extra_map) { - const jsmntok_t *channels, *channel; - size_t i; - - if (json_get_member(buf, toks, "error")) - goto malformed; - - channels = json_get_member(buf, toks, "channels"); - if (!channels) - goto malformed; - - json_for_each_arr(i, channel, channels) { - struct short_channel_id_dir scidd; - const jsmntok_t *scidtok = json_get_member(buf, channel, "short_channel_id"); - /* If channel is still opening, this won't be there. - * Also it won't be in the gossmap, so there is - * no need to mark it as disabled. */ - if (!scidtok) - continue; - if (!json_to_short_channel_id(buf, scidtok, &scidd.scid)) - goto malformed; - - bool connected; - if(!json_to_bool(buf, - json_get_member(buf,channel,"peer_connected"), - &connected)) - goto malformed; - - if (!connected) { - payment_disable_chan(p, scidd.scid, LOG_DBG, - "peer disconnected"); - continue; - } - - const jsmntok_t *spendabletok, *dirtok,*statetok, *totaltok, - *peeridtok; - struct amount_msat spendable,capacity; - - const struct node_id src=my_id; - struct node_id dst; + struct chan_extra *ce; - spendabletok = json_get_member(buf, channel, "spendable_msat"); - dirtok = json_get_member(buf, channel, "direction"); - statetok = json_get_member(buf, channel, "state"); - totaltok = json_get_member(buf, channel, "total_msat"); - peeridtok = json_get_member(buf,channel,"peer_id"); - - if(spendabletok==NULL || dirtok==NULL || statetok==NULL || - totaltok==NULL || peeridtok==NULL) - goto malformed; - if (!json_to_msat(buf, spendabletok, &spendable)) - goto malformed; - if (!json_to_msat(buf, totaltok, &capacity)) - goto malformed; - if (!json_to_int(buf, dirtok, &scidd.dir)) - goto malformed; - if(!json_to_node_id(buf,peeridtok,&dst)) - goto malformed; - - /* Don't report opening/closing channels */ - if (!json_tok_streq(buf, statetok, "CHANNELD_NORMAL") - && !json_tok_streq(buf, statetok, "CHANNELD_AWAITING_SPLICE")) { - payment_disable_chan(p, scidd.scid, LOG_DBG, - "channel in state %.*s", - statetok->end - statetok->start, - buf + statetok->start); - continue; - } - - struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scidd.scid); - - if(!ce) - { - /* this channel is not public, but it belongs to us */ - ce = new_chan_extra(chan_extra_map, - scidd.scid, - capacity); - /* FIXME: features? */ - gossmap_local_addchan(p->local_gossmods, - &src, &dst, &scidd.scid, NULL); - } - gossmap_local_updatechan(p->local_gossmods, - &scidd.scid, - - /* TODO(eduardo): does it - * matter to consider HTLC - * limits in our own channel? */ - AMOUNT_MSAT(0),capacity, + if (!enabled) { + payment_disable_chan(p, scidd->scid, LOG_DBG, + "listpeerchannelks says not enabled"); + return; + } - /* fees = */0,0, + ce = chan_extra_map_get(chan_extra_map, scidd->scid); + if (!ce) { + const jsmntok_t *totaltok; + struct amount_msat capacity; - /* TODO(eduardo): does it - * matter to set this delay? */ - /*delay=*/0, - true, - scidd.dir); + /* this channel is not public, but it belongs to us */ + totaltok = json_get_member(buf, chantok, "total_msat"); + json_to_msat(buf, totaltok, &capacity); - /* FIXME: There is a bug with us trying to send more down a local - * channel (after fees) than it has capacity. For now, we reduce - * our capacity by 1% of total, to give fee headroom. */ - if (!amount_msat_sub(&spendable, spendable, - amount_msat_div(p->amount, 100))) - spendable = AMOUNT_MSAT(0); - - // TODO(eduardo): this includes pending HTLC of previous - // payments! - /* We know min and max liquidity exactly now! */ - chan_extra_set_liquidity(chan_extra_map, - &scidd,spendable); + ce = new_chan_extra(chan_extra_map, scidd->scid, capacity); } - return true; -malformed: - return false; + /* FIXME: There is a bug with us trying to send more down a local + * channel (after fees) than it has capacity. For now, we reduce + * our capacity by 1% of total, to give fee headroom. */ + if (!amount_msat_sub(&max, max, amount_msat_div(p->amount, 100))) + max = AMOUNT_MSAT(0); + + // TODO(eduardo): this includes pending HTLC of previous + // payments! + /* We know min and max liquidity exactly now! */ + chan_extra_set_liquidity(chan_extra_map, scidd, max); } /* Forget ALL channels information by a fraction of the capacity. */ diff --git a/plugins/renepay/uncertainty_network.h b/plugins/renepay/uncertainty_network.h index f9f8445ed3d8..8376676f59c0 100644 --- a/plugins/renepay/uncertainty_network.h +++ b/plugins/renepay/uncertainty_network.h @@ -39,12 +39,13 @@ void uncertainty_network_channel_can_send( /* listpeerchannels gives us the certainty on local channels' capacity. Of course, * this is racy and transient, but better than nothing! */ -bool uncertainty_network_update_from_listpeerchannels( - struct chan_extra_map * chan_extra_map, - struct node_id my_id, - struct payment *payment, - const char *buf, - const jsmntok_t *toks); +void uncertainty_network_update_from_listpeerchannels(struct payment *p, + const struct short_channel_id_dir *scidd, + struct amount_msat max, + bool enabled, + const char *buf, + const jsmntok_t *chantok, + struct chan_extra_map *chan_extra_map); /* Forget ALL channels information by a fraction of the capacity. */ void uncertainty_network_relax_fraction( From d536eeb3fb7db8b1dca9cfd47ce3761e3442aa7b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 19/29] pytest: fix test_zeroconf_open() l2 gave us a routehint, but it should have seen l1 as a dead-end. It didn't due to the presence of a channel alias, which was a bug. We're about to fix this, which breaks the test. Add a dummy node off l1. Signed-off-by: Rusty Russell --- tests/test_opening.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/test_opening.py b/tests/test_opening.py index 25ff00fd1eb7..e8926e3596a8 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -1634,14 +1634,18 @@ def test_zeroconf_open(bitcoind, node_factory): """ plugin_path = Path(__file__).parent / "plugins" / "zeroconf-selective.py" - l1, l2 = node_factory.get_nodes(2, opts=[ + # Without l0->l1, l2 doesn't add a routehint since l1 looks like a deadend + l0, l1, l2 = node_factory.get_nodes(3, opts=[ + {}, {}, { 'plugin': str(plugin_path), - 'zeroconf-allow': '0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518' + 'zeroconf-allow': '022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59' }, ]) + node_factory.join_nodes([l0, l1], wait_for_announce=True) + # Try to open a mindepth=0 channel l1.fundwallet(10**6) @@ -1653,7 +1657,7 @@ def test_zeroconf_open(bitcoind, node_factory): # plugin l1.rpc.fundchannel(l2.info['id'], 'all', mindepth=0) - assert l1.db.query('SELECT minimum_depth FROM channels') == [{'minimum_depth': 0}] + assert l1.db.query('SELECT minimum_depth FROM channels WHERE minimum_depth != 1') == [{'minimum_depth': 0}] assert l2.db.query('SELECT minimum_depth FROM channels') == [{'minimum_depth': 0}] l1.daemon.wait_for_logs([ @@ -1665,16 +1669,19 @@ def test_zeroconf_open(bitcoind, node_factory): r'Peer told us that they\'ll use alias=[0-9x]+ for this channel', ]) - wait_for(lambda: only_one(l1.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') + wait_for(lambda: [c['state'] for c in l1.rpc.listpeerchannels()['channels']] == ['CHANNELD_NORMAL'] * 2) wait_for(lambda: only_one(l2.rpc.listpeerchannels()['channels'])['state'] == 'CHANNELD_NORMAL') wait_for(lambda: l2.rpc.listincoming()['incoming'] != []) + # Make sure l2 sees l0->l1 + wait_for(lambda: l2.rpc.listchannels() != {'channels': []}) + inv = l2.rpc.invoice(10**8, 'lbl', 'desc')['bolt11'] details = l1.rpc.decodepay(inv) pprint(details) assert('routes' in details and len(details['routes']) == 1) hop = details['routes'][0][0] # First (and only) hop of hint 0 - l1alias = only_one(l1.rpc.listpeerchannels()['channels'])['alias']['local'] + l1alias = only_one(l1.rpc.listpeerchannels(l2.info['id'])['channels'])['alias']['local'] assert(hop['pubkey'] == l1.info['id']) # l1 is the entrypoint assert(hop['short_channel_id'] == l1alias) # Alias has to make sense to entrypoint l1.rpc.pay(inv) From 08dda8d49973084bb74fb85ebd4eff8dfdc3dca3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 20/29] lightningd: permit wrong-alias lookups for private channel_update. This is wrong, but we send them for now in zeroconf! Signed-off-by: Rusty Russell --- lightningd/gossip_control.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 4378f6c1a26a..b4083c29ad6b 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -205,6 +205,30 @@ static void set_channel_remote_update(struct lightningd *ld, wallet_channel_save(ld->wallet, channel); } +/* One of the few places where we look up by *remote* id. It's not unique, + * but it is unique for a specific peer. */ +static struct channel *lookup_by_peer_remote_alias(struct lightningd *ld, + const struct node_id *source, + struct short_channel_id scid) +{ + const struct peer *p; + struct channel *chan; + + if (!source) + return NULL; + + p = peer_by_id(ld, source); + if (!p) + return NULL; + + list_for_each(&p->channels, chan, list) { + if (chan->alias[REMOTE] + && short_channel_id_eq(&scid, chan->alias[REMOTE])) + return chan; + } + return NULL; +} + static void handle_peer_update_data(struct lightningd *ld, const u8 *msg) { struct channel *channel; @@ -216,8 +240,10 @@ static void handle_peer_update_data(struct lightningd *ld, const u8 *msg) fatal("Gossip gave bad GOSSIPD_REMOTE_CHANNEL_UPDATE %s", tal_hex(msg, msg)); channel = any_channel_by_scid(ld, &update->scid, true); + if (!channel) + channel = lookup_by_peer_remote_alias(ld, source, update->scid); if (!channel) { - log_unusual(ld->log, "Bad gossip: could not find channel %s for peer's " + log_unusual(ld->log, "Bad gossip order: could not find channel %s for peer's " "channel update", short_channel_id_to_str(tmpctx, &update->scid)); return; From 06efdc7d075ac3bdb6498c81b5a5f044e8b9884b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 21/29] lightningd: make listincoming use gossmods_from_listpeerchannels(). We temporarily use a second gossmap so we can just switch private info off for listincoming and not listchannels. Note that listchannels now uses the local alias (if no scid), so we have to change that in the routehint caller. Since we now *always* use a channel alias in hints if one exists, a test broke, so fix that. Signed-off-by: Rusty Russell --- lightningd/routehint.c | 62 ++++++++++++++++++++++-------------------- plugins/topology.c | 40 ++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/lightningd/routehint.c b/lightningd/routehint.c index 0ac8b6dcce7e..071f37213c25 100644 --- a/lightningd/routehint.c +++ b/lightningd/routehint.c @@ -63,7 +63,6 @@ routehint_candidates(const tal_t *ctx, struct routehint_candidate candidate; struct amount_msat fee_base, htlc_max; struct route_info *r; - struct peer *peer; bool is_public; r = tal(tmpctx, struct route_info); @@ -94,27 +93,8 @@ routehint_candidates(const tal_t *ctx, json_tok_full(buf, toks)); } - /* Do we know about this peer? */ - peer = peer_by_id(ld, &r->pubkey); - if (!peer) { - log_debug(ld->log, "%s: unknown peer", - type_to_string(tmpctx, - struct node_id, - &r->pubkey)); - continue; - } - - /* Check channel is in CHANNELD_NORMAL or CHANNELD_AWAITING_SPLICE */ - candidate.c = find_channel_by_scid(peer, &r->short_channel_id); - - /* Try seeing if we should be using a remote alias - * instead. The `listpeers` result may have returned - * the REMOTE alias, because it is the only scid we - * have, and it is mandatory once the channel is in - * CHANNELD_NORMAL or CHANNELD_AWAITING_SPLICE. */ - if (!candidate.c) - candidate.c = find_channel_by_alias(peer, &r->short_channel_id, REMOTE); - + /* Note: listincoming returns real scid or local alias if no real scid. */ + candidate.c = any_channel_by_scid(ld, &r->short_channel_id, true); if (!candidate.c) { log_debug(ld->log, "%s: channel not found in peer %s", type_to_string(tmpctx, @@ -126,6 +106,7 @@ routehint_candidates(const tal_t *ctx, continue; } + /* Check channel is in CHANNELD_NORMAL or CHANNELD_AWAITING_SPLICE */ if (!channel_state_can_add_htlc(candidate.c->state)) { log_debug(ld->log, "%s: abnormal channel", type_to_string(tmpctx, @@ -212,15 +193,36 @@ routehint_candidates(const tal_t *ctx, * - MUST NOT use the real `short_channel_id` in * BOLT 11 `r` fields. */ - /* FIXME: We don't remember the type explicitly, so - * we just assume all private channels negotiated since - * we had alias support want this. */ - - /* Note explicit flag test here: if we're told to expose all - * private channels, then "is_public" is forced true */ - if (!(candidate.c->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL) - && candidate.c->alias[REMOTE]) { + if (channel_has(candidate.c, OPT_SCID_ALIAS)) { + if (!candidate.c->alias[REMOTE]) { + log_debug(ld->log, "%s: no remote alias (yet?)", + type_to_string(tmpctx, + struct short_channel_id, + &r->short_channel_id)); + continue; + } r->short_channel_id = *candidate.c->alias[REMOTE]; + } else { + /* Older code didn't remember type correctly, + * or negotiate properly, so best effort here */ + + /* Note explicit flag test here: if we're told to expose all + * private channels, then "is_public" is forced true */ + if (candidate.c->alias[REMOTE] + /* Use remote alias if it's all we've got, or unannounced channel */ + && (!(candidate.c->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL) + || !candidate.c->scid)) { + r->short_channel_id = *candidate.c->alias[REMOTE]; + } else if (candidate.c->scid) { + r->short_channel_id = *candidate.c->scid; + } else { + /* Haven't got remote alias yet? Can't use ut. */ + log_debug(ld->log, "%s: no alias", + type_to_string(tmpctx, + struct short_channel_id, + &r->short_channel_id)); + continue; + } } /* OK, finish it and append to one of the arrays. */ diff --git a/plugins/topology.c b/plugins/topology.c index e1c19ddeeaf3..df8ffb793d4f 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -181,7 +181,7 @@ listpeerchannels_getroute_done(struct command *cmd, static struct command_result *listpeerchannels_err(struct command *cmd, const char *buf, const jsmntok_t *result, - struct getroute_info *info) + void *unused) { plugin_err(cmd->plugin, "Bad listpeerchannels: %.*s", @@ -558,18 +558,26 @@ static struct amount_msat peer_capacity(const struct gossmap *gossmap, return capacity; } -static struct command_result *json_listincoming(struct command *cmd, - const char *buffer, - const jsmntok_t *params) +static struct command_result * +listpeerchannels_listincoming_done(struct command *cmd, + const char *buffer, + const jsmntok_t *result, + void *unused) { struct json_stream *js; struct gossmap_node *me; struct gossmap *gossmap; + struct gossmap_localmods *mods; - if (!param(cmd, buffer, params, NULL)) - return command_param_failed(); + /* Get local knowledge */ + mods = gossmods_from_listpeerchannels(tmpctx, &local_id, + buffer, result, + gossmod_add_localchan, + NULL); - gossmap = get_gossmap(false); + /* Overlay local knowledge */ + gossmap = get_gossmap(true); + gossmap_apply_localmods(gossmap, mods); js = jsonrpc_stream_success(cmd); json_array_start(js, "incoming"); @@ -621,9 +629,27 @@ static struct command_result *json_listincoming(struct command *cmd, done: json_array_end(js); + gossmap_remove_localmods(gossmap, mods); return command_finished(cmd, js); } +static struct command_result *json_listincoming(struct command *cmd, + const char *buffer, + const jsmntok_t *params) +{ + struct out_req *req; + + if (!param(cmd, buffer, params, NULL)) + return command_param_failed(); + + /* Add local info */ + req = jsonrpc_request_start(cmd->plugin, + cmd, "listpeerchannels", + listpeerchannels_listincoming_done, + listpeerchannels_err, NULL); + return send_outreq(cmd->plugin, req); +} + static void memleak_mark(struct plugin *p, struct htable *memtable) { memleak_scan_obj(memtable, global_gossmap); From 5a81edd76534b38b4e50ab857d8c0176b893eeb7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 22/29] pytest: remove test waits for routehints. Now listincoming sees local channels in listpeerchannels, we don't need these waits. Signed-off-by: Rusty Russell --- tests/test_pay.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_pay.py b/tests/test_pay.py index 919ac39c5836..0892b88b951b 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -3469,7 +3469,6 @@ def test_excluded_adjacent_routehint(node_factory, bitcoind): l1, l2, l3 = node_factory.line_graph(3) # We'll be forced to use routehint, since we don't know about l3. - l3.wait_channel_active(l3.get_channel_scid(l2)) inv = l3.rpc.invoice(10**3, "lbl", "desc", exposeprivatechannels=l2.get_channel_scid(l3)) l1.wait_channel_active(l1.get_channel_scid(l2)) @@ -4038,9 +4037,6 @@ def no_more_blocks(req): bitcoind.generate_block(2) sync_blockheight(bitcoind, [l3]) - # FIXME: routehint currently requires channels in gossip store - l3.wait_channel_active(l2l3) - inv = l3.rpc.invoice(Millisatoshi(2 * 10000 * 1000), 'i', 'i', exposeprivatechannels=True)['bolt11'] assert 'routes' in l3.rpc.decodepay(inv) @@ -4894,8 +4890,6 @@ def test_routehint_tous(node_factory, bitcoind): # Make sure l3 sees l1->l2 channel. l3.wait_channel_active(scid12) - # FIXME: Routehint code currently relies on private gossip in store! - l3.wait_channel_active(scid23) inv = l3.rpc.invoice(10, "test", "test")['bolt11'] decoded = l3.rpc.decodepay(inv) assert(only_one(only_one(decoded['routes']))['short_channel_id'] @@ -5480,8 +5474,6 @@ def test_pay_routehint_minhtlc(node_factory, bitcoind): # And make sure l1 knows that l2->l3 has htlcmin 1000 wait_for(lambda: l1.rpc.listchannels(scid)['channels'][0]['htlc_minimum_msat'] == Millisatoshi(1000)) - # FIXME: Routehint code currently relies on private gossip in store! - l4.wait_channel_active(scid34) inv = l4.rpc.invoice(100000, "inv", "inv") assert only_one(l1.rpc.decodepay(inv['bolt11'])['routes']) From da4ba260d0a8aa74d74aa6f15aa0b93cd640b4a7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 23/29] topology: don't show private nodes in listnodes. This breaks our tests a bit, which assumed we can always see ourselves even if we don't have a proper channel. Usually we would deprecate this first, but it's unlikely to break anyone since it's a bit obscure that this worked at all. Signed-off-by: Rusty Russell Changelog-Changed: JSON-RPC: `listnodes` no longer shows private (peer) nodes: use listpeers --- contrib/pyln-testing/pyln/testing/utils.py | 3 ++- plugins/topology.c | 2 +- tests/test_splicing.py | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index 968aea657034..899f962fecac 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -1662,7 +1662,8 @@ def join_nodes(self, nodes, fundchannel=True, fundamount=FUNDAMOUNT, wait_for_an # Make sure we have all node announcements, too for n in nodes: for n2 in nodes: - wait_for(lambda: 'alias' in only_one(n.rpc.listnodes(n2.info['id'])['nodes'])) + alias = n2.rpc.getinfo()['alias'] + wait_for(lambda: [n.get('alias') for n in n.rpc.listnodes(n2.info['id'])['nodes']] == [alias]) def line_graph(self, num_nodes, fundchannel=True, fundamount=FUNDAMOUNT, wait_for_announce=False, opts=None, announce_channels=True): """ Create nodes, connect them and optionally fund channels. diff --git a/plugins/topology.c b/plugins/topology.c index df8ffb793d4f..094fa9a259ea 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -515,7 +515,7 @@ static struct command_result *json_listnodes(struct command *cmd, NULL)) return command_param_failed(); - gossmap = get_gossmap(false); + gossmap = get_gossmap(true); js = jsonrpc_stream_success(cmd); json_array_start(js, "nodes"); if (id) { diff --git a/tests/test_splicing.py b/tests/test_splicing.py index 78e480571ac8..e173c595e29d 100644 --- a/tests/test_splicing.py +++ b/tests/test_splicing.py @@ -136,8 +136,8 @@ def test_splice_listnodes(node_factory, bitcoind): bitcoind.generate_block(7) - assert len(l1.rpc.listnodes()['nodes']) == 2 - assert len(l2.rpc.listnodes()['nodes']) == 2 + wait_for(lambda: len(l1.rpc.listnodes()['nodes']) == 2) + wait_for(lambda: len(l2.rpc.listnodes()['nodes']) == 2) @pytest.mark.openchannel('v1') From f6a22102446956c66d3821245159a291a85c73b4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 24/29] pytest: fix tests in assumption that listchannels will no longer show private gossip. Some can only be changed once that is true, but some can be removed/amended already. Signed-off-by: Rusty Russell --- tests/test_gossip.py | 135 ++++++------------------------------------ tests/test_opening.py | 5 +- tests/test_pay.py | 22 ++++--- tests/test_plugin.py | 18 ++++-- 4 files changed, 48 insertions(+), 132 deletions(-) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index c4ed0999dc41..56a4ca847032 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -1555,104 +1555,30 @@ def test_getroute_exclude(node_factory, bitcoind): l1.rpc.getroute(l4.info['id'], 1, 1, exclude=[chan_l2l3, l5.info['id'], chan_l2l4]) -def test_gossip_store_local_channels(node_factory, bitcoind): - l1, l2 = node_factory.line_graph(2, wait_for_announce=False) - - # We see this channel, even though it's not announced, because it's local. - wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2) - - l2.stop() - l1.restart() - - # We should still see local channels! - time.sleep(3) # Make sure store is loaded - chans = l1.rpc.listchannels()['channels'] - assert len(chans) == 2 - - # Now compact store - l1.rpc.call('dev-compact-gossip-store') - l1.restart() - - time.sleep(3) # Make sure store is loaded - # We should still see local channels! - chans = l1.rpc.listchannels()['channels'] - assert len(chans) == 2 - - -def test_gossip_store_private_channels(node_factory, bitcoind): - l1, l2 = node_factory.line_graph(2, announce_channels=False) - - # We see this channel, even though it's not announced, because it's local. - wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2) - - l2.stop() - l1.restart() - - # We should still see local channels! - time.sleep(3) # Make sure store is loaded - chans = l1.rpc.listchannels()['channels'] - assert len(chans) == 2 - - # Now compact store - l1.rpc.call('dev-compact-gossip-store') - l1.restart() - - time.sleep(3) # Make sure store is loaded - # We should still see local channels! - chans = l1.rpc.listchannels()['channels'] - assert len(chans) == 2 - - def setup_gossip_store_test(node_factory, bitcoind): - l1, l2, l3 = node_factory.line_graph(3, fundchannel=False) - - # Create channel. - scid23, _ = l2.fundchannel(l3, 10**6) - - # Have that channel announced. - mine_funding_to_announce(bitcoind, [l1, l2, l3]) - # Make sure we've got node_announcements - wait_for(lambda: ['alias' in n for n in l2.rpc.listnodes()['nodes']] == [True, True]) + l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True) # Now, replace the one channel_update, so it's past the node announcements. l2.rpc.setchannel(l3.info['id'], 20, 1000) - # Old base feerate is 1. - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l2.rpc.listchannels()['channels']]) == 21) + l3.rpc.setchannel(l2.info['id'], 21, 1001) - # Create another channel, which will stay private. - scid12, _ = l1.fundchannel(l2, 10**6) - - # FIXME: We assume that private announcements are in gossip_store! - l2.wait_channel_active(scid12) - - # Now insert channel_update for previous channel; now they're both past the - # node announcements. - l3.rpc.setchannel(l2.info['id'], feebase=20, feeppm=1000) - wait_for(lambda: [c['base_fee_millisatoshi'] for c in l2.rpc.listchannels(scid23)['channels']] == [20, 20]) + # Wait for it to hit l1's gossip store. + wait_for(lambda: sorted([c['fee_per_millionth'] for c in l1.rpc.listchannels()['channels']]) == [10, 10, 1000, 1001]) - # Replace both (private) updates for scid12. - l1.rpc.setchannel(l2.info['id'], feebase=20, feeppm=1000) - l2.rpc.setchannel(l1.info['id'], feebase=20, feeppm=1000) - wait_for(lambda: [c['base_fee_millisatoshi'] for c in l2.rpc.listchannels(scid12)['channels']] == [20, 20]) - - # Records in store now looks (something) like: - # DELETED: private channel_announcement (scid23) - # DELETED: private channel_update (scid23/0) - # DELETED: private channel_update (scid23/1) - # delete channel (scid23) + # Records in l2's store now looks (something) like: + # channel_announcement (scid12) + # channel_amount + # channel_update (scid12/0) + # channel_update (scid12/1) + # node_announcement (l1) + # node_announcement (l2) # channel_announcement (scid23) # channel_amount # DELETED: channel_update (scid23/0) # DELETED: channel_update (scid23/1) # node_announcement - # node_announcement - # channel_update (scid23) - # private channel_announcement (scid12) - # DELETED: private channel_update (scid12/0) - # DELETED: private channel_update (scid12/1) - # channel_update (scid23) - # private_channel_update (scid12) - # private_channel_update (scid12) + # channel_update (scid23/0) + # channel_update (scid23/1) return l2 @@ -1750,13 +1676,15 @@ def test_gossip_store_compact_on_load(node_factory, bitcoind): l2.restart() # These appear before we're fully started, so will already in log: - line = l2.daemon.is_in_log(r'gossip_store_compact_offline: .* deleted, 9 copied') + # FIXME: this will change! + line = l2.daemon.is_in_log(r'gossip_store_compact_offline: .* deleted, .* copied') m = re.search(r'gossip_store_compact_offline: (.*) deleted', line) # We can have private re-tranmissions, but at minumum we had a deleted private # channel message and two private updates, then two deleted updates. assert int(m.group(1)) >= 5 - assert l2.daemon.is_in_log(r'gossip_store: Read 2/4/2/0 cannounce/cupdate/nannounce/cdelete from store \(0 deleted\) in [0-9]* bytes') + # FIXME: this will change! + assert l2.daemon.is_in_log(r'gossip_store: Read 2/4/[23]/0 cannounce/cupdate/nannounce/cdelete from store \(0 deleted\) in [0-9]* bytes') def test_gossip_announce_invalid_block(node_factory, bitcoind): @@ -2169,35 +2097,6 @@ def test_close_12_block_delay(node_factory, bitcoind): wait_for(lambda: l4.rpc.listchannels(source=l2.info['id'])['channels'] == []) -def test_gossip_private_updates(node_factory, bitcoind): - """Check that private channel updates are properly added and deleted from - the gossip store. - - """ - l1, l2 = node_factory.get_nodes(2) - - l1.rpc.connect(l2.info['id'], 'localhost', l2.port) - scid, _ = l1.fundchannel(l2, 10**6, None, False) - bitcoind.generate_block(5) - - l1.wait_local_channel_active(scid) - l2.wait_local_channel_active(scid) - - l2.rpc.setchannel(l1.info['id'], feebase=11) - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 12) - l2.rpc.setchannel(l1.info['id'], feebase=12) - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 13) - l2.rpc.setchannel(l1.info['id'], feebase=13) - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 14) - l2.rpc.setchannel(l1.info['id'], feebase=14) - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 15) - l2.rpc.setchannel(l1.info['id'], feebase=15) - wait_for(lambda: sum([c['base_fee_millisatoshi'] for c in l1.rpc.listchannels()['channels']]) == 16) - l1.restart() - - wait_for(lambda: l1.daemon.is_in_log(r'gossip_store_compact_offline: 5 deleted, 3 copied')) - - def test_gossip_not_dying(node_factory, bitcoind): l1 = node_factory.get_node() l2, l3 = node_factory.line_graph(2, wait_for_announce=True) diff --git a/tests/test_opening.py b/tests/test_opening.py index e8926e3596a8..40f56710b04d 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -1835,7 +1835,8 @@ def test_zeroconf_forward(node_factory, bitcoind): # And now try the other way around: zeroconf channel first # followed by a public one. - wait_for(lambda: len(l3.rpc.listchannels()['channels']) == 4) + # Make sure it l3 sees l1->l2 + wait_for(lambda: len(l3.rpc.listchannels(source=l1.info['id'])['channels']) == 1) # Make sure all htlcs completely settled! wait_for(lambda: (p['htlcs'] == [] for p in l2.rpc.listpeerchannels()['channels'])) @@ -2011,7 +2012,7 @@ def test_scid_alias_private(node_factory, bitcoind): scid12 = chan['short_channel_id'] # Make sure it sees both sides of private channel in gossmap! - wait_for(lambda: len(l3.rpc.listchannels()['channels']) == 4) + wait_for(lambda: 'remote' in only_one(l3.rpc.listpeerchannels(l2.info['id'])['channels'])['updates']) # BOLT #2: # - if `channel_type` has `option_scid_alias` set: diff --git a/tests/test_pay.py b/tests/test_pay.py index 0892b88b951b..66ae923f6841 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -259,8 +259,6 @@ def test_pay_disconnect(node_factory, bitcoind): inv = l2.rpc.invoice(123000, 'test_pay_disconnect', 'description') rhash = inv['payment_hash'] - wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [True, True]) - # Can't use `pay` since that'd notice that we can't route, due to disabling channel_update route = l1.rpc.getroute(l2.info['id'], 123000, 1)["route"] @@ -2045,7 +2043,8 @@ def channel_get_config(scid): assert channel['minimum_htlc_out_msat'] == 17 assert channel['maximum_htlc_out_msat'] == 133337 - # wait for gossip and check if l1 sees new fees in listchannels + # wait for gossip and check if l1 sees new fees in listchannels after mining + bitcoind.generate_block(5) wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_BASE, 1337]) wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid)['channels']] == [DEF_PPM, 137]) wait_for(lambda: [c['htlc_minimum_msat'] for c in l1.rpc.listchannels(scid)['channels']] == [0, 17]) @@ -2448,10 +2447,19 @@ def test_setchannel_all(node_factory, bitcoind): # now try to set all (two) channels using wildcard syntax result = l1.rpc.setchannel("all", 0xDEAD, 0xBEEF, 0xBAD, 0xCAFE) - wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_BASE, 0xDEAD]) - wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid2)['channels']] == [DEF_PPM, 0xBEEF]) - wait_for(lambda: [c['base_fee_millisatoshi'] for c in l1.rpc.listchannels(scid3)['channels']] == [0xDEAD, DEF_BASE]) - wait_for(lambda: [c['fee_per_millionth'] for c in l1.rpc.listchannels(scid3)['channels']] == [0xBEEF, DEF_PPM]) + channel_after = {"htlc_minimum_msat": Millisatoshi(0xBAD), + "htlc_maximum_msat": Millisatoshi(0xCAFE), + "cltv_expiry_delta": 6, + "fee_base_msat": Millisatoshi(0xDEAD), + "fee_proportional_millionths": 0xBEEF} + + # We should see these updates immediately. + assert only_one(l1.rpc.listpeerchannels(l2.info['id'])['channels'])['updates']['local'] == channel_after + assert only_one(l1.rpc.listpeerchannels(l3.info['id'])['channels'])['updates']['local'] == channel_after + + # Peer should see them soon (once we sent) + wait_for(lambda: only_one(l2.rpc.listpeerchannels()['channels'])['updates']['remote'] == channel_after) + wait_for(lambda: only_one(l3.rpc.listpeerchannels()['channels'])['updates']['remote'] == channel_after) # Don't assume order! assert len(result['channels']) == 2 diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 894b85992832..51140f352c8b 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -4,6 +4,7 @@ from hashlib import sha256 from pyln.client import RpcError, Millisatoshi from pyln.proto import Invoice +from pyln.testing.utils import FUNDAMOUNT from utils import ( only_one, sync_blockheight, TIMEOUT, wait_for, TEST_NETWORK, expected_peer_features, expected_node_features, @@ -1874,18 +1875,25 @@ def test_hook_crash(node_factory, executor, bitcoind): l1 = node_factory.get_node() nodes = [node_factory.get_node() for _ in perm] + # For simplicity, give us N UTXOs to spend. + addr = l1.rpc.newaddr('p2tr')['p2tr'] + for n in nodes: + bitcoind.rpc.sendtoaddress(addr, (FUNDAMOUNT + 5000) / 10**8) + bitcoind.generate_block(1, wait_for_mempool=len(nodes)) + sync_blockheight(bitcoind, [l1]) + # Start them in any order and we should still always end up with each # plugin being called and ultimately the `pay` call should succeed: for plugins, n in zip(perm, nodes): for p in plugins: n.rpc.plugin_start(p) - l1.openchannel(n, 10**6, confirm=False, wait_for_announce=False) + l1.connect(n) + l1.rpc.fundchannel(n.info['id'], FUNDAMOUNT) - # Mine final openchannel tx first. - sync_blockheight(bitcoind, [l1] + nodes) - mine_funding_to_announce(bitcoind, [l1] + nodes, wait_for_mempool=1) + # Mine txs first. + mine_funding_to_announce(bitcoind, [l1] + nodes, num_blocks=6, wait_for_mempool=len(nodes)) - wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2 * len(perm)) + wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2 * len(nodes)) # Start an RPC call that should error once the plugin crashes. f1 = executor.submit(nodes[0].rpc.hold_rpc_call) From 3362f7428e5c9dfbe37caf61c2f83582f63bb623 Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Wed, 13 Dec 2023 16:05:43 +1030 Subject: [PATCH 25/29] pytest: skip test_hook_crash on liquid CI --- tests/test_plugin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 51140f352c8b..58eb81368756 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1852,6 +1852,7 @@ def test_bcli(node_factory, bitcoind, chainparams): assert not resp["success"] and "decode failed" in resp["errmsg"] +@unittest.skipIf(TEST_NETWORK != 'regtest', 'p2tr addresses not supported by elementsd') def test_hook_crash(node_factory, executor, bitcoind): """Verify that we fail over if a plugin crashes while handling a hook. From 9bf173cd7e609240a4baf8ee00ccd88154bbe6b5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:06:19 +1030 Subject: [PATCH 26/29] topology: don't show private nodes in listchannels. This alters a few remaining tests, as well. [ Inclused even more test fixes from Alex Myers ! ] Signed-off-by: Rusty Russell Changelog-Deprecated: JSON-RPC: `listchannels` listing private channels: use listpeerchannels --- doc/lightning-listchannels.7.md | 7 ++- doc/schemas/listchannels.schema.json | 2 +- plugins/topology.c | 2 +- tests/test_cln_rs.py | 2 +- tests/test_connection.py | 4 +- tests/test_gossip.py | 79 +++++++++++++--------------- tests/test_pay.py | 2 +- 7 files changed, 50 insertions(+), 48 deletions(-) diff --git a/doc/lightning-listchannels.7.md b/doc/lightning-listchannels.7.md index 4e30be0eb1a8..1c0388d0d24b 100644 --- a/doc/lightning-listchannels.7.md +++ b/doc/lightning-listchannels.7.md @@ -13,6 +13,9 @@ The **listchannels** RPC command returns data on channels that are known to the node. Because channels may be bidirectional, up to 2 objects will be returned for each channel (one for each direction). +Note that for local channels, listpeerchannels(7) gives much more detailed +information: **listchannels** only shows public gossip information (previously it merged local information, but that was deprecated in *v24.02*). + If *short\_channel\_id* is a short channel id, then only known channels with a matching *short\_channel\_id* are returned. Otherwise, it must be null. @@ -37,7 +40,7 @@ On success, an object containing **channels** is returned. It is an array of ob - **destination** (pubkey): the destination node - **short\_channel\_id** (short\_channel\_id): short channel id of channel - **direction** (u32): direction (0 if source < destination, 1 otherwise). -- **public** (boolean): true if this is announced (otherwise it must be our channel) +- **public** (boolean): true if this is announced (from *v24.02*, being false is deprecated) - **amount\_msat** (msat): the total capacity of this channel (always a whole number of satoshis) - **message\_flags** (u8): as defined by BOLT #7 - **channel\_flags** (u8): as defined by BOLT #7 @@ -80,4 +83,4 @@ Lightning RFC site - BOLT \#7: -[comment]: # ( SHA256STAMP:cef9786aeca2eddaca0d1adf6dc3d0eef442297e0f63d7c49647e65dbca73396) +[comment]: # ( SHA256STAMP:5e729a362943aa9481cc12e410c1f507020983251871fbac497dbb8679ca36ca) diff --git a/doc/schemas/listchannels.schema.json b/doc/schemas/listchannels.schema.json index 9761f0a15e8f..19b79ba67fa3 100644 --- a/doc/schemas/listchannels.schema.json +++ b/doc/schemas/listchannels.schema.json @@ -47,7 +47,7 @@ }, "public": { "type": "boolean", - "description": "true if this is announced (otherwise it must be our channel)" + "description": "true if this is announced (from *v24.02*, being false is deprecated)" }, "amount_msat": { "type": "msat", diff --git a/plugins/topology.c b/plugins/topology.c index 094fa9a259ea..aafca3d831e2 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -359,7 +359,7 @@ static struct command_result *listpeerchannels_done(struct command *cmd, struct node_map *connected; struct gossmap_chan *c; struct json_stream *js; - struct gossmap *gossmap = get_gossmap(false); + struct gossmap *gossmap = get_gossmap(true); connected = local_connected(opts, buf, result); diff --git a/tests/test_cln_rs.py b/tests/test_cln_rs.py index 4caae5984f56..5e480cdb7175 100644 --- a/tests/test_cln_rs.py +++ b/tests/test_cln_rs.py @@ -316,7 +316,7 @@ def test_grpc_keysend_routehint(bitcoind, node_factory): ]) # FIXME: keysend needs (unannounced) channel in gossip_store - l1.wait_channel_active(first_scid(l1, l2)) + l1.wait_local_channel_active(first_scid(l1, l2)) # And now we send a keysend with that routehint list call = clnpb.KeysendRequest( diff --git a/tests/test_connection.py b/tests/test_connection.py index 570faaa54bbc..ad8484966e5b 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -2400,12 +2400,14 @@ def test_channel_reenable(node_factory): # Restart l2, will cause l1 to reconnect l2.stop() - wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [False, False]) + wait_for(lambda: [c['peer_connected'] for c in l1.rpc.listpeerchannels()['channels']] == [False]) l2.start() # Updates may be suppressed if redundant; just test results. wait_for(lambda: [c['active'] for c in l1.rpc.listchannels()['channels']] == [True, True]) + wait_for(lambda: [c['peer_connected'] for c in l1.rpc.listpeerchannels()['channels']] == [True]) wait_for(lambda: [c['active'] for c in l2.rpc.listchannels()['channels']] == [True, True]) + wait_for(lambda: [c['peer_connected'] for c in l2.rpc.listpeerchannels()['channels']] == [True]) def test_update_fee(node_factory, bitcoind): diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 56a4ca847032..0451c62c7287 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -92,7 +92,8 @@ def test_gossip_disable_channels(node_factory, bitcoind): def count_active(node): chans = node.rpc.listchannels()['channels'] active = [c for c in chans if c['active']] - return len(active) + connected = len([p for p in node.rpc.listpeerchannels()['channels'] if p['peer_connected'] is True]) + return connected * len(active) l1.wait_channel_active(scid) l2.wait_channel_active(scid) @@ -394,23 +395,32 @@ def test_gossip_jsonrpc(node_factory): # Shouldn't send announce signatures until 6 deep. assert not l1.daemon.is_in_log('peer_out WIRE_ANNOUNCEMENT_SIGNATURES') - # Channels should be activated locally - wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2) - wait_for(lambda: len(l2.rpc.listchannels()['channels']) == 2) - # Make sure we can route through the channel, will raise on failure l1.rpc.getroute(l2.info['id'], 100, 1) - # Outgoing should be active, but not public. - channels1 = l1.rpc.listchannels()['channels'] - channels2 = l2.rpc.listchannels()['channels'] + # Channels not should be activated locally + assert l1.rpc.listchannels() == {'channels': []} + assert l2.rpc.listchannels() == {'channels': []} + + # Outgoing should be public, even if not announced yet. + channels1 = l1.rpc.listpeerchannels()['channels'] + channels2 = l2.rpc.listpeerchannels()['channels'] + + assert [c['private'] for c in channels1] == [False] + assert [c['private'] for c in channels2] == [False] - assert [c['active'] for c in channels1] == [True, True] - assert [c['active'] for c in channels2] == [True, True] - # The incoming direction will be considered public, hence check for out - # outgoing only - assert len([c for c in channels1 if not c['public']]) == 2 - assert len([c for c in channels2 if not c['public']]) == 2 + # Now proceed to funding-depth and do a full gossip round + l1.bitcoin.generate_block(5) + # Could happen in either order. + l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES', + 'peer_in WIRE_ANNOUNCEMENT_SIGNATURES']) + + # Just wait for the update to kick off and then check the effect + needle = "Received node_announcement for node" + l1.daemon.wait_for_log(needle) + l2.daemon.wait_for_log(needle) + l1.wait_channel_active(only_one(channels1)['short_channel_id']) + l2.wait_channel_active(only_one(channels1)['short_channel_id']) # Test listchannels-by-source channels1 = l1.rpc.listchannels(source=l1.info['id'])['channels'] @@ -440,19 +450,6 @@ def test_gossip_jsonrpc(node_factory): with pytest.raises(RpcError, match=r"Can only specify one of.*"): l1.rpc.listchannels(short_channel_id="1x1x1", source=l2.info['id']) - # Now proceed to funding-depth and do a full gossip round - l1.bitcoin.generate_block(5) - # Could happen in either order. - l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES', - 'peer_in WIRE_ANNOUNCEMENT_SIGNATURES']) - - # Just wait for the update to kick off and then check the effect - needle = "Received node_announcement for node" - l1.daemon.wait_for_log(needle) - l2.daemon.wait_for_log(needle) - l1.wait_channel_active(only_one(channels1)['short_channel_id']) - l2.wait_channel_active(only_one(channels1)['short_channel_id']) - nodes = l1.rpc.listnodes()['nodes'] assert set([n['nodeid'] for n in nodes]) == set([l1.info['id'], l2.info['id']]) @@ -561,20 +558,20 @@ def active(node): return sorted([c['short_channel_id'] for c in chans if c['active']]) def non_public(node): - chans = node.rpc.listchannels()['channels'] - return sorted([c['short_channel_id'] for c in chans if not c['public']]) + # Not just c["private"] == True, but immature ones too. + public_chans = [c['short_channel_id'] for c in node.rpc.listchannels()['channels']] + our_chans = [c['short_channel_id'] for c in node.rpc.listpeerchannels()['channels'] if c['state'] in ('CHANNELD_NORMAL', 'CHANNELD_AWAITING_SPLICE')] + return sorted(list(set(our_chans) - set(public_chans))) # Channels should be activated wait_for(lambda: active(l1) == [scid12, scid12, scid23, scid23]) wait_for(lambda: active(l2) == [scid12, scid12, scid23, scid23]) - # This one sees its private channel - wait_for(lambda: active(l3) == [scid12, scid12, scid23, scid23, scid34, scid34]) + # This one has private channels, but doesn't appear in listchannels. + wait_for(lambda: active(l3) == [scid12, scid12, scid23, scid23]) - # l1 restarts and doesn't connect, but loads from persisted store, all - # local channels should be disabled, leaving only the two l2 <-> l3 - # directions + # l1 restarts and public gossip should persist l1.restart() - wait_for(lambda: active(l1) == [scid23, scid23]) + wait_for(lambda: active(l1) == [scid12, scid12, scid23, scid23]) # Now reconnect, they should re-enable the two l1 <-> l2 directions l1.rpc.connect(l2.info['id'], 'localhost', l2.port) @@ -590,24 +587,24 @@ def non_public(node): wait_for(lambda: active(l1) == [scid23, scid23]) wait_for(lambda: active(l2) == [scid23, scid23]) - wait_for(lambda: active(l3) == [scid23, scid23, scid34, scid34]) + wait_for(lambda: active(l3) == [scid23, scid23]) # The channel l3 -> l4 should be known only to them assert non_public(l1) == [] assert non_public(l2) == [] - wait_for(lambda: non_public(l3) == [scid34, scid34]) - wait_for(lambda: non_public(l4) == [scid34, scid34]) + wait_for(lambda: non_public(l3) == [scid34]) + wait_for(lambda: non_public(l4) == [scid34]) # Finally, it should also remember the deletion after a restart l3.restart() l4.restart() l2.rpc.connect(l3.info['id'], 'localhost', l3.port) l3.rpc.connect(l4.info['id'], 'localhost', l4.port) - wait_for(lambda: active(l3) == [scid23, scid23, scid34, scid34]) + wait_for(lambda: active(l3) == [scid23, scid23]) # Both l3 and l4 should remember their local-only channel - wait_for(lambda: non_public(l3) == [scid34, scid34]) - wait_for(lambda: non_public(l4) == [scid34, scid34]) + wait_for(lambda: non_public(l3) == [scid34]) + wait_for(lambda: non_public(l4) == [scid34]) def test_routing_gossip_reconnect(node_factory): diff --git a/tests/test_pay.py b/tests/test_pay.py index 66ae923f6841..878dff692403 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -309,7 +309,7 @@ def test_pay_get_error_with_update(node_factory): l3.stop() # Make sure that l2 has seen disconnect, considers channel disabled. - wait_for(lambda: [c['active'] for c in l2.rpc.listchannels(chanid2)['channels']] == [False, False]) + wait_for(lambda: only_one(l2.rpc.listpeerchannels(l3.info['id'])['channels'])['peer_connected'] is False) assert(l1.is_channel_active(chanid2)) with pytest.raises(RpcError, match=r'WIRE_TEMPORARY_CHANNEL_FAILURE'): From 1d8f94e3e913580b306531a45cb3bba40d15d550 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:06:28 +1030 Subject: [PATCH 27/29] common: gossmap now always ignores private gossip_store messages. In the next PR, they'll be removed, but for now all our code doesn't want them. Signed-off-by: Rusty Russell --- common/gossmap.c | 6 ------ common/gossmap.h | 3 --- plugins/fetchinvoice.c | 2 -- plugins/keysend.c | 2 -- plugins/pay.c | 2 -- plugins/renepay/pay.c | 3 --- plugins/topology.c | 17 ++++++----------- 7 files changed, 6 insertions(+), 29 deletions(-) diff --git a/common/gossmap.c b/common/gossmap.c index 5c54dd835d9d..bec5dea27eae 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -17,8 +17,6 @@ #include #include -bool gossmap_public_only; - /* We need this global to decode indexes for hash functions */ static struct gossmap *map; @@ -638,12 +636,8 @@ static bool map_catchup(struct gossmap *map, size_t *num_rejected) type = map_be16(map, off); if (type == WIRE_CHANNEL_ANNOUNCEMENT) add_channel(map, off, false); - else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL && !gossmap_public_only) - add_channel(map, off + 2 + 8 + 2, true); else if (type == WIRE_CHANNEL_UPDATE) num_bad += !update_channel(map, off); - else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE && !gossmap_public_only) - num_bad += !update_channel(map, off + 2 + 2); else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN) remove_channel_by_deletemsg(map, off); else if (type == WIRE_NODE_ANNOUNCEMENT) diff --git a/common/gossmap.h b/common/gossmap.h index 19f87d0e4d36..b173c9bd5515 100644 --- a/common/gossmap.h +++ b/common/gossmap.h @@ -40,9 +40,6 @@ struct gossmap_chan { } half[2]; }; -/* Temporary flag for testing: don't load private gossip info! */ -extern bool gossmap_public_only; - /* If num_channel_updates_rejected is not NULL, indicates how many channels we * marked inactive because their values were too high to be represented. */ struct gossmap *gossmap_load(const tal_t *ctx, const char *filename, diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index 17bb8780c4b6..cbb367f6fada 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -1577,8 +1577,6 @@ static const struct plugin_hook hooks[] = { int main(int argc, char *argv[]) { setup_locale(); - /* We are migrated, ready for public-only gossmap! */ - gossmap_public_only = true; plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands), /* No notifications */ diff --git a/plugins/keysend.c b/plugins/keysend.c index 17e39fd026c7..c53cd4b7f336 100644 --- a/plugins/keysend.c +++ b/plugins/keysend.c @@ -611,8 +611,6 @@ int main(int argc, char *argv[]) features->bits[i] = tal_arr(features, u8, 0); set_feature_bit(&features->bits[NODE_ANNOUNCE_FEATURE], KEYSEND_FEATUREBIT); - /* We are migrated, ready for public-only gossmap! */ - gossmap_public_only = true; plugin_main(argv, init, PLUGIN_STATIC, true, features, commands, ARRAY_SIZE(commands), NULL, 0, hooks, ARRAY_SIZE(hooks), notification_topics, ARRAY_SIZE(notification_topics), NULL); diff --git a/plugins/pay.c b/plugins/pay.c index d162e70bf512..153d86a32ba7 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -1300,8 +1300,6 @@ static const char *notification_topics[] = { int main(int argc, char *argv[]) { setup_locale(); - /* We are migrated, ready for public-only gossmap! */ - gossmap_public_only = true; plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands), NULL, 0, NULL, 0, notification_topics, ARRAY_SIZE(notification_topics), diff --git a/plugins/renepay/pay.c b/plugins/renepay/pay.c index 3383be8a318d..5fc6d0a61405 100644 --- a/plugins/renepay/pay.c +++ b/plugins/renepay/pay.c @@ -1339,9 +1339,6 @@ int main(int argc, char *argv[]) pay_plugin = tal(NULL, struct pay_plugin); pay_plugin->debug_mcf = pay_plugin->debug_payflow = false; - /* We are migrated, ready for public-only gossmap! */ - gossmap_public_only = true; - plugin_main( argv, init, diff --git a/plugins/topology.c b/plugins/topology.c index aafca3d831e2..7bc337faa129 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -23,14 +23,9 @@ static struct node_id local_id; static struct plugin *plugin; /* We load this on demand, since we can start before gossipd. */ -static struct gossmap *get_gossmap(bool public_only) +static struct gossmap *get_gossmap(void) { - /* Temporary hack so callers can individually exclude private gossip */ - tal_free(global_gossmap); - gossmap_public_only = public_only; - global_gossmap = gossmap_load(NULL, - GOSSIP_STORE_FILENAME, - NULL); + gossmap_refresh(global_gossmap, NULL); return global_gossmap; } @@ -170,7 +165,7 @@ listpeerchannels_getroute_done(struct command *cmd, gossmod_add_localchan, NULL); /* Overlay local knowledge for dijkstra */ - gossmap = get_gossmap(true); + gossmap = get_gossmap(); gossmap_apply_localmods(gossmap, mods); res = try_route(cmd, gossmap, info); gossmap_remove_localmods(gossmap, mods); @@ -359,7 +354,7 @@ static struct command_result *listpeerchannels_done(struct command *cmd, struct node_map *connected; struct gossmap_chan *c; struct json_stream *js; - struct gossmap *gossmap = get_gossmap(true); + struct gossmap *gossmap = get_gossmap(); connected = local_connected(opts, buf, result); @@ -515,7 +510,7 @@ static struct command_result *json_listnodes(struct command *cmd, NULL)) return command_param_failed(); - gossmap = get_gossmap(true); + gossmap = get_gossmap(); js = jsonrpc_stream_success(cmd); json_array_start(js, "nodes"); if (id) { @@ -576,7 +571,7 @@ listpeerchannels_listincoming_done(struct command *cmd, NULL); /* Overlay local knowledge */ - gossmap = get_gossmap(true); + gossmap = get_gossmap(); gossmap_apply_localmods(gossmap, mods); js = jsonrpc_stream_success(cmd); From 59a0479b25a349dd86914132d4aac07a73dcc5e3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:06:28 +1030 Subject: [PATCH 28/29] topology: deprecate overriding `active` in `listchannels` with `listpeerchannels` info. Signed-off-by: Rusty Russell Changelog-Deprecated: `listchannels` no longer uses local knowledge to set `active` to false if disconnected. --- doc/schemas/listchannels.schema.json | 2 +- plugins/topology.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/schemas/listchannels.schema.json b/doc/schemas/listchannels.schema.json index 19b79ba67fa3..bd3dd50de372 100644 --- a/doc/schemas/listchannels.schema.json +++ b/doc/schemas/listchannels.schema.json @@ -63,7 +63,7 @@ }, "active": { "type": "boolean", - "description": "true unless source has disabled it, or it's a local channel and the peer is disconnected or it's still opening or closing" + "description": "true unless source has disabled it (or (deprecated in *v24.02*) it's a local channel and the peer is disconnected or it's still opening or closing)" }, "last_update": { "type": "u32", diff --git a/plugins/topology.c b/plugins/topology.c index 7bc337faa129..b2771707f8e2 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -239,10 +239,10 @@ static void json_add_halfchan(struct json_stream *response, if (!gossmap_chan_get_capacity(gossmap, c, &capacity)) capacity = AMOUNT_SAT(0); - /* Local channels are not "active" unless peer is connected. */ - if (node_id_eq(&node_id[0], &local_id)) + /* Deprecated: local channels are not "active" unless peer is connected. */ + if (connected && node_id_eq(&node_id[0], &local_id)) local_disable = !node_map_get(connected, &node_id[1]); - else if (node_id_eq(&node_id[1], &local_id)) + else if (connected && node_id_eq(&node_id[1], &local_id)) local_disable = !node_map_get(connected, &node_id[0]); else local_disable = false; @@ -345,7 +345,7 @@ static struct node_map *local_connected(const tal_t *ctx, return connected; } -/* We want to combine local knowledge to we know which are actually inactive! */ +/* FIXME: We don't need this listpeerchannels at all if not deprecated! */ static struct command_result *listpeerchannels_done(struct command *cmd, const char *buf, const jsmntok_t *result, @@ -356,7 +356,10 @@ static struct command_result *listpeerchannels_done(struct command *cmd, struct json_stream *js; struct gossmap *gossmap = get_gossmap(); - connected = local_connected(opts, buf, result); + if (deprecated_apis) + connected = local_connected(opts, buf, result); + else + connected = NULL; js = jsonrpc_stream_success(cmd); json_array_start(js, "channels"); From 406e6d0861cf3568088369623e7a652c442d2a40 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Dec 2023 16:06:28 +1030 Subject: [PATCH 29/29] plugins: re-enable listchannels local info in deprecated mode. We only deprecated this, we didn't actually remove it. Signed-off-by: Rusty Russell --- doc/lightning-listchannels.7.md | 4 ++-- plugins/topology.c | 37 +++++++++++++++++++++++++++++++++ tests/test_gossip.py | 36 +++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/doc/lightning-listchannels.7.md b/doc/lightning-listchannels.7.md index 1c0388d0d24b..a9aadf3c8d55 100644 --- a/doc/lightning-listchannels.7.md +++ b/doc/lightning-listchannels.7.md @@ -44,7 +44,7 @@ On success, an object containing **channels** is returned. It is an array of ob - **amount\_msat** (msat): the total capacity of this channel (always a whole number of satoshis) - **message\_flags** (u8): as defined by BOLT #7 - **channel\_flags** (u8): as defined by BOLT #7 -- **active** (boolean): true unless source has disabled it, or it's a local channel and the peer is disconnected or it's still opening or closing +- **active** (boolean): true unless source has disabled it (or (deprecated in *v24.02*) it's a local channel and the peer is disconnected or it's still opening or closing) - **last\_update** (u32): UNIX timestamp on the last channel\_update from *source* - **base\_fee\_millisatoshi** (u32): Base fee changed by *source* to use this channel - **fee\_per\_millionth** (u32): Proportional fee changed by *source* to use this channel, in parts-per-million @@ -83,4 +83,4 @@ Lightning RFC site - BOLT \#7: -[comment]: # ( SHA256STAMP:5e729a362943aa9481cc12e410c1f507020983251871fbac497dbb8679ca36ca) +[comment]: # ( SHA256STAMP:c32fcbcb0d0ba926513978a96e6b68ee9e3d7f732b5a9cc167aa77cdd33d717f) diff --git a/plugins/topology.c b/plugins/topology.c index b2771707f8e2..38b458026512 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -345,6 +345,29 @@ static struct node_map *local_connected(const tal_t *ctx, return connected; } +/* Only add a local entry if it's unknown publicly */ +static void gossmod_add_unknown_localchan(struct gossmap_localmods *mods, + const struct node_id *self, + const struct node_id *peer, + const struct short_channel_id_dir *scidd, + struct amount_msat min, + struct amount_msat max, + struct amount_msat fee_base, + u32 fee_proportional, + u32 cltv_delta, + bool enabled, + const char *buf UNUSED, + const jsmntok_t *chantok UNUSED, + struct gossmap *gossmap) +{ + if (gossmap_find_chan(gossmap, &scidd->scid)) + return; + + gossmod_add_localchan(mods, self, peer, scidd, min, max, + fee_base, fee_proportional, cltv_delta, enabled, + buf, chantok, gossmap); +} + /* FIXME: We don't need this listpeerchannels at all if not deprecated! */ static struct command_result *listpeerchannels_done(struct command *cmd, const char *buf, @@ -355,12 +378,23 @@ static struct command_result *listpeerchannels_done(struct command *cmd, struct gossmap_chan *c; struct json_stream *js; struct gossmap *gossmap = get_gossmap(); + struct gossmap_localmods *mods; if (deprecated_apis) connected = local_connected(opts, buf, result); else connected = NULL; + /* In deprecated mode, re-add private channels */ + if (deprecated_apis) { + mods = gossmods_from_listpeerchannels(tmpctx, &local_id, + buf, result, + gossmod_add_unknown_localchan, + gossmap); + gossmap_apply_localmods(gossmap, mods); + } else + mods = NULL; + js = jsonrpc_stream_success(cmd); json_array_start(js, "channels"); if (opts->scid) { @@ -401,6 +435,9 @@ static struct command_result *listpeerchannels_done(struct command *cmd, json_array_end(js); + if (mods) + gossmap_remove_localmods(gossmap, mods); + return command_finished(cmd, js); } diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 0451c62c7287..984542b2908c 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -6,7 +6,8 @@ from utils import ( wait_for, TIMEOUT, only_one, sync_blockheight, expected_node_features, - mine_funding_to_announce, default_ln_port, CHANNEL_SIZE + mine_funding_to_announce, default_ln_port, CHANNEL_SIZE, + first_scid, ) import json @@ -2334,3 +2335,36 @@ def test_read_spam_nannounce(node_factory, bitcoind): l1.daemon.wait_for_log('Received node_announcement') l1.restart() assert not l1.daemon.is_in_log('BROKEN') + + +def test_listchannels_deprecated_local(node_factory, bitcoind): + """Test listchannels shows local/private channels only in deprecated mode""" + l1, l2, l3 = node_factory.get_nodes(3, + opts=[{}, {'allow-deprecated-apis': True}, {}]) + # This will be in block 103 + node_factory.join_nodes([l1, l2], wait_for_announce=False) + l1l2 = first_scid(l1, l2) + # This will be in block 104 + node_factory.join_nodes([l2, l3], wait_for_announce=False) + l2l3 = first_scid(l2, l3) + + # Non-deprecated nodes say no. + assert l1.rpc.listchannels() == {'channels': []} + assert l3.rpc.listchannels() == {'channels': []} + # Deprecated API lists both sides of local channels: + + vals = [(c['active'], c['public'], c['short_channel_id']) for c in l2.rpc.listchannels()['channels']] + # Either order + assert vals == [(True, False, l1l2)] * 2 + [(True, False, l2l3)] * 2 or vals == [(True, False, l2l3)] * 2 + [(True, False, l1l2)] * 2 + + # Mine l1-l2 channel so it's public. + bitcoind.generate_block(4) + sync_blockheight(bitcoind, [l1, l2, l3]) + + wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2) + wait_for(lambda: len(l3.rpc.listchannels()['channels']) == 2) + + # l2 shows public one correctly, and private one correctly + # Either order + vals = [(c['active'], c['public'], c['short_channel_id']) for c in l2.rpc.listchannels()['channels']] + assert vals == [(True, True, l1l2)] * 2 + [(True, False, l2l3)] * 2 or vals == [(True, False, l2l3)] * 2 + [(True, True, l1l2)] * 2