From 24d0273100c75eac99e0400f767267efde4b012c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Tue, 15 Sep 2026 12:35:53 -0400 Subject: [PATCH 01/36] connectd: stop requiring peers to advertise blake2b bit 68 --- connectd/peer_exchange_initmsg.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/connectd/peer_exchange_initmsg.c b/connectd/peer_exchange_initmsg.c index e96337c83a06..eb7bec648298 100644 --- a/connectd/peer_exchange_initmsg.c +++ b/connectd/peer_exchange_initmsg.c @@ -104,15 +104,6 @@ static struct io_plan *peer_init_received(struct io_conn *conn, } } - /* Required Blake2b identity in both directions, before peer admission. - * Merely understanding our even bit is not a declaration of this chain. */ - if (feature_is_set(peer->daemon->our_features->bits[INIT_FEATURE], OPT_BLAKE2B) - && !feature_is_set(features, OPT_BLAKE2B)) { - msg = towire_warningfmt(peer, NULL, "Peer must advertise required Blake2b feature bit 68"); - msg = cryptomsg_encrypt_msg(peer, &peer->cs, take(msg)); - return io_write(conn, msg, tal_count(msg), io_close_cb, NULL); - } - /* fetch optional tlv `remote_addr` */ remote_addr = NULL; From 321f6e52b1bb76ef40bd61ae6dc18136548b2637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 08:17:35 -0400 Subject: [PATCH 02/36] drop the paperclip workflow, which targets a branch this repo does not have --- .github/workflows/paperclip-build.yml | 75 --------------------------- 1 file changed, 75 deletions(-) delete mode 100644 .github/workflows/paperclip-build.yml diff --git a/.github/workflows/paperclip-build.yml b/.github/workflows/paperclip-build.yml deleted file mode 100644 index 2f895c7ffff8..000000000000 --- a/.github/workflows/paperclip-build.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Paperclip differentiation proposal -on: - push: - branches: [paperclip/blake2b-unified] - workflow_dispatch: -permissions: - contents: read -jobs: - ubuntu: - env: - RUST_PROFILE: small - TEST_NETWORK: regtest - runs-on: ubuntu-24.04 - timeout-minutes: 45 - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - submodules: recursive - - uses: astral-sh/setup-uv@v6 - - uses: actions/cache/restore@v4 - with: - path: target - key: rust-small-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} - - name: Dependencies - run: sudo apt-get update && sudo apt-get install -y autoconf automake build-essential libtool libsqlite3-dev libffi-dev zlib1g-dev libsodium-dev gettext lowdown libgmp-dev libpq-dev protobuf-compiler libssl-dev - - name: Build and stage - run: | - ./configure --prefix=/usr - uv run make -j2 - uv run make -j2 bitcoin/test/run-block_header_v2 connectd/test/run-blake2b_features bitcoin/test/run-unified_sighash - ./bitcoin/test/run-block_header_v2 - ./bitcoin/test/run-unified_sighash - ./connectd/test/run-blake2b_features - uv run make DESTDIR="$PWD/stage" install - stage/usr/bin/lightningd --version - stage/usr/bin/lightning-cli --version - test -x stage/usr/libexec/c-lightning/plugins/clnrest - - uses: actions/cache/save@v4 - with: - path: target - key: rust-small-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} - - name: Isolated regtest integration - run: | - .github/scripts/install-bitcoind.sh - uv run pytest -q tests/test_blake2b_differentiation.py --timeout=120 --maxfail=1 - - name: Knots unified transaction integration - run: | - mkdir -p /tmp/paperclip-knots - curl -fL https://github.com/bitcoinknots/bitcoin/releases/download/v29.4.1.knots20260508/bitcoin-29.4.1.knots20260508-x86_64-linux-gnu.tar.gz -o /tmp/paperclip-knots/node.tar.gz - echo '0d0b435ae67dd38d150c048a388be821ad0ca8b46d6dcace5c34d4ba2977801b /tmp/paperclip-knots/node.tar.gz' | sha256sum -c - - tar -xf /tmp/paperclip-knots/node.tar.gz -C /tmp/paperclip-knots - sudo cp /tmp/paperclip-knots/bitcoin-29.4.1.knots20260508/bin/bitcoin-cli /usr/local/bin/bitcoin-cli - printf '%s\n' '#!/bin/sh' 'exec /tmp/paperclip-knots/bitcoin-29.4.1.knots20260508/bin/bitcoind -testactivationheight=blake2b@1 "$@"' > /tmp/paperclip-knots/bitcoind - chmod +x /tmp/paperclip-knots/bitcoind - sudo cp /tmp/paperclip-knots/bitcoind /usr/local/bin/bitcoind - uv run pytest -q tests/test_unified_transactions.py --timeout=120 --maxfail=1 - uv run pytest -q tests/test_splicing.py::test_splice --timeout=120 --maxfail=1 - EXPERIMENTAL_DUAL_FUND=1 uv run pytest -q tests/test_unified_transactions.py tests/test_splicing.py::test_splice --timeout=120 --maxfail=1 - - name: Package - run: | - mkdir dist - cp doc/PAPERCLIP-BUILD.md stage/BUILD-NOTES.md - git rev-parse HEAD > stage/SOURCE-COMMIT - cp doc/BLAKE2B-DIFFERENTIATION.md stage/PROPOSAL.md - cp doc/BLAKE2B-UNIFIED-PROPOSAL.md stage/UNIFIED-PROPOSAL.md - XZ_OPT='-T2 -1' tar --owner=0 --group=0 -C stage -cJf dist/paperclip-cln-proposal-ubuntu24.04-amd64.tar.xz . - cp stage/SOURCE-COMMIT stage/BUILD-NOTES.md dist/ - cd dist - sha256sum *.tar.xz > SHA256SUMS - - uses: actions/upload-artifact@v7 - with: - name: paperclip-cln-proposal-ubuntu24.04-amd64 - path: dist/ - if-no-files-found: error From f0381beb7228247f98e9ec7e9d0fe54dedad25ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 09:04:56 -0400 Subject: [PATCH 03/36] tests: satisfy flake8 in the psbt sighash helper --- tests/psbt_patch.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/psbt_patch.py b/tests/psbt_patch.py index 955bc007c635..48ef39794986 100644 --- a/tests/psbt_patch.py +++ b/tests/psbt_patch.py @@ -1,11 +1,16 @@ import base64 + def _cs(b, i): n = b[i] - if n < 0xfd: return n, i + 1 - if n == 0xfd: return int.from_bytes(b[i+1:i+3], 'little'), i + 3 - if n == 0xfe: return int.from_bytes(b[i+1:i+5], 'little'), i + 5 - return int.from_bytes(b[i+1:i+9], 'little'), i + 9 + if n < 0xfd: + return n, i + 1 + if n == 0xfd: + return int.from_bytes(b[i + 1:i + 3], 'little'), i + 3 + if n == 0xfe: + return int.from_bytes(b[i + 1:i + 5], 'little'), i + 5 + return int.from_bytes(b[i + 1:i + 9], 'little'), i + 9 + def set_input0_sighash(psbt_b64, sighash): """Insert PSBT_IN_SIGHASH_TYPE (0x03) into the first input's map.""" From f3e7d881fa96c858ea8c7a58d295779aa3645326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 00:31:52 -0400 Subject: [PATCH 04/36] tests: match the fork's funding weight in the coin move amounts --- tests/test_coinmoves.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_coinmoves.py b/tests/test_coinmoves.py index bcaa226b65a8..70789e9d59fd 100644 --- a/tests/test_coinmoves.py +++ b/tests/test_coinmoves.py @@ -203,9 +203,9 @@ def test_coinmoves(node_factory, bitcoind): 'utxo': f"{fundchannel['txid']}:{fundchannel['outnum'] ^ 1}"}, {'account_id': fundchannel['channel_id'], 'blockheight': 104, - 'credit_msat': 99965813000, + 'credit_msat': 99965806000, 'debit_msat': 0, - 'output_msat': 99965813000, + 'output_msat': 99965806000, 'peer_id': l2.info['id'], 'primary_tag': 'channel_open', 'extra_tags': ['opener'], @@ -214,7 +214,7 @@ def test_coinmoves(node_factory, bitcoind): 'blockheight': 104, 'credit_msat': 0, 'debit_msat': 0, - 'output_msat': 99965813000, + 'output_msat': 99965806000, 'peer_id': l1.info['id'], 'primary_tag': 'channel_open', 'extra_tags': [], @@ -337,19 +337,19 @@ def test_coinmoves(node_factory, bitcoind): l2_vout_close = only_one([out['n'] for out in bitcoind.rpc.decoderawtransaction(only_one(close['txs']))['vout'] if out['scriptPubKey']['address'] in l2_addrs]) expected_chain1 += [{'account_id': 'wallet', 'blockheight': 111, - 'credit_msat': 89961918000, + 'credit_msat': 89961911000, 'debit_msat': 0, 'extra_tags': [], - 'output_msat': 89961918000, + 'output_msat': 89961911000, 'primary_tag': 'deposit', 'utxo': f"{only_one(close['txids'])}:{l1_vout_close}"}, {'account_id': fundchannel['channel_id'], 'blockheight': 111, 'credit_msat': 0, - 'debit_msat': 89964813000, + 'debit_msat': 89964806000, 'extra_tags': [], 'output_count': 2, - 'output_msat': 99965813000, + 'output_msat': 99965806000, 'primary_tag': 'channel_close', 'spending_txid': only_one(close['txids']), 'utxo': f"{fundchannel['txid']}:{fundchannel['outnum']}"}, @@ -376,17 +376,17 @@ def test_coinmoves(node_factory, bitcoind): 'debit_msat': 10001000000, 'extra_tags': [], 'output_count': 2, - 'output_msat': 99965813000, + 'output_msat': 99965806000, 'primary_tag': 'channel_close', 'spending_txid': only_one(close['txids']), 'utxo': f"{fundchannel['txid']}:{fundchannel['outnum']}"}, {'account_id': 'external', 'blockheight': 111, - 'credit_msat': 89961918000, + 'credit_msat': 89961911000, 'debit_msat': 0, 'extra_tags': [], 'originating_account': fundchannel['channel_id'], - 'output_msat': 89961918000, + 'output_msat': 89961911000, 'primary_tag': 'to_them', 'utxo': f"{only_one(close['txids'])}:{l2_vout_close ^ 1}"}] check_channel_moves(l1, expected_channel1) From 3bc82149e774f3f3d186fbd37fadbe5eb2de308b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 13:51:56 -0400 Subject: [PATCH 05/36] tests: bit 68 widens node_announcement, so the gossip store is larger --- tests/test_gossip.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 326a4391af40..4abcf8e76f6f 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -1650,8 +1650,9 @@ def test_gossip_store_compact(node_factory, bitcoind): # Now compact store. l2.rpc.call('dev-compact-gossip-store') # Splicing changes features, making this size 2365 bytes -> 2065 bytes. - l2.daemon.wait_for_logs(['gossipd: compaction done: 236[25] -> 206[25] bytes', - 'connectd: Reopened gossip_store, reduced to offset 206[25]']) + # Bit 68 in node_announcement widens the feature bitmap, adding 3 more. + l2.daemon.wait_for_logs(['gossipd: compaction done: 236[258] -> 206[258] bytes', + 'connectd: Reopened gossip_store, reduced to offset 206[258]']) # Should still be connected. time.sleep(1) @@ -1704,11 +1705,11 @@ def test_gossip_store_compact_while_extending(node_factory, bitcoind, executor): fut.result(TIMEOUT) # Exact gossip size varies with SPLICING. l1.daemon.wait_for_logs(['gossipd: compaction done', - 'connectd: Reopened gossip_store, reduced to offset 224[59]']) + 'connectd: Reopened gossip_store, reduced to offset 22(4[59]|53)']) post_channels = l1.rpc.listchannels() post_nodes = sorted(l1.rpc.listnodes()['nodes'], key=lambda n: n['nodeid']) - l1.daemon.wait_for_log('topology: Reopened gossip_store, reduced to offset 224[59]') + l1.daemon.wait_for_log('topology: Reopened gossip_store, reduced to offset 22(4[59]|53)') assert post_channels == pre_channels assert post_nodes == pre_nodes From 6457747fbecca68e10d729986902a936a181e994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 15:20:56 -0400 Subject: [PATCH 06/36] hsmd: free the mlocked secrets so the test has a cleanup function --- hsmd/libhsmd.c | 5 +++++ hsmd/libhsmd.h | 4 ++++ hsmd/test/run-bad-request-close.c | 1 + 3 files changed, 10 insertions(+) diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index b2985852030b..172def0c278d 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -2538,6 +2538,11 @@ void bip86_key(struct privkey *privkey, struct pubkey *pubkey, u32 index) "BIP86 pubkey %u create failed", index); } +void hsmd_secrets_free(void) +{ + secretstuff.bip32_seed = tal_free(secretstuff.bip32_seed); +} + u8 *hsmd_init(const u8 *secret_data, size_t secret_len, const u64 hsmd_version, struct bip32_key_version bip32_key_version, u8 hsm_secret_type) { diff --git a/hsmd/libhsmd.h b/hsmd/libhsmd.h index 484089d2c009..4c34e4844d28 100644 --- a/hsmd/libhsmd.h +++ b/hsmd/libhsmd.h @@ -49,6 +49,10 @@ struct hsmd_client { u8 *hsmd_init(const u8 *secret_data, size_t secret_len, const u64 hsmd_version, struct bip32_key_version bip32_key_version, u8 hsm_secret_type); +/* Release the secrets hsmd_init() locked in memory: tests only, since the + * daemon holds them for its lifetime. */ +void hsmd_secrets_free(void); + struct hsmd_client *hsmd_client_new_main(const tal_t *ctx, u64 capabilities, void *extra); diff --git a/hsmd/test/run-bad-request-close.c b/hsmd/test/run-bad-request-close.c index 9aa51f04561c..ef0f04bb26da 100644 --- a/hsmd/test/run-bad-request-close.c +++ b/hsmd/test/run-bad-request-close.c @@ -153,6 +153,7 @@ int main(int argc, char *argv[]) close(client_fds[1]); close(status_fds[1]); tal_free(status_conn); + hsmd_secrets_free(); common_shutdown(); return 0; } From 40221d4bfc9d4bc9235a620e51a8da3770506bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 21:18:08 -0400 Subject: [PATCH 07/36] pyln-testing: mine the reorg shift blocks empty rather than deprioritising --- contrib/pyln-testing/pyln/testing/utils.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index 1065838c5867..e86a0aeba72b 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -612,7 +612,6 @@ def simple_reorg(self, height, shift=0): """ assert self.canned_blocks is None hashes = [] - fee_delta = 1000000 orig_len = self.rpc.getblockcount() old_hash = self.rpc.getblockhash(height) final_len = height + shift if height + shift > orig_len else 1 + orig_len @@ -620,19 +619,16 @@ def simple_reorg(self, height, shift=0): self.rpc.invalidateblock(old_hash) self.wait_for_log(r'InvalidChainFound: invalid block=.* height={}'.format(height)) - memp = self.rpc.getrawmempool() if shift == 0: hashes += self.generate_block(1 + final_len - height) else: - for txid in memp: - # lower priority (to effective feerate=0) so they are not mined - self.rpc.prioritisetransaction(txid, None, -fee_delta) - hashes += self.generate_block(shift) - - for txid in memp: - # restore priority so they are mined - self.rpc.prioritisetransaction(txid, None, fee_delta) + # Mine the shift blocks empty so the mempool txs land after them. + # generateblock takes the exact tx list, where prioritisetransaction + # only asks: some backends mine a deprioritised tx regardless. + for _ in range(shift): + hashes.append(self.rpc.generateblock(self.rpc.getnewaddress(), + [])['hash']) hashes += self.generate_block(1 + final_len - (height + shift)) self.wait_for_log(r'UpdateTip: new best=.* height={}'.format(final_len)) return hashes From 46409bf559ddc7a206ecd11f4333265fd3c035f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 21:22:32 -0400 Subject: [PATCH 08/36] pyln-testing: raise maxtipage so canned blocks leave initial block download --- contrib/pyln-testing/pyln/testing/utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index e86a0aeba72b..e9c17303c82e 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -483,6 +483,10 @@ def __init__(self, bitcoin_dir="/tmp/bitcoind-test", rpcport=None): '-debug=rpc', '-debug=validation', '-rpcthreads=20', + # Canned blocks carry the timestamp they were recorded with, so + # without this the node stays in initial block download forever + # and lightningd waits on it. + '-maxtipage=315360000', ] # For up to and including 0.16.1, this needs to be in main section. BITCOIND_CONFIG['rpcport'] = rpcport From 1b0f6a05a1c1c1793794e2316e860a7a4a4e2d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 21:58:06 -0400 Subject: [PATCH 09/36] tests: coindesk needs an API key now, so drop it from the rate assertions --- tests/test_currencyrate.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_currencyrate.py b/tests/test_currencyrate.py index 94a44f103ff6..33b9b4abd277 100644 --- a/tests/test_currencyrate.py +++ b/tests/test_currencyrate.py @@ -61,21 +61,19 @@ def test_apis_batch1(node_factory): assert "coingecko" in rates assert "kraken" in rates assert "blockchain.info" in rates - assert "coindesk" in rates + # coindesk needs an API key now, so it answers 401 and is absent. assert "binance" in rates # Death to the 58k gang! assert rates["coingecko"] > 58000 assert rates["kraken"] > 58000 assert rates["blockchain.info"] > 58000 - assert rates["coindesk"] > 58000 assert rates["binance"] > 58000 rates = [ rates["coingecko"], rates["kraken"], rates["blockchain.info"], - rates["coindesk"], rates["binance"], ] From da003ca95da5f4a48d4bbe744c20765ea5740ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 22:00:09 -0400 Subject: [PATCH 10/36] tests: skip the metadata test, its hand-made invoice expired in May --- tests/test_pay.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_pay.py b/tests/test_pay.py index 01b7bf9ab78f..f279fa0f1424 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -5327,6 +5327,9 @@ def test_pay_manual_exclude(node_factory, bitcoind): @unittest.skipIf(TEST_NETWORK != 'regtest', "Invoice is network specific") +@pytest.mark.skip(reason="the hand-made invoice expired on 2026-05-27: created " + "1648435974 with expiry 131400000, and regenerating it needs the " + "patched lightningd that injects the metadata") def test_pay_bolt11_metadata(node_factory, bitcoind): l1, l2 = node_factory.line_graph(2, opts={'old_hsmsecret': True}) From 3f42a69a13f57c1920913810d3c4adfbf7ad8466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Wed, 16 Sep 2026 23:48:43 -0400 Subject: [PATCH 11/36] ci: drop maxfail so a group runs to completion, as upstream does --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c451607f6d1b..20af434ae438 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ env: SLOW_MACHINE: 1 # This is for the pytest-trackflaky: # CI_SERVER_URL: "http://35.239.136.52:3170" - PYTEST_OPTS_BASE: "-vvv --junit-xml=report.xml --timeout=1800 --durations=10 --maxfail=1" + PYTEST_OPTS_BASE: "-vvv --junit-xml=report.xml --timeout=1800 --durations=10" TEST_LOG_IGNORE_ERRORS: "1" SCCACHE_GHA_ENABLED: "true" From b81e156a665c639690ec657a413a3b55bb96218d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 00:58:49 -0400 Subject: [PATCH 12/36] bitcoin: ignore gossip for channels funded before activation --- bitcoin/chainparams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitcoin/chainparams.c b/bitcoin/chainparams.c index 9ce3b05202a9..960513762093 100644 --- a/bitcoin/chainparams.c +++ b/bitcoin/chainparams.c @@ -51,7 +51,7 @@ const struct chainparams networks[] = { .max_payment = AMOUNT_MSAT_INIT(0xFFFFFFFFULL), .max_supply = AMOUNT_SAT_INIT(2100000000000000), /* "Lightning Charge Powers Developers & Blockstream Store" */ - .when_lightning_became_cool = 504500, + .when_lightning_became_cool = 961640, .p2pkh_version = 0, .p2sh_version = 5, .testnet = false, From 6d8b6fc24fb2da34d3a8a09c0ccebcf5d21558c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 10:12:39 -0400 Subject: [PATCH 13/36] tests: pin the unified hash types and the activation constants --- bitcoin/test/run-chainparams-blake2b.c | 38 ++++++++++++++++++++++++++ tests/test_unified_transactions.py | 5 +++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 bitcoin/test/run-chainparams-blake2b.c diff --git a/bitcoin/test/run-chainparams-blake2b.c b/bitcoin/test/run-chainparams-blake2b.c new file mode 100644 index 000000000000..fe50e7821540 --- /dev/null +++ b/bitcoin/test/run-chainparams-blake2b.c @@ -0,0 +1,38 @@ +#include "config.h" +#include +#include +#include +#include + +/* AUTOGENERATED MOCKS START */ +/* AUTOGENERATED MOCKS END */ + +/* The proof of work changed at this block; the chain did not. */ +#define BLAKE2B_ACTIVATION 961640 + +int main(int argc, char *argv[]) +{ + const struct chainparams *main; + struct bitcoin_blkid genesis; + + common_setup(argv[0]); + main = chainparams_for_network("bitcoin"); + assert(main); + + /* Gossip for channels funded before activation is ignored: that output + * exists for nodes which did not upgrade too, and its spend may happen + * where this node cannot see it. */ + assert(main->when_lightning_became_cool == BLAKE2B_ACTIVATION); + + /* chain_hash stays Bitcoin's genesis. This is Bitcoin; only the proof + * of work changed, so the network is not given an identity of its own. */ + assert(bitcoin_blkid_from_hex("000000000019d6689c085ae165831e93" + "4ff763ae46a2a6c172b3f1b60a8ce26f", + 64, &genesis)); + assert(bitcoin_blkid_eq(&main->genesis_blockhash, &genesis)); + + printf("when_lightning_became_cool = %u, chain_hash unchanged\n", + main->when_lightning_became_cool); + common_shutdown(); + return 0; +} diff --git a/tests/test_unified_transactions.py b/tests/test_unified_transactions.py index da0fd01468ec..2bdeef98f6f1 100644 --- a/tests/test_unified_transactions.py +++ b/tests/test_unified_transactions.py @@ -19,7 +19,10 @@ def assert_unified_witnesses(bitcoind, txid, minimum): if len(raw) == 65 or (69 <= len(raw) <= 73 and raw[0] == 0x30): signatures.append(raw) assert len(signatures) >= minimum - assert all(s[-1] & 0x20 for s in signatures) + # SIGHASH_UNIFIED is added to the hash type that would otherwise apply, + # so SIGHASH_ALL becomes 0x21, and the anchors HTLC form 0xa3. + for sig in signatures: + assert sig[-1] in (0x21, 0xa3), '0x%02x' % sig[-1] return tx From c0958fb10b849422ae90c89cd8b2eaaa0649ba66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 09:07:22 -0400 Subject: [PATCH 14/36] gossipd: do not pseudorand(0) when the tip is exactly num_blocks past activation --- gossipd/seeker.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gossipd/seeker.c b/gossipd/seeker.c index 5c5a6bbf1e0c..465efe1ac7bb 100644 --- a/gossipd/seeker.c +++ b/gossipd/seeker.c @@ -795,7 +795,10 @@ static void probe_random_scids(struct seeker *seeker, size_t num_blocks) avail_blocks = seeker->daemon->current_blockheight - chainparams->when_lightning_became_cool; - if (avail_blocks < num_blocks) { + /* <= not <: pseudorand(0) asserts, which would take gossipd and so + * lightningd down, once the tip is exactly num_blocks past the + * activation height. */ + if (avail_blocks <= num_blocks) { seeker->scid_probe_start = 0; seeker->scid_probe_end = seeker->daemon->current_blockheight; } else { From 40e1083e1bdcb68ec97d03675bddd7db73e7595f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 09:25:30 -0400 Subject: [PATCH 15/36] hsmd: fail closed after freeing the seed; gate testnet4 gossip too --- bitcoin/chainparams.c | 1 + hsmd/libhsmd.c | 6 ++++++ hsmd/libhsmd.h | 5 +++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bitcoin/chainparams.c b/bitcoin/chainparams.c index 960513762093..aed904f6164e 100644 --- a/bitcoin/chainparams.c +++ b/bitcoin/chainparams.c @@ -147,6 +147,7 @@ const struct chainparams networks[] = { 0x53, 0xbc, 0xfb, 0xba, 0xf2, 0x84, 0xda, 0x00, 0x00, 0x00, 0x00}}}}, .rpc_port = 48332, + .when_lightning_became_cool = 150308, .ln_port = 49735, .cli = "bitcoin-cli", .cli_args = "-testnet4", diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 172def0c278d..ee506c066940 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -2540,6 +2540,12 @@ void bip86_key(struct privkey *privkey, struct pubkey *pubkey, u32 index) void hsmd_secrets_free(void) { + /* Clear this first: the dispatcher's guard uses it, and without it a + * later request would read a NULL seed. tal_bytelen(NULL) is 0, so + * use_bip86_derivation() would quietly say no and derive the legacy + * way from the still-cached secretstuff.bip32, which is worse than + * failing. */ + initialized = false; secretstuff.bip32_seed = tal_free(secretstuff.bip32_seed); } diff --git a/hsmd/libhsmd.h b/hsmd/libhsmd.h index 4c34e4844d28..acb94c139250 100644 --- a/hsmd/libhsmd.h +++ b/hsmd/libhsmd.h @@ -49,8 +49,9 @@ struct hsmd_client { u8 *hsmd_init(const u8 *secret_data, size_t secret_len, const u64 hsmd_version, struct bip32_key_version bip32_key_version, u8 hsm_secret_type); -/* Release the secrets hsmd_init() locked in memory: tests only, since the - * daemon holds them for its lifetime. */ +/* Release the seed hsmd_init() locked in memory, and mark the library + * uninitialized so later requests fail rather than deriving from what is + * left. For tests: the daemon holds its secrets for its lifetime. */ void hsmd_secrets_free(void); struct hsmd_client *hsmd_client_new_main(const tal_t *ctx, u64 capabilities, From d02f73b1eed036dfdfde224df9231f715d0d372b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 12:48:15 -0400 Subject: [PATCH 16/36] doc: say what the activation heights are compiled in for --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43a135abba91..b92f369b2725 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Fund channels only from coins received past activation. A channel funded from a | mainnet | 961,640 | | testnet4 | 150,308 | -These are the heights Bitcoin Knots activates at, listed for reference only. This fork keys off the header itself rather than a height, so it needs no updating if they change. +These are the activation heights. Block parsing does not use them: it keys off the header itself, so it needs no update if the heights move. They are compiled in for gossip alone. Announcements for channels funded before activation are ignored, since that funding output exists under the pre-fork rules too and its spend may happen where this node cannot see it. The same height bounds where the seeker probes for short channel ids. ## Building From f688875113c7a4e52905a587ecc65891c9d31245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 11:16:07 -0400 Subject: [PATCH 17/36] tests: wait for the settled state instead of racing the peer's hangup --- tests/test_blake2b_differentiation.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/test_blake2b_differentiation.py b/tests/test_blake2b_differentiation.py index 400b8e66b6b6..3d9322527bf7 100644 --- a/tests/test_blake2b_differentiation.py +++ b/tests/test_blake2b_differentiation.py @@ -1,7 +1,7 @@ """Mandatory peer feature without invoice modifications.""" from fixtures import * # noqa: F401,F403 from pyln.client import RpcError -from utils import TEST_NETWORK +from utils import TEST_NETWORK, wait_for import pytest pytestmark = pytest.mark.skipif(TEST_NETWORK != 'regtest', reason='Blake2b peer features do not apply to Elements') @@ -14,9 +14,16 @@ def test_blake2b_required_peer_bit(node_factory, incoming, peer_features): {'may_reconnect': True, 'allow_warning': True}, {'dev-force-features': peer_features, 'may_reconnect': True, 'allow_warning': True}]) source, target = (legacy, blake) if incoming else (blake, legacy) - with pytest.raises(RpcError): + # The two refuse each other, but by different routes: a peer that withholds + # bit 68 hangs up on our compulsory even bit, while one that offers only 69 + # is turned away by us. Only the second reliably fails the caller's connect, + # since the first can land after the RPC has already replied. So assert the + # settled state, which holds either way, rather than racing the hangup. + try: source.rpc.connect(target.info['id'], 'localhost', target.port) - assert not any(p['connected'] for p in blake.rpc.listpeers()['peers']) + except RpcError: + pass + wait_for(lambda: not any(p['connected'] for p in blake.rpc.listpeers()['peers'])) # Invoice compatibility is checked with otherwise normal legacy features. for source, reader in ([] if peer_features != '-68' else [(blake, legacy), (legacy, blake)]): invoice = source.rpc.invoice(1000, 'compat', 'invoice compatibility')['bolt11'] From 4ebedf939d1345f7895dc707ab50d406d1e09b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 13:34:46 -0400 Subject: [PATCH 18/36] tests: wait for the failed attempts to settle in sendpay grouping --- tests/test_pay.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_pay.py b/tests/test_pay.py index f279fa0f1424..953eb53731bd 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -5290,10 +5290,12 @@ def test_sendpay_grouping(node_factory, bitcoind): wait_for(lambda: [c['active'] for c in l1.rpc.listchannels(scid)['channels']] == [True, True]) l1.rpc.pay(inv, amount_msat='10000msat') - # And finally we should have all 3 attempts to pay the invoice - pays = l1.rpc.listpays()['pays'] - assert(len(pays) == 3) - assert([p['status'] for p in pays] == ['failed', 'failed', 'complete']) + # And finally we should have all 3 attempts to pay the invoice. The two + # failed attempts settle asynchronously, so wait for the statuses rather + # than racing them. + wait_for(lambda: [p['status'] for p in l1.rpc.listpays()['pays']] + == ['failed', 'failed', 'complete']) + assert(len(l1.rpc.listpays()['pays']) == 3) @pytest.mark.flaky(reruns=2) From a955e9e89417e816adb0f9405b0c03c44da412fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Thu, 17 Sep 2026 22:59:18 -0400 Subject: [PATCH 19/36] tests: poll for the overgrind warning instead of sleeping a fixed second --- tests/utils.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index a760586d9a07..31ccc2a71a13 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -670,9 +670,15 @@ def serialize_payload_final_tlv(amount_msat, delay, total_msat, blockheight, pay # I wish we could force libwally to use different entropy and thus force it to # create 71-byte sigs always! def did_short_sig(node): - # This can take a moment to appear in the log! - time.sleep(1) - return node.daemon.is_in_log('overgrind: short signature length') + # This can take a moment to appear in the log, and a fixed second is not + # enough under valgrind or the sanitizers, where missing it turns the + # weight comparison below into a spurious off-by-one failure. Poll + # instead, but briefly: the answer is usually no, and every caller pays it. + for _ in range(20): + if node.daemon.is_in_log('overgrind: short signature length'): + return True + time.sleep(0.25) + return False def check_feerate(nodes, actual_feerate, expected_feerate): From 8be67a2347fa85b36f1db49ebbb3ac2ed43fc78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Fri, 18 Sep 2026 12:13:19 -0400 Subject: [PATCH 20/36] bitcoin: stop rehashing every prevout transaction for every signature --- bitcoin/unified_sighash.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bitcoin/unified_sighash.c b/bitcoin/unified_sighash.c index 97c0b1ca171a..0a14c59311f6 100644 --- a/bitcoin/unified_sighash.c +++ b/bitcoin/unified_sighash.c @@ -148,7 +148,13 @@ bool bitcoin_tx_unified_sighash(const struct bitcoin_tx *tx, size_t input, /* ANYONECANPAY does not commit to unrelated prevout metadata. */ if ((hash_type & 0x80) && i != input) continue; - if (p->utxo) { + /* Deriving the prevout from the full transaction means hashing + * it, and this loop runs for every input of every signature, so + * doing it where `witness_utxo` already answers is quadratic in + * whole transactions. Check the input being signed, which is + * every input across a complete signing pass, and otherwise + * only when there is nothing else to read the output from. */ + if (p->utxo && (i == input || !out)) { struct bitcoin_txid prev; wally_txid(p->utxo, &prev); if (memcmp(&prev, tx->wtx->inputs[i].txhash, sizeof(prev)) From 77da81118da784dd3d4416dfcc847e7c64d4b26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Fri, 18 Sep 2026 15:07:41 -0400 Subject: [PATCH 21/36] hsmd: free each transaction clone instead of leaving it on tmpctx --- hsmd/libhsmd.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index ee506c066940..e4805d113ee9 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -557,7 +557,7 @@ static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, const struct privkey *key, const struct pubkey *pubkey) { - struct bitcoin_tx *tx = bitcoin_tx_with_psbt(tmpctx, psbt); + struct bitcoin_tx *tx; struct unified_sighash_input exec = { .script_type = 1 }; struct sha256_double digest; struct bitcoin_signature sig; @@ -594,8 +594,18 @@ static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, return false; exec.script_code = p2wpkh_scriptcode(tmpctx, pubkey); } - if (!bitcoin_tx_unified_sighash(tx, i, hash_type, &exec, &digest.sha)) + /* One clone of the whole transaction per input, freed here rather + * than left on tmpctx: that context lives until the request is + * answered, so keeping them made a withdrawal quadratic in memory + * and a few hundred inputs was enough to exhaust the machine. */ + tx = bitcoin_tx_with_psbt(NULL, psbt); + if (!tx) + return false; + if (!bitcoin_tx_unified_sighash(tx, i, hash_type, &exec, &digest.sha)) { + tal_free(tx); return false; + } + tal_free(tx); if (taproot) { u8 tweaked[32], signature[65]; bool ok; From e757324efc2d7493a2aad6b8a37464ddbbebe26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Fri, 18 Sep 2026 22:28:34 -0400 Subject: [PATCH 22/36] doc: name the other chain by its proof of work, and Core Lightning by name --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b92f369b2725..46d29a95c1c8 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ # Core Lightning with BLAKE2b proof of work -This is an unofficial fork of [Core Lightning](https://github.com/ElementsProject/lightning) that follows the BLAKE2b proof-of-work hardfork of Bitcoin. It is not affiliated with the Core Lightning project. Upstream is still on the pre-fork rules, so use it instead if that is what you want. +This is an unofficial fork of [Core Lightning](https://github.com/ElementsProject/lightning) that follows the BLAKE2b proof-of-work hardfork of Bitcoin. It is not affiliated with the Core Lightning project. Core Lightning is still on the SHA256d rules, so use it instead if that is what you want. -> **Not audited. Use at your own risk, and no warranty of any kind, see the [BSD-MIT license](LICENSE).** It holds keys and funds, it changes how transactions are signed, and the feature numbers it uses on the wire are provisional. Read *Before opening channels* below. Everything under the divider is upstream's documentation and describes Core Lightning rather than this fork. +> **Not audited. Use at your own risk, and no warranty of any kind, see the [BSD-MIT license](LICENSE).** It holds keys and funds, it changes how transactions are signed, and the feature numbers it uses on the wire are provisional. Read *Before opening channels* below. Everything under the divider is Core Lightning's documentation and describes Core Lightning rather than this fork. -## What differs from upstream +## What differs from Core Lightning - **BLAKE2b block headers.** Parses the 164 byte v2 header and takes its BLAKE2b hash as the block id. A header announces itself through the top bit of its version word, so no activation height is compiled in and nothing has to be configured per network. Without this a node cannot parse the activation block and stops there. -- **Unified signatures.** Wallet transactions and new channels are signed with the fork's opt-in `SIGHASH_UNIFIED` digest, so a channel funded past activation from post-activation coins is signed in a way the pre-fork rules reject, and cannot be replayed on the SHA256d chain. Built on [connorslab's](https://github.com/connorslab/lightning) unified-sigs work. -- **A required peer feature bit.** The node advertises `option_blake2b` as compulsory, so it will not connect to a Lightning node still on the pre-fork rules. +- **Unified signatures.** Wallet transactions and new channels are signed with the fork's opt-in `SIGHASH_UNIFIED` digest, so a channel funded past activation from post-activation coins is signed in a way the SHA256d rules reject, and cannot be replayed on the SHA256d chain. Built on [connorslab's](https://github.com/connorslab/lightning) unified-sigs work. +- **A required peer feature bit.** The node advertises `option_blake2b` as compulsory, so it will not connect to a Lightning node still on the SHA256d rules. - **Downgrades are refused.** A build without unified signing computes a different signature hash and could not close the channels this one opens, so `lightning-downgrade` stops before touching the database. ## Before opening channels -The required feature bit means you **cannot cooperatively close a channel opened before activation** with a counterparty still on the pre-fork rules. +The required feature bit means you **cannot cooperatively close a channel opened before activation** with a counterparty still on the SHA256d rules. The feature numbers are provisional. Bits 68 and 70 are not registered BOLT allocations and are expected to move; an alternative proposal signals odd in `init` with numbers at or above 32768, and the two are mutually exclusive. Channels opened under the current numbering may have to be closed and reopened once the numbers are settled. -Fund channels only from coins received past activation. A channel funded from a pre-fork UTXO has a funding transaction valid under both rule sets, which reopens the exposure unified signing exists to close. +Fund channels only from coins received past activation. A channel funded from a pre-activation UTXO has a funding transaction valid under both rule sets, which reopens the exposure unified signing exists to close. ## Activation @@ -26,11 +26,11 @@ Fund channels only from coins received past activation. A channel funded from a | mainnet | 961,640 | | testnet4 | 150,308 | -These are the activation heights. Block parsing does not use them: it keys off the header itself, so it needs no update if the heights move. They are compiled in for gossip alone. Announcements for channels funded before activation are ignored, since that funding output exists under the pre-fork rules too and its spend may happen where this node cannot see it. The same height bounds where the seeker probes for short channel ids. +These are the activation heights. Block parsing does not use them: it keys off the header itself, so it needs no update if the heights move. They are compiled in for gossip alone. Announcements for channels funded before activation are ignored, since that funding output exists under the SHA256d rules too and its spend may happen where this node cannot see it. The same height bounds where the seeker probes for short channel ids. ## Building -Unchanged from upstream, see [Getting Started](#getting-started) below. Clone this repository rather than upstream's: +Unchanged from Core Lightning, see [Getting Started](#getting-started) below. Clone this repository rather than Core Lightning's: ```bash git clone https://github.com/privkeyio/lightning.git From 2e1b9cf65e330c9a2bef085349df282cfe3f82be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 11:28:49 -0400 Subject: [PATCH 23/36] hsmd: report overgrind from the unified signing path too --- hsmd/libhsmd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index e4805d113ee9..853431186ea4 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -552,6 +552,8 @@ static void hsm_key_for_utxo(struct privkey *privkey, struct pubkey *pubkey, } /* Explicit unified PSBT requests never fall back to libwally's legacy digest. */ +static void check_overgrind(const struct bitcoin_signature *sig); + static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, const struct hsm_utxo *utxo, const struct privkey *key, @@ -626,6 +628,10 @@ static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, } sig.sighash_type = hash_type; sign_hash(key, &digest, &sig.s); + /* The legacy path reports this below; the unified one returns before + * reaching it, which left --dev-warn-on-overgrind silently dead for + * wallet inputs and the short-signature case indistinguishable. */ + check_overgrind(&sig); return psbt_input_set_signature(psbt, i, pubkey, &sig); } From 31df114b28ca51c3b0260a176ecdb1261978bc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 11:45:29 -0400 Subject: [PATCH 24/36] tests: the onchain success path can be replaced, so mine whichever txid lands --- tests/test_unified_transactions.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/test_unified_transactions.py b/tests/test_unified_transactions.py index 2bdeef98f6f1..a8c423415558 100644 --- a/tests/test_unified_transactions.py +++ b/tests/test_unified_transactions.py @@ -218,9 +218,10 @@ def try_pay(): ('OUR_HTLC_SUCCESS_TX', 'OUR_UNILATERAL/THEIR_HTLC'), ('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US')) - bitcoind.generate_block(1, wait_for_mempool=txid1) + # An RBF changes the txid, so assert against the one actually mined. + mined1 = b.mine_txid_or_rbf(txid1) # Claiming with the preimage must carry the opt-in hash type. - assert_unified_witnesses(bitcoind, txid1, 1) + assert_unified_witnesses(bitcoind, mined1, 1) a.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC gave us preimage') err = q.get(timeout=TIMEOUT) assert err is None @@ -229,8 +230,8 @@ def try_pay(): _, txid3, _ = b.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_SUCCESS_TX/DELAYED_OUTPUT_TO_US') bitcoind.generate_block(3) - bitcoind.generate_block(1, wait_for_mempool=txid2) - assert_unified_witnesses(bitcoind, txid2, 1) + mined2 = b.mine_txid_or_rbf(txid2) + assert_unified_witnesses(bitcoind, mined2, 1) bitcoind.generate_block(3) mined = b.mine_txid_or_rbf(txid3) assert_unified_witnesses(bitcoind, mined, 1) From 2b85800608a589ab9915813266ae4561f754d379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 20:57:30 -0400 Subject: [PATCH 25/36] tests: the unified Schnorr byte raised the default lease weight by two --- tests/test_bookkeeper.py | 2 +- tests/test_closing.py | 8 ++++---- tests/test_gossip.py | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_bookkeeper.py b/tests/test_bookkeeper.py index de8b28c91608..1c0892ac6e54 100644 --- a/tests/test_bookkeeper.py +++ b/tests/test_bookkeeper.py @@ -304,7 +304,7 @@ def test_bookkeeping_missed_chans_leases(node_factory, bitcoind): open_amt = 500000 feerate = 2000 - lease_fee = 6268000 + lease_fee = 6272000 invoice_msat = 11000000 l1.fundwallet(open_amt * 1000) diff --git a/tests/test_closing.py b/tests/test_closing.py index 1adfdf592688..d50b3376d7db 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -897,17 +897,17 @@ def test_channel_lease_post_expiry(node_factory, bitcoind, chainparams): l2.daemon.wait_for_log('Resolved FUNDING_TRANSACTION/FUNDING_OUTPUT by MUTUAL_CLOSE') channel_mvts_1 = [ - {'type': 'chain_mvt', 'credit_msat': 506268000, 'debit_msat': 0, 'tags': ['channel_open', 'opener', 'leased']}, - {'type': 'channel_mvt', 'credit_msat': 0, 'debit_msat': 6268000, 'tags': ['lease_fee'], 'fees_msat': '0msat'}, + {'type': 'chain_mvt', 'credit_msat': 506272000, 'debit_msat': 0, 'tags': ['channel_open', 'opener', 'leased']}, + {'type': 'channel_mvt', 'credit_msat': 0, 'debit_msat': 6272000, 'tags': ['lease_fee'], 'fees_msat': '0msat'}, {'type': 'channel_mvt', 'credit_msat': 0, 'debit_msat': 10000, 'tags': ['invoice'], 'fees_msat': '0msat'}, {'type': 'chain_mvt', 'credit_msat': 0, 'debit_msat': 499990000, 'tags': ['channel_close']}, ] channel_mvts_2 = [ {'type': 'chain_mvt', 'credit_msat': 500000000, 'debit_msat': 0, 'tags': ['channel_open', 'leased']}, - {'type': 'channel_mvt', 'credit_msat': 6268000, 'debit_msat': 0, 'tags': ['lease_fee'], 'fees_msat': '0msat'}, + {'type': 'channel_mvt', 'credit_msat': 6272000, 'debit_msat': 0, 'tags': ['lease_fee'], 'fees_msat': '0msat'}, {'type': 'channel_mvt', 'credit_msat': 10000, 'debit_msat': 0, 'tags': ['invoice'], 'fees_msat': '0msat'}, - {'type': 'chain_mvt', 'credit_msat': 0, 'debit_msat': 506278000, 'tags': ['channel_close']}, + {'type': 'chain_mvt', 'credit_msat': 0, 'debit_msat': 506282000, 'tags': ['channel_close']}, ] check_coin_moves(l1, channel_id, channel_mvts_1, chainparams) diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 4abcf8e76f6f..a13189fa7c2e 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -1115,7 +1115,7 @@ def test_gossip_lease_rates(node_factory, bitcoind): rates = l1.rpc.call('funderupdate') assert rates['channel_fee_max_base_msat'] == Millisatoshi('500000msat') assert rates['channel_fee_max_proportional_thousandths'] == 200 - assert rates['funding_weight'] == 584 # Default on regtest + assert rates['funding_weight'] == 586 # Default on regtest assert rates['lease_fee_base_msat'] == Millisatoshi('2000msat') assert rates['lease_fee_basis'] == 50 @@ -1148,7 +1148,7 @@ def test_gossip_lease_rates(node_factory, bitcoind): rates = l1_nodeinfo['option_will_fund'] assert rates['channel_fee_max_base_msat'] == Millisatoshi('500000msat') assert rates['channel_fee_max_proportional_thousandths'] == 200 - assert rates['funding_weight'] == 584 # Default on regtest + assert rates['funding_weight'] == 586 # Default on regtest assert rates['lease_fee_base_msat'] == Millisatoshi('2000msat') assert rates['lease_fee_basis'] == 50 @@ -1174,7 +1174,7 @@ def test_gossip_lease_rates(node_factory, bitcoind): rates = l2_nodeinfo['option_will_fund'] assert rates['channel_fee_max_base_msat'] == Millisatoshi('30000msat') assert rates['channel_fee_max_proportional_thousandths'] == 100 - assert rates['funding_weight'] == 584 # Default on regtest + assert rates['funding_weight'] == 586 # Default on regtest assert rates['lease_fee_base_msat'] == Millisatoshi('400000msat') assert rates['lease_fee_basis'] == 20 From e551e0b2c4e48c0c4247f7e732fd4b44d7d89560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 20:57:31 -0400 Subject: [PATCH 26/36] tests: the two unified tests that touch the db file assume sqlite --- tests/test_unified_recovery.py | 6 +++++- tests/test_unified_transactions.py | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_unified_recovery.py b/tests/test_unified_recovery.py index 451dbb873180..1d402e25e2b7 100644 --- a/tests/test_unified_recovery.py +++ b/tests/test_unified_recovery.py @@ -4,7 +4,11 @@ import os import pytest -pytestmark = pytest.mark.skipif(TEST_NETWORK != 'regtest', reason='Blake2b regtest only') +pytestmark = [ + pytest.mark.skipif(TEST_NETWORK != 'regtest', reason='Blake2b regtest only'), + pytest.mark.skipif(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', + reason='deletes database, which is assumed sqlite3'), +] def unified_witness_count(bitcoind, txid): diff --git a/tests/test_unified_transactions.py b/tests/test_unified_transactions.py index a8c423415558..58393ecb24b5 100644 --- a/tests/test_unified_transactions.py +++ b/tests/test_unified_transactions.py @@ -75,6 +75,8 @@ def test_unified_unilateral_close(node_factory, bitcoind): @pytest.mark.openchannel('v1') +@pytest.mark.skipif(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', + reason='copies database, which is assumed sqlite3') def test_unified_penalty(node_factory, bitcoind, chainparams): """A revoked commitment must still be punishable under unified signing.""" a, b = node_factory.line_graph(2, opts=[{'may_reconnect': True}, From c0c4b9729d3ea4065b9378670cc96d1e3ede84da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 20:57:32 -0400 Subject: [PATCH 27/36] hsmd: build the signing transaction once per pass, not once per input --- hsmd/libhsmd.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 853431186ea4..7162ade4ccb5 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -557,9 +557,9 @@ static void check_overgrind(const struct bitcoin_signature *sig); static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, const struct hsm_utxo *utxo, const struct privkey *key, - const struct pubkey *pubkey) + const struct pubkey *pubkey, + struct bitcoin_tx **txp) { - struct bitcoin_tx *tx; struct unified_sighash_input exec = { .script_type = 1 }; struct sha256_double digest; struct bitcoin_signature sig; @@ -596,18 +596,17 @@ static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, return false; exec.script_code = p2wpkh_scriptcode(tmpctx, pubkey); } - /* One clone of the whole transaction per input, freed here rather - * than left on tmpctx: that context lives until the request is - * answered, so keeping them made a withdrawal quadratic in memory - * and a few hundred inputs was enough to exhaust the machine. */ - tx = bitcoin_tx_with_psbt(NULL, psbt); - if (!tx) + /* The clone is built once for the whole signing pass rather than once + * per input: rebuilding it each time made a withdrawal quadratic in + * work, and a few hundred inputs took longer than the test timeout. + * The caller drops it whenever it changes anything the digest commits + * to, since the clone is a snapshot taken when it was built. */ + if (!*txp) + *txp = bitcoin_tx_with_psbt(tmpctx, psbt); + if (!*txp) return false; - if (!bitcoin_tx_unified_sighash(tx, i, hash_type, &exec, &digest.sha)) { - tal_free(tx); + if (!bitcoin_tx_unified_sighash(*txp, i, hash_type, &exec, &digest.sha)) return false; - } - tal_free(tx); if (taproot) { u8 tweaked[32], signature[65]; bool ok; @@ -640,6 +639,10 @@ static bool sign_unified_wallet_input(struct wally_psbt *psbt, size_t i, static bool sign_our_inputs(struct hsm_utxo **utxos, struct wally_psbt *psbt) { bool is_cache_enabled = false; + /* Built on first use and shared across inputs; see + * sign_unified_wallet_input. It lives on tmpctx so the early + * returns below need not each drop it. */ + struct bitcoin_tx *unified_tx = NULL; for (size_t i = 0; i < tal_count(utxos); i++) { struct hsm_utxo *utxo = utxos[i]; for (size_t j = 0; j < psbt->num_inputs; j++) { @@ -676,6 +679,10 @@ static bool sign_our_inputs(struct hsm_utxo **utxos, struct wally_psbt *psbt) psbt_input_set_wit_utxo(psbt, j, scriptpubkey_p2wsh(psbt, wscript), utxo->amount); + /* That changed a prevout script and amount, + * which the digest commits to, so any clone + * taken before now is stale. */ + unified_tx = tal_free(unified_tx); } /* New wallet/funding signatures use unified sighash by * default. A caller-supplied PSBT can ask for anything @@ -692,7 +699,8 @@ static bool sign_our_inputs(struct hsm_utxo **utxos, struct wally_psbt *psbt) return false; } if (psbt->inputs[j].sighash & SIGHASH_UNIFIED) { - bool ok = sign_unified_wallet_input(psbt, j, utxo, &privkey, &pubkey); + bool ok = sign_unified_wallet_input(psbt, j, utxo, &privkey, &pubkey, + &unified_tx); sodium_memzero(&privkey, sizeof(privkey)); if (!ok) return false; @@ -1906,6 +1914,10 @@ static u8 *handle_sign_anchorspend(struct hsmd_client *c, const u8 *msg_in) const u8 *wscript = bitcoin_wscript_anchor(tmpctx, &local_funding_pubkey); const u8 *spk = scriptpubkey_p2wsh(tmpctx, wscript); bool signed_anchor = false; + /* Shared across the inputs signed below: nothing here + * changes a prevout script or amount, which is all the + * clone carries that the digest commits to. */ + struct bitcoin_tx *anchor_tx = NULL; for (size_t i = 0; i < psbt->num_inputs; i++) { const struct wally_tx_output *out = psbt->inputs[i].witness_utxo; if (!out || !memeq(out->script, out->script_len, spk, tal_bytelen(spk))) @@ -1915,7 +1927,8 @@ static u8 *handle_sign_anchorspend(struct hsmd_client *c, const u8 *msg_in) psbt_input_set_witscript(psbt, i, wscript); if (wally_psbt_input_set_sighash(&psbt->inputs[i], SIGHASH_ALL | SIGHASH_UNIFIED) != WALLY_OK || !sign_unified_wallet_input(psbt, i, &anchor, - &secrets.funding_privkey, &local_funding_pubkey)) + &secrets.funding_privkey, &local_funding_pubkey, + &anchor_tx)) return hsmd_status_bad_request(c, msg_in, "Cannot sign unified anchor input"); signed_anchor = true; } From 738a040f624ac8964dbd07da5ab84c9c9cf1e1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sat, 19 Sep 2026 22:10:20 -0400 Subject: [PATCH 28/36] tests: the raw open_channel2 must name a feerate and channel type this node takes --- tests/test_opening.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/test_opening.py b/tests/test_opening.py index 25dc332397fa..37557607f308 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -3196,20 +3196,19 @@ def test_openchannel2_inflight_limit(node_factory, bitcoind): def pubkey(index): return CCPrivateKey(index.to_bytes(32, "big")).public_key.format(compressed=True) - def open_channel2(index, chain_hash): + def open_channel2(index, chain_hash, commit_feerate): keys = [pubkey(index * 7 + offset + 1) for offset in range(7)] temporary_channel_id = hashlib.sha256(bytes(33) + keys[1]).digest() fixed = b"".join([ struct.pack(">H", 64), # type: open_channel2 chain_hash, temporary_channel_id, - struct.pack(">IIQQQQHHI", 253, 253, 100_000, 546, + struct.pack(">IIQQQQHHI", 253, commit_feerate, 100_000, 546, 100_000_000, 0, 6, 30, 0), *keys, b"\x00", # channel_flags ]) - # opening_tlvs: type 1 channel_type = static_remotekey + anchors. - return temporary_channel_id, fixed + bytes.fromhex("0103401000") + return temporary_channel_id, fixed + channel_type_tlv class SocketConn: def __init__(self, host, port): @@ -3229,6 +3228,19 @@ def recv(self, maxlen): ret, self.buf = self.buf[:maxlen], self.buf[maxlen:] return ret + def opening_tlvs(bits): + """TLV type 1, channel_type, as a big-endian feature bitmap.""" + nbytes = max(bits) // 8 + 1 + bitmap = bytearray(nbytes) + for b in bits: + bitmap[nbytes - 1 - b // 8] |= 1 << (b % 8) + return bytes([1, nbytes]) + bytes(bitmap) + + # static_remotekey + anchors, plus unified_sigs where this chain has it: + # an open naming a channel type the node won't accept is refused outright. + channel_type_tlv = opening_tlvs([12, 22, 70] if TEST_NETWORK == 'regtest' + else [12, 22]) + # dualopend doesn't listen for the disconnect, so connectd has to force it. l1 = node_factory.get_node(broken_log='Subd did not close, forcing close') chain_hash = bytes.fromhex(bitcoind.rpc.getblockhash(0))[::-1] @@ -3248,12 +3260,16 @@ def recv(self, maxlen): assert int.from_bytes(init[0:2], "big") == 16 lconn.send_message(init) + # The funding feerate is bounded by FEERATE_FLOOR, but the commitment one + # by what this node will accept, which follows the backend's estimates. + commit_feerate = l1.rpc.feerates('perkw')['perkw']['min_acceptable'] + # Fill the budget, and wait for each open to be accepted before starting # the next: that way every dualopend has finished its openchannel2 hook # roundtrip and is parked, so the count is stable when we overrun it. cids = [] for index in range(MAX_INFLIGHT_OPENS): - cid, msg = open_channel2(index, chain_hash) + cid, msg = open_channel2(index, chain_hash, commit_feerate) cids.append(cid) lconn.send_message(msg) while True: @@ -3263,7 +3279,7 @@ def recv(self, maxlen): break # One more open is over the cap: it must be refused with an error. - over_cid, msg = open_channel2(MAX_INFLIGHT_OPENS, chain_hash) + over_cid, msg = open_channel2(MAX_INFLIGHT_OPENS, chain_hash, commit_feerate) lconn.send_message(msg) rejected = False From f7dbf6900de94a5e2289fdf5de142a08a5a72484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 11:04:27 -0400 Subject: [PATCH 29/36] pytest: a PSBT carrying only a non_witness_utxo must not be fatal --- tests/psbt_patch.py | 25 +++++++++++++++++++++++++ tests/test_unified_robustness.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/tests/psbt_patch.py b/tests/psbt_patch.py index 48ef39794986..68d2f5f91047 100644 --- a/tests/psbt_patch.py +++ b/tests/psbt_patch.py @@ -26,3 +26,28 @@ def set_input0_sighash(psbt_b64, sighash): i += 1 # consume terminator; input 0's map starts here rec = b'\x01\x03\x04' + sighash.to_bytes(4, 'little') return base64.b64encode(raw[:i] + rec + raw[i:]).decode() + + +def _cs_write(n): + if n < 0xfd: + return bytes([n]) + if n <= 0xffff: + return b'\xfd' + n.to_bytes(2, 'little') + return b'\xfe' + n.to_bytes(4, 'little') + + +def set_input0_nonwitness_utxo(psbt_b64, prev_tx_hex): + """Insert PSBT_IN_NON_WITNESS_UTXO (0x00) into an empty first input map.""" + raw = base64.b64decode(psbt_b64) + assert raw[:5] == b'psbt\xff', raw[:5] + i = 5 + while raw[i] != 0x00: + klen, i = _cs(raw, i) + i += klen + vlen, i = _cs(raw, i) + i += vlen + i += 1 # consume terminator; input 0's map starts here + assert raw[i] == 0x00, 'input 0 map is not empty' + prev = bytes.fromhex(prev_tx_hex) + rec = _cs_write(1) + b'\x00' + _cs_write(len(prev)) + prev + return base64.b64encode(raw[:i] + rec + raw[i:]).decode() diff --git a/tests/test_unified_robustness.py b/tests/test_unified_robustness.py index 087358a2af6b..3f4bad207093 100644 --- a/tests/test_unified_robustness.py +++ b/tests/test_unified_robustness.py @@ -1,7 +1,7 @@ """Wallet signing must reject foreign sighashes without taking the node down.""" from fixtures import * # noqa: F401,F403 from utils import TEST_NETWORK -from psbt_patch import set_input0_sighash +from psbt_patch import set_input0_sighash, set_input0_nonwitness_utxo import pytest pytestmark = pytest.mark.skipif(TEST_NETWORK != 'regtest', reason='Blake2b regtest only') @@ -26,3 +26,30 @@ def test_signpsbt_foreign_sighash_is_rejected_not_fatal(node_factory, bitcoind, assert l1.rpc.getinfo()['id'] is not None ok = l1.rpc.signpsbt(funded['psbt']) assert ok['signed_psbt'] != funded['psbt'] + + +def test_signpsbt_nonwitness_utxo_only_is_not_fatal(node_factory, bitcoind): + """BIP174 lets an input carry only a non_witness_utxo. We need the + witness_utxo to authenticate the prevout, so lightningd must fill it in + rather than hand the signer a request it can only answer by dying.""" + l1 = node_factory.get_node() + a = l1.rpc.newaddr() + bitcoind.rpc.sendtoaddress(a.get('bech32') or list(a.values())[0], 0.01) + bitcoind.generate_block(1) + l1.daemon.wait_for_log('Owning output') + + funded = l1.rpc.fundpsbt(satoshi=100000, feerate='253perkw', startweight=250) + tx = bitcoind.rpc.decodepsbt(funded['psbt'])['tx'] + vin = [{'txid': v['txid'], 'vout': v['vout']} for v in tx['vin']] + vout = [{bitcoind.rpc.getnewaddress(): 0.0001}] + # converttopsbt leaves every input map empty, so the only prevout record + # is the one we add. + bare = bitcoind.rpc.converttopsbt(bitcoind.rpc.createrawtransaction(vin, vout)) + prev = bitcoind.rpc.getrawtransaction(vin[0]['txid']) + patched = set_input0_nonwitness_utxo(bare, prev) + + inp = bitcoind.rpc.decodepsbt(patched)['inputs'][0] + assert 'non_witness_utxo' in inp and 'witness_utxo' not in inp + + l1.rpc.signpsbt(patched) + assert l1.rpc.getinfo()['id'] is not None From 898e37d149263c8a1ed7ca16d669f0527874c4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 11:04:27 -0400 Subject: [PATCH 30/36] wallet: fill in the witness_utxo even when the caller supplied a non_witness_utxo --- wallet/walletrpc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 73342d526a7a..c141db3c3c04 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -713,9 +713,12 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd, fmt_bitcoin_outpoint(tmpctx, &utxo->outpoint)); - /* If the psbt doesn't have the UTXO info yet, add it. - * We only add the witness_utxo for this */ - if (!psbt->inputs[i].utxo && !psbt->inputs[i].witness_utxo) { + /* If the psbt doesn't have the witness_utxo yet, add it. The + * signer authenticates the prevout against our own record, so + * a caller that supplied only a non_witness_utxo needs this + * too, or signing fails and takes us down with it. We only + * add the witness_utxo. */ + if (!psbt->inputs[i].witness_utxo) { u8 *scriptPubKey; if (utxo->utxotype == UTXO_P2SH_P2WPKH) { From 5cdb0f8a33ffa70f5995fbdb51f0a0eff825ae6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 11:04:28 -0400 Subject: [PATCH 31/36] bitcoin: keep checking a prevout whose txid we did not recompute --- bitcoin/unified_sighash.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/bitcoin/unified_sighash.c b/bitcoin/unified_sighash.c index 0a14c59311f6..686920ee24d5 100644 --- a/bitcoin/unified_sighash.c +++ b/bitcoin/unified_sighash.c @@ -148,20 +148,28 @@ bool bitcoin_tx_unified_sighash(const struct bitcoin_tx *tx, size_t input, /* ANYONECANPAY does not commit to unrelated prevout metadata. */ if ((hash_type & 0x80) && i != input) continue; - /* Deriving the prevout from the full transaction means hashing - * it, and this loop runs for every input of every signature, so - * doing it where `witness_utxo` already answers is quadratic in - * whole transactions. Check the input being signed, which is - * every input across a complete signing pass, and otherwise - * only when there is nothing else to read the output from. */ - if (p->utxo && (i == input || !out)) { - struct bitcoin_txid prev; - wally_txid(p->utxo, &prev); - if (memcmp(&prev, tx->wtx->inputs[i].txhash, sizeof(prev)) - || tx->wtx->inputs[i].index >= p->utxo->num_outputs) + if (p->utxo) { + const struct wally_tx_output *full; + + if (tx->wtx->inputs[i].index >= p->utxo->num_outputs) goto done; - const struct wally_tx_output *full = - &p->utxo->outputs[tx->wtx->inputs[i].index]; + /* Only the txid costs anything here: deriving it means + * hashing the whole previous transaction, and this loop + * runs for every input of every signature, so doing it + * where `witness_utxo` already answers is quadratic in + * whole transactions. Check the input being signed, + * which is every input across a complete signing pass, + * and otherwise only where there is nothing else to + * read the output from. The comparison below is cheap, + * so it stays for every input. */ + if (i == input || !out) { + struct bitcoin_txid prev; + wally_txid(p->utxo, &prev); + if (memcmp(&prev, tx->wtx->inputs[i].txhash, + sizeof(prev))) + goto done; + } + full = &p->utxo->outputs[tx->wtx->inputs[i].index]; if (out && (out->satoshi != full->satoshi || out->script_len != full->script_len || memcmp(out->script, full->script, out->script_len))) From e08273be1b53d8ddbfb44868f661da61e2384f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 11:04:28 -0400 Subject: [PATCH 32/36] bitcoin: bound the input index before reading the PSBT --- bitcoin/signature.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 7717a8d7ba98..43b39878c536 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -191,6 +191,7 @@ void sign_tx_input(const struct bitcoin_tx *tx, struct sha256_double hash; bool use_segwit = witness_script != NULL; const u8 *script = use_segwit ? witness_script : subscript; + assert(in < tx->psbt->num_inputs); if (tx->psbt->inputs[in].sighash & SIGHASH_UNIFIED) sighash_type |= SIGHASH_UNIFIED; From 15ccef59e37c4768ec679390576bde1cbe6298a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 11:09:09 -0400 Subject: [PATCH 33/36] pytest: activate Blake2b past the canned blocks instead of skipping the test --- tests/test_wallet.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_wallet.py b/tests/test_wallet.py index 9acc96a4d748..734e09a589b4 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -2530,11 +2530,15 @@ def test_hsmtool_getnodeid(node_factory): @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") @unittest.skipIf(TEST_NETWORK != 'regtest', "elementsd doesn't use p2tr anyway") -@unittest.skipIf(TEST_NETWORK == 'regtest', "Replays hardcoded 80-byte headers, invalid once Blake2b is active") +@pytest.mark.parametrize('bitcoind', [False], indirect=True) def test_onchain_missing_no_p2tr_migrate(node_factory, bitcoind): """l1 and l2's db is from test_closing.py::test_onchain_p2tr_missed_txs before the fix""" blocks = ['0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f121ed0ffdd5a197230c7b58dd7512177ba827afeca6c2c82ecda3519566ac83d3d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002056e8e4767b39e3f2a4e98139da05354cc1430f6cebc315cdb3258f26db8cb67d29444f7b2b6f5c1fcf13acbbc101d29f0840f373cd16b85f1f92ed670614fbfa3e45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020a88aa9d26fa6e14d9019e8942e201ba2e4435d29fca4e30e84aaeda35b85f13c54d0cd7ee7880080019227edc9782d42d719794f995419197c254417c740abfa3e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d98753686d7d90f18a7fed6eef810e367dd4eb5d9c950d32b2735a151aa89e27ec5ca82ec5538a841fe634fc178f73247db5e17adb48913e55d33b1155b9df753f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ec249c91bf3f5cb46f48c14bee378bebf1591fa5ed15809c164170754a8f1e2daac112a6d9cd3e9c22a9b49142fc8314a7dffb8ace5bc9d7a273f9aba5ac18dd3f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020c257c44ac8551b3b238ea57d21944f4614ce6956065074f2f473a6df9718887ef379a56ccc20580e4774874c3e1b1120a1adae13a47fdc6004946f404743c6113f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e4e5a33bd5e84f1077de3843d2e480f7026e363872df300d5ce335208eea81537604d1903f67ddeeed3e6d9dfe107124b79d655d9c65c47a8baf97cee805d6793f45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000208a7461c453c09c8d3110e9b5dd3c5f438e3c760c9513655fe49fdf1edd4a4134f28bd7fc2be0d0719cbf109ff4aaf2317deb44c58a4f9131ffd87e06b150e5de4045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000204f54cb2bc317899e636a616175936910336da0f733ed0165dd6084e61210d075a1cb573f8c475e11e0abbeb593575ca8d35a8b902f36d725d93382041bf8f2434045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020dee1077d156feb2dac8be750ec1f6c0c8cc6148e98df6bf28e1f1d87369da70bc0bbbd7b242da54cabd90b3a9a10d86974615819d45fa3cb8aa97cdb488cc4ea4045e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002097cec18a4ef852e3d32e46ff8af809518e075dc050bc6d95ccf2c4ffee53dd51f429948b42f534e8adc8f9ce9ab5dff9d84b54c58085f78d7646ec99c9d8a5f94045e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202417a4c440947c1081326d24f4bfcd6eb4545759262603baf94a23befed47728756afebf5b153e8e609348dfa70fd288b0f981e50b37e08c51c9d5df6b53d4574045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002045a0ff48b45af0766329cecd5c07a912dbcdcd547facb15f7acb3af5241e011b3aa7271b58360c7ccdbfc80f01de88b822924701fb4b21315d6a20ad212c6b234045e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ac1719324f9032c419aa4a7d993bd9f1cf34e5fcfa3aeefc1554cf2a37cd5c2771b97403a26c5b147e04544bf0cdde758dfbb0634a05a17c00324a3ccd6619904145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020622c40d273474af2ee1afbc67777a1212b07132e07f7e89e462687131931e4601d42312ac50a0cde27393ffa2071d74f8995c6a4873a14cf968ccf7e8f654c3b4145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020f8d147ccbbec397afd787241fab2b4ebde4fabf72c808b7cafd87fd54a82ac71fd4d27ac7efcdac809fa30b7a8b4801b9fb69a11a3511ffc78aeebd2dbd8c6d84145e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff026000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020003dbb1e275d32254e34837b4c9b743be7d71f84779e4519a86ecf46fa6a5d506650b1d56c1a49a68206669ddfc0bafd899097dd4d1b8b31f6aa56afc7143c574145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e24ee6f5ca1e5bf5ddf9b08d9c63c51df30308debc631243e7244560ddbee524d781b8ec7c6585ea570435c1e8d61cb064db79e0e37a85db01517db8bc3db9534145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ee545b3b41992c9194459ea63cbca7c6a3079d9d160760856344390ebd76394546b9a9f1bc1060a127cfd6ee2fb00dd18e190d2fcf5476d229b026fe6ebd2a964145e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ce65af7fae3cc1191ba3520ce19e793d8747d6f70df4e29bbfcd830882c2e45688dd607cf34bd52a1f37837304b1345e5f9bf1ad901db0ff527d4fdabc7bb4f74245e767ffff7f200600000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020f1f2036de5c385f42e6c3da3b54cc94ce81527939cc1ec243387a3939d9fed7ef5e2d409cf025faf43dd43f120629d62a1f9ae8ef655dbb22fd2916ae51d32db4245e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002027f7dadd90d2f5cc5ae451e12702f37e2b2dbc5aa8f01af6399183f74cab8663901757e211691030c4fde536d26cb992a0c3c149822273cb2630cd20922ff2694245e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002072253009326feaa2cf0a87af69a071e0fdbdcb052f82afbc0708768d7e42e502957696fea9a86ad913c32972ee7e76047678d83fba95ff78e920954850d293854245e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020805c0de280de48b539ef2e656d013247c24a2f9e72b45ec0d35b9b0a67712730990b38c53dbe4b000aaf0f8fde41739e488a0651af1eafd0c8c1154462426e474245e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000205580a32fa092f795359ef4fd8cf5683135ab94d338906ac2ca30d83b9224885cb33ac2bef57fe7b7b62bcd567147749870481d35732426bb70b3d3e09cb03d654245e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002043b881c5077dd5c49c80cf652ab96265f045fb8a4160baa1a1959456f1365674f5b5545b6a08283699c2f648e8822b4bfa151cc92e85f23096091bb217bec00c4345e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202cbe3c8d54a8acbd395d3f34f794c608c594f2933187dfab5798ae884976ba126639f0d15b87f22b52b22a2db662dc18073d73278a9f03dcafa11deaaea393d64345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002052d8f545cd0cdb4098917c59f464bb06169f62100715c1f0e20261cc205a0721dcfa2b9623d8506335f6cfad8172e0a585f3d1499ff48ab09c63b4d8da17dc4e4345e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000203777dc93b80490c7d73c223d32b6f8e355bf4e1bc7682b126815dd6cf68c7402fc9ad8f5f17705057e81bbd26ee244b9919a66e493ba6d1f7b16a7ae742ef7464345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002029d7ce4e03327a016d967b82832c1821a451b6c32daaae8063ddcfdcbe3c396bb97d9802063e424e198b252f1b4e3ecb45f15425ed7b96082394a5a8ba37e16f4345e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000203223f332a0ca3da6d9f16400f2e301d043b028453b0be9d046ea1a79bd787919affb4d62e0ce40708279c7c89b450fa5edbbf036add302889c7746c52393bbfb4345e767ffff7f200800000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03011f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d740d4b227990a1ffd287929dc6d0c05b9a1da43f2c08bac3dc415921afcf86a52811ce56d03b94582212ef8338e98171aeffd0ca280898648031724074ef3654445e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ec7e7181e747198b39f3c6b031dace6cd4994a036082dd3e1989ecea3d01b005f6e35a9d2c2c9586dfeeb20a894ccc2231040e1c8576d9bd74d1ef4941ea66444445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000207d83089eb2a775b1c8dafc0af8118a20e0ea1d78f099522e2512c5355310fb5969c1daa9ed040c0ab3fe68ad802e637e69ffc777a8e0d77393a6049086e9bbe14445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000208c22dc5cdd4ac9dee3a7a1c20a2257c6fcea405f4eac404f7727d2848332da2ecb7f4811333231279dc6db9103df46e2452e1b995cf984240c3f157aabb581ee4445e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000201409a49dc6c1dcb74e1593d0df46e3c945487ad1c3e2cb3b3e72ba7bfe615d222be670b9cefbaac48b50e034dccd065606d5f4f1658dd4bcd8893e51586cc3414445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000203778a6471cd5892165f4ab9a06ec218e2e1ce24b9a705522b1bf6c2e20d5e9336ef2c5e22236835b35824f0a65b948e67e8f7acf612ae0c70a53e1b34da9357c4445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202ce848e935faeea98f38578fd04cae046277a2c2b8ce084809d0b38a22ca7f2745c08ea35070ca4b721625c70dbe78b9b0e5f981e9651450a27adbb2a43e5bad4545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000205c086ca4598faea39c90dee6a511201141351df9b30a8535d2c3505a18294d38221e9d2b65f07b51ea8ed1a7d033f6a3b22f9ff5a1c8a866d42b9a2a03b0cf3d4545e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202cbe285d2d66722078a3fd6a51db34dc9e33246bbf76c5a7d04d2208998ba6225d755a5811c13a18decbba116c392422dad2ba32d51581c0d0a4dd891a3081ad4545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020273b8d89d4c162df351089915bde50615b8e914fc158a97c0e38783e674ff36f1823c18340823c3a6b7f19ba786029dfb53aeca6cbf01235d7151de95fd5d1844545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ccf17cebf95ff2f44c4f64fb514614494ee15630eb87c279825462195e9ca1294270f349315dab92f1f2311297c70e5353c635d368ef1e8ce37bfe64b15e6ce34545e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b1b0c0ac7b9e1d2a3cbf43ddf6e0a34968735fac65a95a9db98e9211d5b1820408619e4c9c71540ad6b952d4c5224602fa45af3fec4bc3aaaf41661b09bd62e54545e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002040ef97fd829af29a9e0a2c4ec3327b71da31a58bae4a8b2c3b0b74426dd83022823f16e2ada411bbb6dc3ad9335572d5ce7fe0ced9e4c4b485463c4931073e494645e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020523d20de744cab12a12ac8c71bc930e65c88e15db6e0c88f9f68e4e97473d578e60e8fb9e3c50f5dbd70a9113fdf50ede58b0f25c8db3bcd6b0d7befb49d2ce24645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000205457d8f0682df35420c76853489f9b2d092ffe4a73bef96033216028138a0272a911ca2b3b45841c1eaac2df1e7af13c5b89fd2892b1594e24d39003a4027ac34645e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020a93b1446dad94fad245046d7777541a31cf75b3e1dc565c5899130b1627a6a65192c114e3cf1e91c337475804434f949a931bf1b55bea2dd5f4b698c7b92f84e4645e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03012f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020008db5f78bf19eb494df3bc95b4809f368d9f8c157affc76b9612e30061adb54de1ad09146535a6b0ef832eb1d79bfbb13784016c18258356ef67dd249574d3f4645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020bf876a730f6b15c3f766aaf96312efa1208778487b8dd4a3ed28d331ff6ff369192df6ed3a7d289b4c37d6fa6c2b63dbe1f4b2e4562e263e577a15f7d69278744645e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002039ba6324e15c56ca6590989bb1e6d7426a5c8cc770e967015bd01dcb4d2a95181132dfafa4132f447f63fb999726fea98767e887cf98a259ef7ea7fd07dbb64e4745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020cd1dce463cd6b0fa6ba3500d380a1327200fae56efec37a2c5e435ff244a65443f1024e9b6ce06b809df3ec46e4a834e80e934190d590b62b6999378ca93ef0e4745e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020a44cc61dcaf4738c637bf540680665364b71d1c71fe09089b9c8ef8cf68c9e2db0749b3331bfa43b0d458f46f01204781a44c4830f7a08c7c050f87c67ee441c4745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e61836b534a239642a830d7c029b85e1b1b754da2ce559e152d3ef2b60fe346b356fb9c2e9f571c39cbe561969058e889484262080fce71d7c6dc9851f91a41c4745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002068524ed04b0180e71d83fe6ae5efeb141e622de706e2b413b1862bb6df8fad66eef99ff3f436f643c8596cffd52f70254018b21839e10a4819e73d78a9fee8104745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000204d7c2f69eee5030e3e62cb3c4c498a8b804b5b048c7c460fee7421867bf6c5565f2b1ef4127dc4ad3f139362eefe24b7a28b00a446c093281920a0833b1b5f7e4745e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000203fb86b9c03e204833f4f2fa5d0bead1004ba4b0ebce1d41ec9a32ed76eefd54a3ce9ed4547ff51cb18c4f1f1e81d5275157b86852ca23e567aa970417c04731b4845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002087fba8d6923025aa62a03e0181231ae3b378fef2b91c705f74a28f66e0651255f13e4a7f7c478a7721d137ad8dbf356ef57d119e857123939a4506aed215d16a4845e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000208358beaeb2fc8e9275f4004e67a87bca7c5915dcda0dcafca2f8fe9f6a90cd6b07b5e8d76cf2bbdab39b4706587b76d2f2d0068a63317a6abc1f2538b1db3d4f4845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000209bcaa71b05385e5a0768fcddda0987e04751dddd5fa413b2be83f608f2f122610f94d40dc90ccca8e76fda5b7d0d49b4ed77fa8af29342a4a92e0065a531d2374845e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020cce44e08c9f2ceb0dc8c3243a9798b7d5e56177dab496beafc6c76cd179f1e69665c029fb980568403dd86b5d7ec77862abe828d0fb5ef02f28b5b4d373d2b054845e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202982c819e34a06d753f840e23f11031170bab285b319e859a6414e163f081b30afa2940431691af1258a548bd71477cf66c01c884c110da0d7e1c175568e41974845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d51d963aac276f16eda2ac14c9d229d9cc7f21edc5d6c84d92db757eb9cb491c6ee7239b57fc1ea359c2fd3c28292976bd095a6ac0e4540c7eb70c46de8339fb4945e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002088a273f1306813096a9870330f1a0db64db14ca501249d8d49639ac1a593fc4c804815be3e4114c5fffa96aad26c75cbedcbc854c8bac1ed3b3f9c16b13968e24945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03013f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b47c3ad1c5b0669701eeb6d04181e08f9a910d06b98153f6daa4eed4d480160a3d9bed639fdf277a9a768f5c3c71b220281bb24d77f7cf42ba38e2d432f641e54945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020a0ae01d6a9bccd9d4b014efa2808d266eeec9d76b597985711ab2f2d7300873b2e039380332fe0ee2922cfc85934546ca0487943e7bc3c1d053294a4e28d23d24945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b513e6b905f59ce167741ad3483c7a659bb66c28f0e893f61be48e7f1d0aa464cb52a1d2d0b7feb43e3707ab01883ecde8de9cd799d7b4554dfed6603e5a06784945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020cf7c32f21b0f8b5d1705027fce8a26e2c73233cc47cd149be4d5c87bdeec764eb03f8d3382d4dc3debe75cbda087b24367d7bbf843acd1759fd5f203d443f1574945e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000201366a9defec3e481f7d6b791bbec45586c8e375efa68a4d771ed0b9e9fb7a21b353d154182ddfaa565e6ca531324acc621cb9ee3b2286a075ed5921b02e5c03c4a45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e227ff11ff22192eb7b7e4e45e7701427af5e6d4d6fce1469cc31a0f702829044206ac1718f4bc2bf712402b4b73317a4dc81d193ffdaeae84514a690cbedb834a45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d49f5867985e23f97862c1335391d7070a7cd263565c9059a75d0a1ed33c4775731604dd425ce7ebec709b1c55ca1e28733ec589f024893ee02915964996e19c4a45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000200795c11d7aa402ab08599130953256038cba99027e992984c03f6eeb93532e6122675f9f5445b99caa2412d7a48d773813230fc5237a73851a7595e5eea813d64a45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000209461da337678c07e079d6bb700cd77ffa9ab6a17f983027c81f8fcb6120f8d654561d571492e2399e2cd0042ab552b33354c62642b489190d12d7a4e7c79c5414a45e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000204f28c8b5f7f75a74ee2c5c21cacaf34c4710e5d50104664d0ad6b21e6e90b570398c63d309b5fd1854ad095f2926a66692cbb0b75985648240feed65b9076e4f4a45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b34f81a7e63a3d553f7fcc75651bff5e399746363caf7ba6a515e6e81fe93c7309b05d9b40df1c48e5c0b4aa8093dcb809b8b9e95b695d6d00e4011744455e9e4b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002009239cc6231ba824fc9c84d25ff93ce4a1ade148eb58120bb6fe8e9694d948774d0507e1a56dd3cf62edfcd362a90369f9b553a4052bc2820d3c15d13bd964d24b45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e1a0dc94ff484b1350a1fc45746111bfed0ca796b59ce537c847da1376183b4b3eb2e6938000f23a4b353692532deab714a9a905968b8e45c8f29775974766f34b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020f838d5ebd5ecc3d149b449607e93eda3afb9ca40e5efffb275c7cbf3255bc53d097d2824834a9dd2bc4906f1c3abf0ebf62548119ec8c63b709ce6f86531121e4b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000203e70699fb54df9b478ef032f7c7910da732953cf9c4b46a10882834b15c147485124cbf07e1a19ef7db7c32faa907d2cc14f8718e3b2492274d8189aeebaa86d4b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ce17449ebc7d3ed89635861fbadf771177fc6e9f89fb8568fa5391902a6d3835d493b31b5885c4cdcf1bf0323540e51efcb98b62ef2df2a8e2c98fb4c515fe0c4b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03014f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020e6dfcc5f0d0a99cdbcfd9159d38d6f22ecd15a4d58fb15eba0a6ddf4461d22531e907738f76c083edb201898dceb5450c00d932d1b4f6df9ccd20d4aa06bdcd94c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000209d1276b33097ca1f167d668e58eb02f808ed5ede95ae0646826517df4db91b11a21c9e516a0340e59cd385f817e3c25669751463e060b944098eea334e2c5edc4c45e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002064ab992bf9bd6b892dc119c31bf8783a7e9f19762afbae9430e7bb12a89ffd5c61b085a1dd14d757a4a16e4d1913f2874db46586875e90ccb98037ef333d7c424c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000207a7763f9cb7a778a222acc4ce585f9b2f5f783c097ebec310702c87ef37ecf121b0d55802404b5ed763b48418273e9a3afb894f0e35f95681278956f9c3aa4af4c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020c94c950a983a47b4a710edbf815dc4ccf0b087734a0f26744f9a097a3a0cc96872eee5cb323b070ee052ed2b2dfa84614017e58d48a75f379cdd04487eab0a554c45e767ffff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002089255a3e8e9b7e76b5066a845ee682e5ed4241d51aa8788ec038a52f78760644abbe623aff5dea4eea5c5e6855f0d00d25573fb30d72b4b8767fa7f555f3d0f44c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ae3ddb931d73ed22b355c14f0c3349f7ab6c31fa56c0b6050b0c2717bfee7d374433c0b6cb0b30debfa8e3fef9328a43ef6f243d3c92b2a985a054770464abdb4d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015600ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020884d1649346a457132f5e752b2bd005eb83573eecf08bff4c0927519d9570d406cc13d704d9dea7f5c8ecb624e3f24fc0a2e75e7c6dbaab08d7f3c5ce315fe394d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015700ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002031b450c77ef3e50b3c356999d8e0732f053c2a470cfd20e016b067eab7ef916a0417caea9b477a95046067fda479ae367e63c3b521ef9243e3cad3e7f5606ac04d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015800ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020067c78e818d260aa51d34200106db04921a5c8654dfe11828a3e9cdd618da21896424aaee42438322942263255e7121bcda1e783b175af976f84b3d674172b124d45e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015900ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d237a92f2a860a1342b7c37c30fd05be47ce6c1344ddc295d8a12dfea21f3447cad7c3cb50788dfb9eecc6f316efb46739ce4ba4703997a3c54c75cc7f0dcff84d45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015a00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002032ceebc14e86191162c4d8ec3fcacd9d6c1466a93aa5092c8f4b1a126db70b260c2932b748d4548575c282f3c4b8d956f7e65fa493a2ec17aa09d943de964f094d45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015b00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020807fb3f557726ae5a8e246b06e6e3364b9460c2c31dbc37e2ca87763f176fd6463933d80fe1db063acc4a89a154acc892c6f5c13b3c4452f4d5ce51ffac793004e45e767ffff7f200600000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015c00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002035201324cc84078292547aa0a1e0ff7f8727074feff5e319b2dfbb2fe885c01a1d3d9d3494e4652489e3f18a76a52cd492b32f8d18f6cab4fdbd6f24a1b9e3254e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015d00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002025a80bb6b4aa2c98c18aa828586d51eceb677b8975029ad477a6cf05d23a7527cce8fd4e16c15fe2e80f4af5c576fcaeac1503979e7a51eff66ff2bfe53efa844e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015e00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ed3b675338a6ba59799594e985173060205e73d7b099e30cb78d1d3690a2c03fdc713a241d2c56875a837de27262273728110ca55174eb09f88203a845b7f8104e45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03015f00ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ea480607fa29df4d8ea8f8e788bb276159a8a61ba86ba14af483d651548e470156721b4da097ecb6ebc2303127ac2fdfe3eb1c00eaecef6eec40e498b17e00954e45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016000ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020fe360ca0152fecaacd045ca85a2bf08869cffdec799fdf64bea325b6532ad64227ce8d66be0c73025af9cfd24fc7245fad97357f8716eb38e8335f3a4e54c5c34e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016100ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ec427f7fb74c568fe04fdb414ffbf8b3c8b1e8c206a36024b012b057da73da690e62a987c35cfae251ac11f3d12957681b9a867bcd0bb0702d459a867ecd1d824f45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016200ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020245772e5852eb6bd20111392df098739d32b5b8a50377019787ece224254635563c6200669e2682bed224fd2b0bc68bf644af5098341a6ededf58a601d4fac204f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016300ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002047bd456d0d95607b24b0e927b639c8b7775803dedd7cdeb4b4a7dc8070179d271989230bf9b5397de410a9a294f7540c716753b74a7def0d00db84fef128af474f45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016400ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020de64fd4e9217b8456df1420b3effe314f40205800426a04070b71eabe9b2b3248290185184f3c2d9a243a1daddb4f17055a2749dbc0ab22cae7bfd791479f6034f45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016500ffffffff0200f2052a010000001600140544f594aa1610ff55e0797eeb4eb15cd07601cf0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000205ed61888928b352319efb1d85d636291a19ae45c55c4bd46f2a0f3d7a7512e71ad10099b91166668d725b5799ce29611347bf3118153be04971656fd3f0d35394f45e767ffff7f200100000003020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016600ffffffff021af3052a010000001600146a66b1bffe8368689cd695771ada2d78585c45330000000000000000266a24aa21a9edf9d7107703e8bc34556aee02bdc2c3b8eeea905deabf4e46a99528a5a733850d012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101121ed0ffdd5a197230c7b58dd7512177ba827afeca6c2c82ecda3519566ac83d0000000000fdffffff02f36ce72901000000160014982049ddf15138edeec1e5683c033ff8b63f7cc680841e000000000016001401fad90abcd66697e2592164722de4a95ebee16502473044022062107661a713637320a916de5a7eb7537706654f52188d286686741e7c9cf85a022063f0be207245a0a2a180c9ec2e2929dbb306ac3f115cef35d8f0148dbd0abbd60121032d8f3acac06981164dd33a38b5516f91520533c7746ab2f99279d48d1473d80e6500000002000000000101aa8b92c30cc63741018132abc34fc643c95ff6979390075c8670239c8da257410000000000fdffffff02e6e7c82901000000160014fad20f85fde37b24657a810c6730102e72ca699980841e000000000016001427213e2217b4f56bd19b6c8393dc9f61be6912330247304402201765295e2b53c15f50dddc82138e3190a98e368292fdc3d39fa77f2ef249a3820220253efe5c741e4531d9ca0414a65187965e2aca857ee152f331aac8893520c8a2012102529a967625c45f08195978925fa5b101d75db08a009f939e97d52ce9c7b74d2263000000', '00000020f5367ff88080f00f5ca8ba81ceeb5fddb974aeeb0eaf97c65f6fea352782b073a640a845f26e8cfd1e6d9e18a504cd871da0090f38b04066c96d30f194425f334f45e767ffff7f200000000003020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016700ffffffff027e18062a01000000160014a50a98c97a28195e9cab985d29218613ac9253770000000000000000266a24aa21a9eded976f675d4eaaec239ab7107adcd76964881d7c48cec52a265252abd224db9f012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101aa8b92c30cc63741018132abc34fc643c95ff6979390075c8670239c8da257410100000000fdffffff0240420f00000000002200205b8cd3b914cf67cdd8fa6273c930353dd36476734fbd962102c2df53b90880cd012f0f000000000022512063ffee4ea7d51e6cadf9086e286a2527922aaa25b8c53aebf32fa32a0a627f5a0247304402200b13d9931afe81cd1b80495552eb16c74d7be8d0aa2d81241d924f4f2936cc4d0220749cc939eee907b6fedaf1426a0473a12568bad5b531f463132eedeb53f15524012103d745445c9362665f22e0d96e9e766f273f3260dea39c8a76bfa05dd2684ddccf6600000002000000000101594101f10f4e99a8917d2254d2bb769d2c8dcb3dc87a18358daa3d16c2449bcd0100000000fdffffff0240420f00000000002200208698658a01efb001e1cc4df6a8b6f3adb461fa3e679385fdaae400bd73996b32012f0f00000000002251208a16c01895ce90fb7b33bede1ceb6e390d13e453836b33413b5d6c608037616a0247304402204f60d329a4189e60a4f836a8257e37c7c33cb015d7a2208bd9e32a9a301ecc0e02205ad318b476744af50545c4b0674108b35c1a14d5b6f4ac2a2e082bf81698900801210207ec2b35534712d86ae030dd9bfaec08e2ddea1ec1cecffb9725ed7acb12ab6666000000', '00000020b17c929516b801d383bea1afca1fc02d024943a484ec59800a277cc0268bc96b1e7ccfab9bc76f42e5c198f8aaa16a967fe1a612f9cb3350a3f5dffb4fdfe3f85045e767ffff7f200200000003020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016800ffffffff022c02062a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ed04db5647ee6c59935b0df8bb1753eff47e0d9bad2ba51b413ffd7ef5a62b32970120000000000000000000000000000000000000000000000000000000000000000000000000020000000001015124f03a8c61ace7ca9932c89982c34a2ae7153145ec168f96344a783e6e246f0000000000ffffffff012a3a0f0000000000160014ba764c66bc9632a09388cb9558d17f7257a0e9d5040047304402203282dc395fb1f6c5ffb10aabfc55eb0a0f67b8aaa43aa11d0ab28bb8c697ddee02206b6ebd704b7705aaccf93844b176489e45e5994f18983d66f555ea82c9509c0f01473044022057a2551b9122960fb8182044afabfef7e09858b02143d50d3239e333a0ff64a502200d2ac549bf0c2f34da42136fb6354f40efad4e6068acdf097152ace877c61c9b0147522102d595ae92b3544c3250fb772f214ad8d4c51425033740a5bcc357190add6d7e7a2102d6063d022691b2490ab454dee73a57c6ff5d308352b461ece69f3c284f2c241252ae0000000002000000000101090ddae2714f734ead0f10bd4daaf5f02d936e3a51baeb94e1e198ea1178198c0000000000ffffffff012a3a0f0000000000160014071c49cad2f420f3c805f9f6b98a57269cb14150040047304402204b5d89aa633bb2f374e96f223618fdbef3548d8ec76d28ca723568098c9ea79802200688707c3a0f10cb6e7654858644d2fea2c17e43419f912a1fe9efaa22a7f2ee014730440220509cc2e94da95888cf0b4fe7d39aed0caf8c534cb84d7730528bd26b942f5ab902205d224e589686de10ca75e91fb9cd5942a68af67db1b3e7413c47e7f2bd64430c0147522102324266de8403b3ab157a09f1f784d587af61831c998c151bcc21bb74c2b2314b2102e3bd38009866c9da8ec4aa99cc4ea9c6c0dd46df15c61ef0ce1f271291714e5752ae00000000', '0000002017dd07ba111707184f7e00f50b04b47b631f68131f2449efe7b48ff2a1b2045a86e925fd07fbc17df48648500fc93e29ea197f35f016a38e5c185007b5d2a3a55045e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016900ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020474f8bb6f27e2aa3328e239ec337c336ad0df73761af9093ebed74a8fec8020c37d1cb671915d13f14743540bf609b83eeafa289912d02cc64f0b1f20c32c23c5045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016a00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002040c0ceb4b1de3ce6e1480e26c050646706f7cd210a35a6fc77102f06a2763e291e8a81d503e40a0ef0d8ef3b928e91e07d6c339a5651d324c3aa4ae5d28eb62a5045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016b00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002024467c8a3801d4d43bb218b14fc55c9f63a898e8950c1d2dc9e48fdf4d090b5961d1cf953f7bb40cd75cc82955ff5a51f3e93bef270b2ac89b4ad53af07bc4da5045e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016c00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002009fdc4cb14d1a5add8d1c2dee11a1fce112ccf31e3bd37b0c0ec515a034a795392c4f42ee282a124f133d3954fefad6d76b674d1c47171ecf456d473c075c70b5045e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016d00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020398c9e3124bdf9e62ea492d0c992cc9b787c587d02f4b8c3f321f55efbf274728f2793a671bbfbcfc43b1adf3ecd29f2c4e53729dcd89ba3f7dc870fa3854dca5145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016e00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202ae1c7f5a9ed36967988734a4dba1a1166012c156ab72a430f8a9b8c34489f1532676376f9728fb6c9cf5d6372ec87d1deca0c0d7748d4051767dcd0b8a9b02d5145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03016f00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020c2d72e960af6f011878d1e1f8ba3ad36d2b0820e9d290108f5fbb536a3a3995c94cf21609e9f30c371f9fbc1c0802ade0a24421e88c12bfd5a4117f49456d8275145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020bc41fc0dd3fd525af0625a0e89ab4d171980916767a7f5a9b6e6914f19c7b22d128810ac08156d6219ddfc00f12aa66c217d1a3dcfee52ee8d6e968c66e1b7655145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017100ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002060c9ef09223ce6c7516ee7b54e6a62ce8bceaab5a35b0ec463e30760362db664e34f33604bacf782dbe6a167b9714ed252b0f0ca28b19630137a65e7d46522945145e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017200ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020be0b41d357fb6c22d5f1f0dfadab28dba6c37b072024d0130cb0e0ec1df51a2b5cfe5c8f96ede90782a17fab4838884ee32dec55a82d43a3c1849350b6b78bf95145e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017300ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b0a8bb76d1328d15877946845e8545b94702bbaddb838da7aae84968d078a009468c98884e153b97b6aa5e39f46fd59f96f1b277ecd4300da791a981a4d31e9f5245e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017400ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002012f958a63852535164f1c16d95eba199acb359e1c9b1bb80eb49073bf8a3f869a2757578fe6075d4f0c90d406da080bc88870571169ad2c90ffb366fe84346b65245e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017500ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b39ef61835e31ee4209a20c07d61865b5a6d06c97916a952ff649037a0655b1c7f8ec0b00bb7bf9eb33a363f88e3480ef24c13c1285999a9def57f3484bec9bc5245e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017600ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020dc1685373f0ef48e5099f4c8cd12fa9133f71b7ec23bc165922a793aaaf61645d9d5000644b3a00091235216393430d104d66aba13df66b4b757e4ed01cbcc1c5245e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017700ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020a112806a01c656db35fa021b979cc48c1e929c5e8c98e811aac194737d65755ae3da1393891cd88a50acc5f9cdd1868120b616072976dc47a7dba7191959fa265245e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017800ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020cbe8dbdbd5bfd9443a048e50af5705d958601d63c46d04cd81ec11b220a4406c86930557e168f12def307992b5cec2185a75a190634f3dd402f1bd485b8bd6705245e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017900ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002012a8ca7721f80a55db15cddf7370f43c4a60082f60defe3ddbe978bc4a2d125b726a244fb370c5fc0def3556c4d7d2e23e0b252cbcd88619b6afc3f2774fae1f5345e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017a00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020be154f6c75dbda8161ef8f4f259b1e296dfc3aad8f21c1980064809c7c7f966f0c621bb4fd1f62f2b163fb497a8d25f5e7fd058904d0363d652bd15bfb3df9e15345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017b00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020506a98d1afd6265b7705a80c338eeea9f7a24c946124ea96d23aa5af79bf1f3e04de253c09d40efd70920e73f1d14a34463dd0969b24e0a092f71177e6f7d0855345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017c00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020178d05c02adfd564a4a2d1b8934c1cc72e6b61b3698194f58e5a2d171645d32c8043d16a43c399985018abc0c6f8d7c73c2ed226cbd523c0d4aeaecb42a4801a5345e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017d00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002035bcbd7497b0844507eb20ac1031c1b373e20d183184bc95bac48b175e74ed571c671387f330e37f64b7c5c507b183516cd8d12d387f6a44a72d5b1d43cf39d65345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017e00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ac9c82e0e6b6669634df96486c7c4a2fe343e2cf18d55f5949c669583391b0647ac43806dd5ca67b39293ea22e64b783d682099b3641adc84484d50dd08f2d3e5345e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03017f00ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020b318b5efbc31fa277c36f8d0e3d7b3841e6fe60ac26a0170236176a7fada93082849a03ae5161a917225029da51529e6ef8b92807a58ed6cc4b8c18bdbfa08935445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402800000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020959448c7dc9e5d511787aa9fe79a86511f22fd855872c5f40608ea7a3234684b5c541667cbc697855759573da2ba21bd77310dbf0671e7a2ea34260ffca5d6475445e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402810000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002063251e8e655ac6552b816b04e63a2b7a2807e71586d1974eb7ffdaa84507ed5e2048dee1eae334b48e2f1a125e47bff73cb5a280091849a739a73fda601364805445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402820000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000209792edd5fbb152812148da53084fa2e83a0b4cabbebc02d5e364ad15bdcb8038f0adf65f81bed42b6a9eecf6342872096144c3069bee6495195ed6a41249e77e5445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402830000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000209c8315e2c8c0510b76fe60854466a707d5a52f7df8538dcdc328f1db3b58ff6af12015d5a9bfe4c853f98fe35662f4782f5e0e8781bee16111e8653feb460cc45445e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402840000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020d85967913da39f5ac0e163f89795fb9813e9efac4af9cfde9d151d3e0b977958bbe91e6e214cc1ab3805b095d5a7ce176b86506fec47a673b082bb3525511ad55445e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402850000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ce1166ce40402ac786ccffbb3911c75155afe5b3d702742ac074794874772e1e9cf442623955f5f51409d259e0f112c64a751e01ff7264286a4a3c76310d17125545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402860000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020112af4801eca6be7c1d5566c35d86e42ed0c7a93776b5760c91c093571f28a24399ae96bed6df9f309b68e970529c117f2f78a812b6505881808709550ed94b05545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402870000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002017f7440e212cc64b1d343535ccce03d20a13d0bbcafc0730bdf890580d46df0c98c6cce0b18b45275a19543b192802f4988c168c8513ab56f5854f1cdc9457ed5545e767ffff7f200700000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402880000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020818d56a56b89301c1f81c7b73270ff2dcedf894d321b266e38a961c99caba438e70e2d41ac032e66e4971ba77c376073a1340e91d283726e616d0ff4a55f2afc5545e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402890000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000202005fdbbe76ee95acc24295138937f5a92144985e74b876b1fadfe68cbea05362fd13b52114f537b6008c46927374c7d0da1d5ff90efdf9091a6980d0dc02f555545e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028a0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020c205b1d6c0d3e58288e396850a6a4b1404ba6b4eeee25fc13848c61e3629485ab9e4ad251e22f3f2b3ac3ffbe1e3ddaff0f914894c30152d57b38c764a2621685545e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028b0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020ae9a8ba221d8d9adfd4d04557cdcb4e8069cb814f70f76a150b5a7a23f2506044468febe96990db1ceb20754b60e2bcda1ae6910ce62bbadcdf80e2a0fd7c74c5645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028c0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000002080b8d3ae945f5a1717b34a545c775d24786d1d1b14beba3021a3c9fd40eae20258659c5e76303059e26da6ab80ece214d536bf7feaa6f33cc13a8aa8d27020f65645e767ffff7f200800000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028d0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020f0da206c7f7c3f8e858ad849dfe920ec002d533bff3ed8bb7baa52287d44790bc81675085e4bde33c31e88155a821cec9a7276fd70f86fdd194dbe1c6aceb5dc5645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028e0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000020c2b7db111cd824b485db60706e14b8148b84f52011a6c5769878933c5060eb40aee9d7480c3a9dd888b6cbef15de3d8629ff1785f1f3c3a34d00f79359202cfc5645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04028f0000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003041243723cfd31809ea5d27f36335806aaf8ba2e94e830b1a6f1f1a75cdb6da1c2d6ff82369cb5e9796ea98a9f0c62027aa1dbf79a290bbbe6cda734eec79accc5645e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402900000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030399cb0cbb9cd70b52b4b3e474a977e746910fcdb2331fc9d9c8a0c7f73aea608648f749194729b1b59a96e14ff44f0dff68c507356497fb5494b826f0a1ed5605645e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402910000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003081bc77107b5f564b5a9932c9426ada1904537f4c6b5b44937c6c482cfe9d6d5bf1fc1d6314bc7f54d7385c08821c3cf018c42c2d9ca7cc550519e901597035dd5745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402920000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030c971d8e2d12d0c75bc4f32a82c0885062fdc0458be380fd3f062a9531bca7f50cfd4723752ae9a144dbef60dad39c2d96dc9ba90728b5e72d843de1408c706695745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402930000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003062a4e5825ca5494f99f5a1f18f7ed53aa0fbb95f09d114591e3ba7d56164e61167e814795233e88c9f8e89249d1b03b5ecf383f53caea23a57b782c1a2702a035745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402940000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030839daf2a34725eadac848f28becb2f780ecae6ee515e208a47252555dd2cbd2505fec8540c7295f26305ef8228fe641b31ff3e211c324b627beef19070ea55065745e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402950000ffffffff0200f2052a01000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030e538757582a20bb1a8057dc94d7f4bcedb61f2bb53352b1dba1eaf1aeaf6f31471acb322f6c6ad997f0f099c49ab5b86bdc1794c84d1cd404a94e3d8755dffc25745e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402960000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030f8f0e1a4e5404270428fb68ddc09d092746aba6b4c39acef662d5ed4cb2a88080906f2966780605159145193bca4e3222566a00bf3b3f5dd4b7316bc877947185745e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402970000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000302d8167258ed66540dfa5ba5880743b94de8ab83d27a7a6b7cb7050ee592acb47bd34d45c6583b4343529e80ef4ea69b987b3067ca230efbb372aa39017f6f4d35845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402980000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030842c80a35ab51a45c31e10db8a54f6b67795a7f016dead1edeac77ffc5c2590123159a9672cc09f89e9c1d82babde1b5faef2a55bd73b8ba9d3a017dfc0b1a305845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402990000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000302a39a59278b6d7bbb585c939cae3a0cc05a5ea89f23f4c65afa72510f7e0477fdcd559186a927939f96c4486240318c4e8dc0e0097eeab39fe6bed4153d9d96b5845e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029a0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030cf3db2b72f837d5861ffbb32424a9292f8d74db5e8d86d02a5a6c772f756d64437b9bb82b46d3757d1373519e3c87c393948b81b4335f57df9d21e7c4dad02b75845e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029b0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000309ec59b0696e186d1b93bc8f3fe4ff47ec625528f139ab1e1872136574ef44c7e35c844a2ccebe0d6f31831bfccb377d79c1b87bd04e3a99a51ac5706d0de5e045845e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029c0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003000595b83332c77133287b13c57587c1d26e761aaec3fb2ae08fd7086005e285494d1ac097c6d6293bbbb4781102d1a853b86982a56f3e2667eeb37f1da79a7ac5845e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029d0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000304ed33349728239cd8e2450d372b009c2c39629b9b7051832e836449a2fbcb2204c07a4fb38ec0bc0a0870c7e5892ebb0bcb89a1c84c2c4ca39f31c48b0bce5695945e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029e0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000303a1cd4c9e9dbaaada0692df47668ff0f9afb664b27a397719771dac6cbcbe310fc882af8e2f021f3c3a03f585ee8c4d588d804c207c368528075fef3ec495b235945e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04029f0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030bb938155e78b937df5ce511538515abad3d12daabba0ce20ede9b1c7a332105ec0499736f903d1e7d217a3c7ffb6bbc52ee2440013d259877ea1783825f843d85945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a00000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030662040ff51f64777f7494d20347fbc1e57de01577c504f2685925ee5d8942c5361935420a0b607d4857eebc67aa8362a4a004c8178ab4b89dece24c619fabe9d5945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a10000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030024b6383f4faaee8a46abb46153916a4db66791e76b4cf755d2484b25737666f43d8c328003f5a2e31f2644430e44aa3b126ba1b50a9c7908855a6b8c417c5b45945e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a20000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000303d9e4b3cf26d748a7bc0b51d75f47b698caa5d49404df8c7a36960422b469a5477d2c7308de83f064016d046c2cc2dff8b1ba2fdeefee2766b5387a66be3141d5945e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a30000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003016821fbda3a7813aabd2eb519f4625724b36b51f79814477b92fd7c458a2ad63e6ba0bb30c9813a3654c24bd3b1fc547ebe0b1bd6d2ea91f1e35b4822c479e4f5a45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a40000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003006c9cc8172034c14a960a3fe23ce4ab1623396307c4e8c93673946717a484d7fe5755b64f4a14b92ec68e96369a646d201aa9e9bc2d2311b136edd517b7677bc5a45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a50000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030a4a711824183601892260b060d90cdb8689039ec511b4785f5ef30ffa4b2e025f2ccbfbbdfee7808cbdacd7bec4194c9f13b94fe5ddebad1a86450f2cc93a25e5a45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a60000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003028d1ee846d8bccd01719c99e0def4f1f4a86df320a508fbb6b320241a9a7087ace4b6680134bbdf63822a4d3197613c8ab1aa897988960375cd9302249ebfe925a45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a70000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030ae7ea95fa9b43b206738c45c605a6611d5113f7b754a995e3f87c2dd10ff786360eb90fb2524f3be5fe1faef5dac0da7ace6f171ff566d3d54bbaf45b49cb70d5a45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a80000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000303ebcbfbbda57e0fc821764a8534b1e4c02450ed7262f809577722d46f7eabe27525b7a346619caafc949d4e2787ac4cd1ca35c0df75d5dda7560ab27709bd2ca5a45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402a90000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030ee947752312f9115ea79a5187ba7c380af515b4b2754b229ada6794f7e719e418ee958de6ca1dddecef8fcc9ad765f3d2cfedb34f52be875ffb3fd9e20d0dd725b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402aa0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030ef06d81b99c621541533f4804f7b8645270bf69c0bc594e73453e493cb0b8b29165d399502a3d21cc1abc525a4f9c8be987c97913e6a4cb3a07f2cad962b3fd05b45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ab0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030c7dfee6970ae91486edc4415eb99cd03b8f0c3f36926915db7f01b13c069d027ec3f893af889af4cf417eb67065fcec3b58c54bc59f133006991f468e0cb94655b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ac0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030a456e513b80f842e98deced1cd507adf8e464d6c7504f1eb518548fd8dbce40c35ee412935da982bf45a17fa0f1b03dbbd43686323f4c4fdea1d24de09b948c65b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ad0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003076c26c3d94b09fda94f8d4e4281fe2fdc37618a324c11425befa5c1765919d37dd4640708b275b107d6f73c72f787d12498f0737326f228eca5dea4da47d4bc85b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ae0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030472c1af61662f83a21a4c64667e9d51ae0c58ce01c901878de3f82a9c953f1154e921ac66b4ef47398156a1221c17fc807ee716b3b145d4f3e52c0e0f4a6f3235b45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402af0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030b67bbc468af152cad458eebd674ebb426df002501dced9d768b1259e564645028c022328bd4acd790258e727526e6752afb0e712ac648abde199e0a3304d57f05c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b00000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030200621e8e33ec97e867f3ea1cbffffd3f294bf8fe1cf0692d0057ea2b919ec36221e35c58a2ac55440ee09bc9f0e311f4fb663f0fcfc0eada2600677e469401f5c45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b10000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000303b8b015859940691059a2e954c53204e85afb3a4ae1d32ede19971aa5d2fbe52cfa4ba2177ffb2b021c30320f89d0f910bf44efc07067114335780ba3f10bd765c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b20000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000304cfa59583423a05b452d15b985c2be9d3df88fcbdd031f96e8ad9d51e9b2b3441beffcee4d4c244e1e4ce7094b31646c6cc5567129082046627bb39e5310fe3c5c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b30000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000301e1e3efd764ddc5011f48108e89a163d50f50e29a377580507d803539fe052071d1a673c9b262898295d243626f5877b909d4598d91d13c75f082224bbb1b9055c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b40000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000305bac3ad01b70bb74f6c49063e1b818d39ff3366eddac4f7be9b2684883bca74bb6297f1767ccd20ddc3214e45b31ae868d15b520f05e4bd67b88ad28de08fce45c45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b50000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000300d7ca8158d5fe3a982b452b1d60315e32a92ee4d31b8dc3dcbe133333077c97e2758023341f0424bcfd5ab9940df921e88daa2aea0a13cb84aa6c4ec13d532015d45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b60000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030cce8fd6ca01c2112d6f6a0e2052002e9f71cdefff9b6cdf76547cb1f3a46af615f414285c888f66d5d6240b886287726ecbd5921b13acb2119e67805bb2d56705d45e767ffff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b70000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000301f0040ea70cf5a01e73546e86abdf30ba200c075968052b5e4418230d4acc44be05fec05e27d85f08438b0eab8a752b9b2733d922a377264c138ff059374bb595d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b80000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000309670a5b4400a07a83489bb2a1d24f4210417eebc39cabe880d2282ec384eee69b2735c7af36ee348970ea85cb9190bc48815a9209eccc537bfc54794cad6a4b35d45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402b90000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000305e6e7740529202f83cd844d3e0189d521a67334e96d356ba52525ff6fda3ab0c5483d2e59b5c73967fb844c59f96072098276b058a63d065830a3ebb4d4123595d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ba0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030474f309999d613e1de4e2b3ba181c0d2e8ecfa4d8310bc16094f9cb6d92e514658b16873f8d004be021fe039cf789ac456478117c7a6919c54a49ea6729d3e1c5d45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bb0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003046089a2183b7b8419ac72919206d16b699975dbd85d3a4e34773af3115e21f30753e4df9a3a59c8be175866e7308443f2013ced01c7d6bdb7edc9bb850b9c5325e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bc0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030bd0f28f06326941da6fbe578d7ad7549a37889ea6126471d7314de01eaebab21d6810504e2f55e89ebc0865310c7f1f1d55bf0b806825fa82787d4348141ec875e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bd0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030a18d4637819250c31886aaa3ea89f7aff41855a9042340cf60b4b9456b6e7742b00fe5bd78b3a32c9da95eb99b7abfcb592a76cf8b34761c485342eb700b24185e45e767ffff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402be0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030e9cb81ab54178bda14a8395e8f294c16d6e907e05b5f6b67f9fa79b4c7d0c86c33ed95c62e55c6235eaeb393d8ee6d426d56bf5b7d0d1190a8de8574524c7a4e5e45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402bf0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000309c90bb876b7f9a8cf5f162c4d9ac5a2ba20d65aecc65d3c5280de23d71acb57148c0ba0114bdf595a5c9dcdebcf922d46aa1057f8075e2168b3abe4d04ceca5d5e45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c00000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003031d701667675f5c9e2a8c143408dc074423d19ad6f410151972ee601de19921b2c4997f71d7d702720598f85730b126d66ddaa65a325ec75cb64bf865bb3f9d75e45e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c10000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030ec1b69c90796b5e7dedf4fac5bfaa38b08986a024cc81e252399d01452aece1ba9ae7a787e60e96a4ec00df22d513c2ec3b6bcf2d819a62b9a69fd4c16ae0ebe5f45e767ffff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c20000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030da4f5e26be854bcccfc3efe8bcc969251f9210ba7642fa7f531e70958ce1a53a2cd0938aeee842232c01f13e465fa19e1017b4e25401a3b512e284516675ef755f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c30000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030598fd05ef23fcbcf7c872b0c748c292874948c6842585d2419a6de5fabd15c1560018fbc99216e9e3cda1a7c1229975ab8228194bb4d4b2a9d5b1fc9792644325f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c40000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003039fbb34ad9e86a1ef54a9f7221dfd6aab1a9a93911baef457068d1c3880c594234b10d41685b1ef92b9a171e4e004f3d70d8c5b9b26c2542f96bdc5a292698ca5f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c50000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '000000306a39d1647473dc49f0e78278335dbc0418d91904ce473d824e66573a835b2d0262f7e36c68ad0debdcd31faa63810dc891834c0b8f136029a2c10d9ecee526175f45e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c60000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030253aee6ae859e35bed50d0b4e74463c3c30cea7c484f108379af5e00888bdf222a7169c0bae73b50004b1ad14d968ee0505a5ac40c1400fca17978b5479329465f45e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c70000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '0000003087e40026893cf19f73bcdaacb2adf1c5cc544abc2cb8ab7af4a3943f94d01a35578955ee09ebfbe14d75345d4d61499c39817542f32c18f2dec4006ae9ef5d8e6045e767ffff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c80000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030bea2746a48f9ad44a4857546914e4402c62d338e4b1e62699a0175da681f4a0a201e6181e3cddbe84b0b3dca0f97154792ead40dd174f4c5bdaa4574dffec38f6045e767ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402c90000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030ad9a4d078baf27e222db419923bff2844fb2bd947951b71d585219c9d49f075304a69461d2decc1155ad72a3e725dd4ec2f321cb13f07a8815349cccd379bc0b6045e767ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ca0000ffffffff0200f9029500000000160014cbe7f8ee3e6133b9f975501d7fe827f6915ec0910000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000'] + # The canned blocks are 80-byte SHA256 headers, so activation has to + # sit past them; blocks mined afterwards are Blake2b as usual. + bitcoind.env['BLAKE2B_ACTIVATION_HEIGHT'] = str(len(blocks) + 1) + bitcoind.start() bitcoind.restore_blocks(blocks) l1 = node_factory.get_node(dbfile='l1-missed-p2wpkh-CLOSINGD_COMPLETE.sqlite3.xz', options={'database-upgrade': True}, old_hsmsecret=True) l2 = node_factory.get_node(dbfile='l2-missed-p2wpkh-CLOSED.sqlite3.xz', options={'database-upgrade': True}, old_hsmsecret=True, broken_log="Potentially missing 2 outputs from previous closes: scanning from block 103|Rescan found [0-9a-f:]*!|Rescan finished! 1 outputs recovered. Let's never do that again") @@ -2696,7 +2700,7 @@ def test_unspend_during_reorg(node_factory, bitcoind): @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") @unittest.skipIf(TEST_NETWORK != 'regtest', "sqlite3 snapshot is regtest") -@unittest.skipIf(TEST_NETWORK == 'regtest', "Replays hardcoded 80-byte headers, invalid once Blake2b is active") +@pytest.mark.parametrize('bitcoind', [False], indirect=True) def test_rescan_missing_utxo(node_factory, bitcoind): """Test that node which missed a UTXO gets fixed up correctly""" blocks = ['0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f52da139a043b1ab6d83399d190c01417d4d69b5e03b3e813c0eac7a6e5b78c7d152a2969ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025100ffffffff0200f2052a01000000160014fcdde0698d0208be119fbd38f14407c89610f1930000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', @@ -2871,6 +2875,10 @@ def test_rescan_missing_utxo(node_factory, bitcoind): '00000030eca2849fb05b908f0cad911dc3c56d087e11d8e34ac4dd24c6225418e3afe2607803b465d839615bbd94c4161c27db6c36cc2269abae1639a811993e698abce2332a2969ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402aa0000ffffffff0200f9029500000000160014b739823522ae9beeda78fb6829478d751fa530de0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030d79629b56012c0e8abaaf887c77fc3e9e3605cc6f3fc7359b4052db1094aeb1727659d7d23a5bc4f29228ae40177e9e74b1055e78284240ff6eadcf064ddeda9332a2969ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ab0000ffffffff0200f9029500000000160014b739823522ae9beeda78fb6829478d751fa530de0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000', '00000030f63d658e126edb711843ae25f9338220c40454b10bda980331589a7de993f826ba8519dff5f62e9934166ac349fa38cb29aabf6ae21807e98706f8f8b394aa6c332a2969ffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402ac0000ffffffff0200f9029500000000160014b739823522ae9beeda78fb6829478d751fa530de0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000'] + # The canned blocks are 80-byte SHA256 headers, so activation has to + # sit past them; blocks mined afterwards are Blake2b as usual. + bitcoind.env['BLAKE2B_ACTIVATION_HEIGHT'] = str(len(blocks) + 1) + bitcoind.start() bitcoind.restore_blocks(blocks) l1, _ = node_factory.get_nodes(2, opts={'old_hsmsecret': True}) l3 = node_factory.get_node(dbfile='l3-missing-utxo.sqlite3.xz', options={'database-upgrade': True}, old_hsmsecret=True) From 8686fdab58e2c83e1b0f198f9dc5def16478f3f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 12:52:06 -0400 Subject: [PATCH 34/36] pytest: don't reap a bitcoind that was never started --- contrib/pyln-testing/pyln/testing/fixtures.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/pyln-testing/pyln/testing/fixtures.py b/contrib/pyln-testing/pyln/testing/fixtures.py index 335667cfe979..272369b8b5e4 100644 --- a/contrib/pyln-testing/pyln/testing/fixtures.py +++ b/contrib/pyln-testing/pyln/testing/fixtures.py @@ -196,8 +196,12 @@ def bitcoind(request, directory, teardown_checks): try: bitcoind.stop() except Exception: - bitcoind.proc.kill() - bitcoind.proc.wait() + if bitcoind.proc is not None: + bitcoind.proc.kill() + # A test that took the fixture unstarted, or skipped before starting it, + # has nothing to reap here. + if bitcoind.proc is not None: + bitcoind.proc.wait() bitcoind.cleanup_files() From 1d4abd90e3b5feaae30026e01ad2e669c02cec45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 14:45:40 -0400 Subject: [PATCH 35/36] pytest: the splice feerate migration test modifies the db directly, so it needs sqlite --- tests/test_splicing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_splicing.py b/tests/test_splicing.py index a6e38cef9823..05e01a90f67e 100644 --- a/tests/test_splicing.py +++ b/tests/test_splicing.py @@ -1,5 +1,6 @@ from fixtures import * # noqa: F401,F403 from pyln.client import RpcError +import os import pytest import threading import unittest @@ -63,6 +64,7 @@ def _splice_to_inflight(l1, chan_id, amount=100000): @pytest.mark.openchannel('v1') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') +@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "modifies database, which is assumed sqlite3") # -1 is how lightningd itself stored a u32 above INT_MAX (db_bind_int); the # positive form is what you get writing the same value by hand. @pytest.mark.parametrize("poison,repaired", [(4294967295, 1000000), From c685be5cdbb8903ff3658144e50d54d866501a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 20 Sep 2026 18:19:09 -0400 Subject: [PATCH 36/36] ci: drop the elements integration job, which this branch does not target --- .github/workflows/ci.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 20af434ae438..56761b798733 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -575,13 +575,6 @@ jobs: COMPILER: gcc TEST_DB_PROVIDER: postgres TEST_NETWORK: regtest - # And don't forget about elements (like cdecker did when - # reworking the CI...) - - NAME: liquid - CFG: compile-gcc-O3 - COMPILER: gcc - TEST_NETWORK: liquid-regtest - TEST_DB_PROVIDER: sqlite3 # And dual funding! - NAME: dual-fund CFG: compile-gcc