From a7cbb8475f96621d554df600fdf244ca2464c6fa Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Thu, 12 Apr 2018 17:10:04 -0600 Subject: [PATCH 01/30] Abstract `uncommitted` and depth personalization for IncrementalMerkleTree. --- src/zcash/IncrementalMerkleTree.cpp | 18 +++++++++++------- src/zcash/IncrementalMerkleTree.hpp | 14 +++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index f8fafb31a..3101cf3f3 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -8,7 +8,11 @@ namespace libzcash { -SHA256Compress SHA256Compress::combine(const SHA256Compress& a, const SHA256Compress& b) +SHA256Compress SHA256Compress::combine( + const SHA256Compress& a, + const SHA256Compress& b, + size_t depth +) { SHA256Compress res = SHA256Compress(); @@ -111,7 +115,7 @@ void IncrementalMerkleTree::append(Hash obj) { right = obj; } else { // Combine the leaves and propagate it up the tree - boost::optional combined = Hash::combine(*left, *right); + boost::optional combined = Hash::combine(*left, *right, 0); // Set the "left" leaf to the object and make the "right" leaf none left = obj; @@ -120,7 +124,7 @@ void IncrementalMerkleTree::append(Hash obj) { for (size_t i = 0; i < Depth; i++) { if (i < parents.size()) { if (parents[i]) { - combined = Hash::combine(*parents[i], *combined); + combined = Hash::combine(*parents[i], *combined, i+1); parents[i] = boost::none; } else { parents[i] = *combined; @@ -202,15 +206,15 @@ Hash IncrementalMerkleTree::root(size_t depth, Hash combine_left = left ? *left : filler.next(0); Hash combine_right = right ? *right : filler.next(0); - Hash root = Hash::combine(combine_left, combine_right); + Hash root = Hash::combine(combine_left, combine_right, 0); size_t d = 1; BOOST_FOREACH(const boost::optional& parent, parents) { if (parent) { - root = Hash::combine(*parent, root); + root = Hash::combine(*parent, root, d); } else { - root = Hash::combine(root, filler.next(d)); + root = Hash::combine(root, filler.next(d), d); } d++; @@ -219,7 +223,7 @@ Hash IncrementalMerkleTree::root(size_t depth, // We may not have parents for ancestor trees, so we fill // the rest in here. while (d < depth) { - root = Hash::combine(root, filler.next(d)); + root = Hash::combine(root, filler.next(d), d); d++; } diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index c4cf9d675..ce536fec4 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -57,9 +57,9 @@ template class EmptyMerkleRoots { public: EmptyMerkleRoots() { - empty_roots.at(0) = Hash(); + empty_roots.at(0) = Hash::uncommitted(); for (size_t d = 1; d <= Depth; d++) { - empty_roots.at(d) = Hash::combine(empty_roots.at(d-1), empty_roots.at(d-1)); + empty_roots.at(d) = Hash::combine(empty_roots.at(d-1), empty_roots.at(d-1), d-1); } } Hash empty_root(size_t depth) { @@ -213,7 +213,15 @@ public: SHA256Compress() : uint256() {} SHA256Compress(uint256 contents) : uint256(contents) { } - static SHA256Compress combine(const SHA256Compress& a, const SHA256Compress& b); + static SHA256Compress combine( + const SHA256Compress& a, + const SHA256Compress& b, + size_t depth + ); + + static SHA256Compress uncommitted() { + return SHA256Compress(); + } }; template From 2b002a7e60bd3fd037f2b4352bb3d4794df6b21d Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 14 Apr 2018 22:33:41 -0600 Subject: [PATCH 02/30] Add implementation of Sapling merkle tree --- src/zcash/IncrementalMerkleTree.cpp | 33 +++++++++++++++++++++++++++++ src/zcash/IncrementalMerkleTree.hpp | 20 +++++++++++++++++ src/zcash/Zcash.h | 2 ++ 3 files changed, 55 insertions(+) diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index 3101cf3f3..f8d5fad61 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -5,9 +5,36 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "crypto/sha256.h" #include "zcash/util.h" +#include "librustzcash.h" namespace libzcash { +PedersenHash PedersenHash::combine( + const PedersenHash& a, + const PedersenHash& b, + size_t depth +) +{ + PedersenHash res = PedersenHash(); + + librustzcash_merkle_hash( + depth, + a.begin(), + b.begin(), + res.begin() + ); + + return res; +} + +PedersenHash PedersenHash::uncommitted() { + PedersenHash res = PedersenHash(); + + librustzcash_tree_uncommitted(res.begin()); + + return res; +} + SHA256Compress SHA256Compress::combine( const SHA256Compress& a, const SHA256Compress& b, @@ -327,4 +354,10 @@ template class IncrementalMerkleTree; template class IncrementalWitness; +template class IncrementalMerkleTree; +template class IncrementalMerkleTree; + +template class IncrementalWitness; +template class IncrementalWitness; + } // end namespace `libzcash` diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index ce536fec4..fc476cd29 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -224,6 +224,20 @@ public: } }; +class PedersenHash : public uint256 { +public: + PedersenHash() : uint256() {} + PedersenHash(uint256 contents) : uint256(contents) { } + + static PedersenHash combine( + const PedersenHash& a, + const PedersenHash& b, + size_t depth + ); + + static PedersenHash uncommitted(); +}; + template EmptyMerkleRoots IncrementalMerkleTree::emptyroots; @@ -235,4 +249,10 @@ typedef libzcash::IncrementalMerkleTree ZCIncrementalWitness; typedef libzcash::IncrementalWitness ZCTestingIncrementalWitness; +typedef libzcash::IncrementalMerkleTree ZCSaplingIncrementalMerkleTree; +typedef libzcash::IncrementalMerkleTree ZCSaplingTestingIncrementalMerkleTree; + +typedef libzcash::IncrementalWitness ZCSaplingIncrementalWitness; +typedef libzcash::IncrementalWitness ZCSaplingTestingIncrementalWitness; + #endif /* ZC_INCREMENTALMERKLETREE_H_ */ diff --git a/src/zcash/Zcash.h b/src/zcash/Zcash.h index 9e6684475..bb805eef5 100644 --- a/src/zcash/Zcash.h +++ b/src/zcash/Zcash.h @@ -6,6 +6,8 @@ #define INCREMENTAL_MERKLE_TREE_DEPTH 29 #define INCREMENTAL_MERKLE_TREE_DEPTH_TESTING 4 +#define SAPLING_INCREMENTAL_MERKLE_TREE_DEPTH 32 + #define ZC_NOTEPLAINTEXT_LEADING 1 #define ZC_V_SIZE 8 #define ZC_RHO_SIZE 32 From 2f23a656fb8b4b20b10955883141fba24e6b4c6a Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Tue, 17 Apr 2018 22:59:41 -0600 Subject: [PATCH 03/30] Add regression tests and test vectors for Sapling merkle tree --- src/Makefile.test.include | 6 + src/gtest/test_merkletree.cpp | 63 +++++++- src/test/data/merkle_commitments_sapling.json | 18 +++ src/test/data/merkle_path_sapling.json | 122 ++++++++++++++++ src/test/data/merkle_roots_empty_sapling.json | 65 +++++++++ src/test/data/merkle_roots_sapling.json | 18 +++ .../data/merkle_serialization_sapling.json | 18 +++ .../merkle_witness_serialization_sapling.json | 138 ++++++++++++++++++ 8 files changed, 443 insertions(+), 5 deletions(-) create mode 100644 src/test/data/merkle_commitments_sapling.json create mode 100644 src/test/data/merkle_path_sapling.json create mode 100644 src/test/data/merkle_roots_empty_sapling.json create mode 100644 src/test/data/merkle_roots_sapling.json create mode 100644 src/test/data/merkle_serialization_sapling.json create mode 100644 src/test/data/merkle_witness_serialization_sapling.json diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 0b80921a9..600ae9301 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -32,6 +32,12 @@ JSON_TEST_FILES = \ test/data/merkle_witness_serialization.json \ test/data/merkle_path.json \ test/data/merkle_commitments.json \ + test/data/merkle_roots_sapling.json \ + test/data/merkle_roots_empty_sapling.json \ + test/data/merkle_serialization_sapling.json \ + test/data/merkle_witness_serialization_sapling.json \ + test/data/merkle_path_sapling.json \ + test/data/merkle_commitments_sapling.json \ test/data/g1_compressed.json \ test/data/g2_compressed.json diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index b3e1027a1..641479054 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -7,6 +7,13 @@ #include "test/data/merkle_path.json.h" #include "test/data/merkle_commitments.json.h" +#include "test/data/merkle_roots_sapling.json.h" +#include "test/data/merkle_roots_empty_sapling.json.h" +#include "test/data/merkle_serialization_sapling.json.h" +#include "test/data/merkle_witness_serialization_sapling.json.h" +#include "test/data/merkle_path_sapling.json.h" +#include "test/data/merkle_commitments_sapling.json.h" + #include #include @@ -51,7 +58,8 @@ void test_tree( UniValue root_tests, UniValue ser_tests, UniValue witness_ser_tests, - UniValue path_tests + UniValue path_tests, + bool libsnark_test ) { size_t witness_ser_i = 0; @@ -106,10 +114,9 @@ void test_tree( ASSERT_THROW(wit.element(), std::runtime_error); } else { auto path = wit.path(); + expect_test_vector(path_tests[path_i++], path); - { - expect_test_vector(path_tests[path_i++], path); - + if (libsnark_test) { typedef Fr FieldT; protoboard pb; @@ -188,7 +195,31 @@ TEST(merkletree, vectors) { UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path)); UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments)); - test_tree(commitment_tests, root_tests, ser_tests, witness_ser_tests, path_tests); + test_tree( + commitment_tests, + root_tests, + ser_tests, + witness_ser_tests, + path_tests, + true + ); +} + +TEST(merkletree, sapling_vectors) { + UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots_sapling)); + UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization_sapling)); + UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization_sapling)); + UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path_sapling)); + UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments_sapling)); + + test_tree( + commitment_tests, + root_tests, + ser_tests, + witness_ser_tests, + path_tests, + false + ); } TEST(merkletree, emptyroots) { @@ -204,6 +235,19 @@ TEST(merkletree, emptyroots) { ASSERT_TRUE(INCREMENTAL_MERKLE_TREE_DEPTH <= 64); } +TEST(merkletree, emptyroots_sapling) { + UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling)); + + libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots; + + for (size_t depth = 0; depth <= 62; depth++) { + expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); + } + + // Double check that we're testing (at least) all the empty roots we'll use. + ASSERT_TRUE(INCREMENTAL_MERKLE_TREE_DEPTH <= 62); +} + TEST(merkletree, emptyroot) { // This literal is the depth-20 empty tree root with the bytes reversed to // account for the fact that uint256S() loads a big-endian representation of @@ -213,6 +257,15 @@ TEST(merkletree, emptyroot) { ASSERT_TRUE(ZCIncrementalMerkleTree::empty_root() == expected); } +TEST(merkletree, emptyroot_sapling) { + // This literal is the depth-20 empty tree root with the bytes reversed to + // account for the fact that uint256S() loads a big-endian representation of + // an integer which converted to little-endian internally. + uint256 expected = uint256S("56f5903dbfe4e7356e55f13b2e6e3180a8f7056c7d8814511f797487b398ee42"); + + ASSERT_TRUE(ZCSaplingIncrementalMerkleTree::empty_root() == expected); +} + TEST(merkletree, deserializeInvalid) { // attempt to deserialize a small tree from a serialized large tree // (exceeds depth well-formedness check) diff --git a/src/test/data/merkle_commitments_sapling.json b/src/test/data/merkle_commitments_sapling.json new file mode 100644 index 000000000..00a2de809 --- /dev/null +++ b/src/test/data/merkle_commitments_sapling.json @@ -0,0 +1,18 @@ +[ + "0dc4084f07e1a7dabfe0f77a2474dce177ba0093d54a6f78d62ba4429f5cf6aa", + "44eae2cfadab5b2da725241ff8a19320ffc21476f0fc0b7e0f1d6365e48d281b", + "3e7c0558765cbc09f39ab31e79620e22adb31ed734213316689f062eb670c037", + "0a42b8363429eab85f55c85af28fda9f681678bd4603277c96c79d60210b050d", + "5537c6615c55d074dc019042d9bbbba27a9a7df60233d5115e4cd7194e7c3f49", + "1fe6122b307aa79fa526f2743e1f59a5267a51009b87b2f28bc95b50c4bbe06f", + "3d517ae368e2823a1c40c06d81ef8ece66cf0a68868a44a46d3b7c48783fd075", + "5b58bb45337bc98187888a16364878fe4a8b5999209c68387ead959fd2a7a589", + "5ce47fabdb3de2ba1c016c701cc63111f49b4dce6d183fc28c609106c1ef2e63", + "1353f1beefbf999e0cf41ca13b9bd58176021fab8825d10591d822064dbdb83e", + "0f5fec1760dcc8b92c446228f423713e300a0b6534e96ea1910726662e34ec40", + "672beb161a290bd84cef0781d518910c7d36d4f96e6b21defe1c74bcbbeb6310", + "31d7eddc17c162b618cb0d0396094a70019d6c225034f98b219b54f860231765", + "445f1d3ddb11a8b2fd1aeeb578b4fed82ad813a537d84a6406a91cc89c433ec1", + "2f7c5c3586a7e5ca60b4b2a010433657af2703a3d1c5936a8720ad4bf3e62338", + "5c6c863d48ed646293d26393e4691798ca197a67b40195376ca29595ea0235a8" +] diff --git a/src/test/data/merkle_path_sapling.json b/src/test/data/merkle_path_sapling.json new file mode 100644 index 000000000..b4b9118b4 --- /dev/null +++ b/src/test/data/merkle_path_sapling.json @@ -0,0 +1,122 @@ +[ + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820546d643b52f4193e63bb3cf0bfb51466013e8ae17f447cf848df22b12a0f2a03201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820546d643b52f4193e63bb3cf0bfb51466013e8ae17f447cf848df22b12a0f2a0320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a0205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a0205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a020531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a020531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce20531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce20531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a923205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a923205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a92320531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a92320531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982063ca4ecc29131ee8be94a5b198f3c6ea30aa2204dafc4cc9bfb9b74de2608523206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982063ca4ecc29131ee8be94a5b198f3c6ea30aa2204dafc4cc9bfb9b74de260852320493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8206e1eb21c1bd59e43c9dce633d56130ca98b863ee439f4467d0b36d3701b8b893203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8206e1eb21c1bd59e43c9dce633d56130ca98b863ee439f4467d0b36d3701b8b89320632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e20081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e20081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f7820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f7820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f78205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f78205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f20c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c3920081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c3920081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c39205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c39205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b205054731cb36c4669cc15aea3f18af91aa2465ff1f32a6996621b661e2a728e2420c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b205054731cb36c4669cc15aea3f18af91aa2465ff1f32a6996621b661e2a728e242065172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310d00000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", + "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1120081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1120081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a11205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a11205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b200d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd20c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b200d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd2065172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310d00000000000000", + "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b2071d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f573620a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c0e00000000000000" +] diff --git a/src/test/data/merkle_roots_empty_sapling.json b/src/test/data/merkle_roots_empty_sapling.json new file mode 100644 index 000000000..3518da50d --- /dev/null +++ b/src/test/data/merkle_roots_empty_sapling.json @@ -0,0 +1,65 @@ +[ + "0000000000000000000000000000000000000000000000000000000000000001", + "3dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f", + "6843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8", + "690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443", + "48afd9db45da4ad47d125d1fbf3faf5ad49bc5800203c9e7f56d98e7f962a74a", + "52664866130ed4307f2039e0230fa0e058b7a315eade184cb423bd558cd06a0c", + "2bf8be233a7a17394bb681c3b9c71114a5e223a1c273b767bac8f320a98556a0", + "68e7d5c0986103474c4343b272b5a5bf79e2da7abd29b1389ac83f8b866301ff", + "6abc7c2e7004ec7850f41a26cae44a322f1c7dd080f8a497cbd61c9ab8c41f5b", + "4c2b46542b96e217e85741ba892989852bc1b2fad76d66019b72e0c3384e28fd", + "23f8ca3569b110fdf40631ce9b8f295bbedf2ef6fe096a69fe7451db1cd4c07e", + "170ed2b7666437569b4bf18b5a038c7d113f8e1b8300a32d914f852689fd5a48", + "6aaf3bfe56ec4bc562fa8640c86888edbe9b2fdf1af0a085223447336cebbf96", + "2ced08116ee1c7607e527fb5d0b34aaca1662703286a807fabe73512b69ac18f", + "5021a742f430467ee691af6fe0dfa842cd2db9bef16c619e0e0675a2230e24b3", + "64066ab77eda0bf616519cda48cc7bc1b9f91b33b0b0debe47d86bec68ef9b3b", + "43a2743ab11d31df45b31bdb1275a4dfc673fddd41b7880405a273e1d934a80d", + "320108cefd4c869f77d675c820a2be828a8ace3f85d20d955082c6ab5d3bd8e8", + "2cf95d6d9b3d401d0fc54a6451e854720ce30e0a4674d690241693a6b41cc2a5", + "488a46044deb7d0d996e388afc53e01ca3793c9d3358944cce36a97aea11d8fe", + "18d8f93549181e2a6b3cd98baa878b0a96c5709c32a9d3dc4168f15f0af00d55", + "3999232c33f87188ae601567558bd3dec6a9c9d243c19870af3cc577ddf691ce", + "0aeade0ee89bb5de407fc4f6213ba1d492ac0628a085cbe9dca9edae9cec1987", + "392094db210b0362be62b65b9de2c038a7cb3d4a43118d0ba1d42bd9da7b7317", + "6ec7712d4d8e8f74c05c1c9706e1d63a0d249bbc3fb088b827d0c31bde3f3685", + "0d5de4e6e2bcb6854c1f34c304ec1ad896b5ba03532e090757b9a8ff4bf57122", + "6576e977682211e28332c97dcf35edfd32845da5db3a6b96822551bd16da96da", + "1e7f2ef5bd82f2fab8a44fd6701b59cf4baf8732c41f92495914cfdf597c2282", + "2a7816907971106d3b93b59dc874da22ec96da002a1653bd6bd56ba8ead5c3e9", + "3f454d16b6837bee1f74aa3e909701ba3330050fb9d0100f83e4c8dfd1349159", + "50ee5be3d5b41522eb84667e970af0803f5cd607e6f6cdead4e9885afe20d688", + "544d516b6cb28e0d904e17a7b80c8b5ee060d11ab0ff5b1ea01577c54ae4ba11", + "42ee98b38774791f5114887d6c05f7a880316e2e3bf1556e35e7e4bf3d90f556", + "1d51c8775f138982a6bda3ae24a60af0b1b706515dc72aed3dc3348908c29ae9", + "6545b76b426c072c2412315fadc0325a9c84cd6c0aed674ce9651a0e4eb1cee5", + "51d771e1e94c31708c6a83e553c0b819a535c93846fd1ed3c8788c8b3ab221c3", + "6c2478acf47f394fe7bc35cdb4b68bcb57a383eaa76d845ff5b5f92a9f16319e", + "5cd44b509881237dc34837f808ffdf79df6cc8e0291c01c9647b3602bb368de1", + "2f06fa6ae0b78cde4741546491c743872c27fc6f4715eb6d5404d8b06fabaa06", + "17cc4c7b7808464a6f0e1fa0af4da7fc833a7f5daea1ce9c46c7c83be24fdfd6", + "1c3e646bf45a89d1f25d9ef007a2a641cafdea18768ef389189d08101d9643ea", + "4ff4278d5b80439fa6282544078b33fd13dde3c7e811472adc1e07fac813d691", + "131c34f77cf89f23905e6912a5c42b978ef82d4a4132b21c317adfccff5acb02", + "3f1b3bc3cd88999836d769437c4b3df8796f042e85e8940c61eb5d2b7002c014", + "33d0bcd7d43158dceae0a9ad695c60661441091bf34a85425e413734c19f7dda", + "1fcfb94450205f2cb8804e932cd6c0302842c3e1cd77969a9e2c07437ae9b58e", + "079eb2637bf551408ea6623a465418007913b38a0bf6cb01f5e89e6409347bca", + "3e48ac5a702faff90b02c3ad9e2788b5a255652461ac68b385fcb00ac99c8ef9", + "69c87915df1e7857ee6d349bf1c6935deb3ce38f0f0cd71af56eb96ea58f72a0", + "186f22a2ff9d27f0b9c9a687e47b3ab45705735a8d4a735fb0050439858c1ba2", + "06495d4ffe824f1dd7272121f4fcf40e7a52fd6bf236f4162ab3039dd26fccd5", + "3d43ba549713dc6aecd6ddac831b523d0df574f9e0d94794ba164de779273327", + "38117f7f9cb1a38d236a01ba12141d0321cabe9e401f19e0dd5fc7b821d946ae", + "3cd5df8545eec9e3a44bd85d32fb690b44e1ea850afea3eb715320c49f56571c", + "4f2edd4af5e97d96d29baec6e80d039b915ae5eaab15bcef431e7fefd0d500cf", + "1a4e1c67131ffc1c27ff5a67889dc89e1146d88c26d2d6534756fad6a932a1c4", + "341b5d3787df25236b512c3434b64c04d30199ffcb82b05b45b52be66292d09c", + "1e48812555a81e5f64729946d34dede7e72d7df32f9611def06089a8951eaacd", + "5c7c7f875becfdc759a78bc08ccdac50ce1b66c9ade1ca9f1004a9efd2bedef5", + "5a14eb62c6c12fee6b70f21030d6f4a7296a83eb4e5c270b8bc7229f50295d24", + "5426249303bb9428453aef640c3bfc0b8ca58034a9b9a8af7390d30071d05602", + "444c299c479546193d7eabdb3a513ff628e5ecbc7c34a0a7ea9750370ea999e1", + "624175dcc2cbc405792d77f78ead1d460fb4d833d9ca33e2025da71738a1eff5" +] diff --git a/src/test/data/merkle_roots_sapling.json b/src/test/data/merkle_roots_sapling.json new file mode 100644 index 000000000..501896530 --- /dev/null +++ b/src/test/data/merkle_roots_sapling.json @@ -0,0 +1,18 @@ +[ + "382658a9ab75efa73c7183b5056b0a534ecd60cc0e2e3f2e77a7e12adae80aab", + "646c930ce6b9728c03d6497e6822104a0130ea64300898790da6f3ee3b5b85f3", + "1b0bfb478e292a2984a01b4c322f7ea3b5f0e96cb8b75a8755f1814a1bbf585e", + "549213b3d562fd5ed171dd5104b24298210b3183260b2a472de165e9acf92652", + "60c5b03aa7f54703e5b97f6b287be542ac2922907e0ff46ec11454575246d1bd", + "45dd233ae03630ac5cc158319af450fe4d1e784229b09d96a7770a3f4b30f5b0", + "194c51e5fcc56fba776f4d550159b727a65e13406ed47464e48a5f150fc1cf63", + "0ffd35b7621625f87dd6cd9166c780d9217b5375a899665fd491a30eced9758b", + "0ed077643316f173744bbdf3d7bd4be20d720dc4eaa2dc23c9019312798fc410", + "04226b0cff412d5c56808152117ca6f91c5fb93df0f4c088bd500c08cd8ab82a", + "560a5929da194ddd246e3375f2c1eda7ebc5b3594723ffa319d881f3ff0f9541", + "32cd6ec036c2e6379bda75d8f10fe47168c89bfa7d55f3ad6fdd48c26237db4c", + "55cfd0476d4d9ac7008e554b6556d3d44d509ff6833da748e889d18a5c740248", + "6db5f557d3a24b1f7dd510bdf18326de30d0d4022049b96c7027f3977f6a75c0", + "39dec1fc21c2879f629257306132005b294ea6acdef2cd8f9d199ac444b43993", + "53b68c58e26345358d8929d0bf3e3a30eefdca77f2c07920c99c10e52f7639ab" +] diff --git a/src/test/data/merkle_serialization_sapling.json b/src/test/data/merkle_serialization_sapling.json new file mode 100644 index 000000000..ca767b40f --- /dev/null +++ b/src/test/data/merkle_serialization_sapling.json @@ -0,0 +1,18 @@ +[ + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", + "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f01a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6" +] diff --git a/src/test/data/merkle_witness_serialization_sapling.json b/src/test/data/merkle_witness_serialization_sapling.json new file mode 100644 index 000000000..53e9f874b --- /dev/null +++ b/src/test/data/merkle_witness_serialization_sapling.json @@ -0,0 +1,138 @@ +[ + "00000001aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d00", + "00000002aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", + "00000002aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea44010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea44010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", + "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a00", + "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056000101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", + "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056000101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", + "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f05600010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0000", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0000", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b00", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98000101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98000101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0000", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0000", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218700", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218700", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6700", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b67010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b67010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", + "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b01013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4401013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f0000", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f0000", + "00000005aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000041b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400035aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056030d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560271d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98036fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980264286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980289a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b00102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980100102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6033eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", + "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b602081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6021063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", + "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60140757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b602c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd00", + "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6010d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd00", + "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c00" +] From 28d20bdb11197b91362553e027bd88a4cb8850ad Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 25 Apr 2018 17:55:33 -0600 Subject: [PATCH 04/30] Rename NullifierType to ShieldedType. --- src/coins.cpp | 14 +++++++------- src/coins.h | 12 ++++++------ src/gtest/test_mempool.cpp | 2 +- src/gtest/test_validation.cpp | 2 +- src/main.cpp | 4 ++-- src/test/coins_tests.cpp | 14 +++++++------- src/txdb.cpp | 6 +++--- src/txdb.h | 2 +- src/txmempool.cpp | 22 +++++++++++----------- src/txmempool.h | 6 +++--- src/zcbenchmarks.cpp | 2 +- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 0559a8820..87b00a226 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -43,7 +43,7 @@ bool CCoins::Spend(uint32_t nPos) return true; } bool CCoinsView::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } -bool CCoinsView::GetNullifier(const uint256 &nullifier, NullifierType type) const { return false; } +bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } uint256 CCoinsView::GetBestBlock() const { return uint256(); } @@ -60,7 +60,7 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); } -bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, NullifierType type) const { return base->GetNullifier(nullifier, type); } +bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } @@ -133,13 +133,13 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tr return true; } -bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, NullifierType type) const { +bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) const { CNullifiersMap* cacheToUse; switch (type) { - case SPROUT_NULLIFIER: + case SPROUT: cacheToUse = &cacheSproutNullifiers; break; - case SAPLING_NULLIFIER: + case SAPLING: cacheToUse = &cacheSaplingNullifiers; break; default: @@ -430,7 +430,7 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const { BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers) { - if (GetNullifier(nullifier, SPROUT_NULLIFIER)) { + if (GetNullifier(nullifier, SPROUT)) { // If the nullifier is set, this transaction // double-spends! return false; @@ -454,7 +454,7 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const } for (const SpendDescription &spendDescription : tx.vShieldedSpend) { - if (GetNullifier(spendDescription.nullifier, SAPLING_NULLIFIER)) // Prevent double spends + if (GetNullifier(spendDescription.nullifier, SAPLING)) // Prevent double spends return false; } diff --git a/src/coins.h b/src/coins.h index e2b454649..a796c9bfb 100644 --- a/src/coins.h +++ b/src/coins.h @@ -298,10 +298,10 @@ struct CNullifiersCacheEntry CNullifiersCacheEntry() : entered(false), flags(0) {} }; -enum NullifierType +enum ShieldedType { - SPROUT_NULLIFIER, - SAPLING_NULLIFIER, + SPROUT, + SAPLING, }; typedef boost::unordered_map CCoinsMap; @@ -330,7 +330,7 @@ public: virtual bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; //! Determine whether a nullifier is spent or not - virtual bool GetNullifier(const uint256 &nullifier, NullifierType type) const; + virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; //! Retrieve the CCoins (unspent transaction outputs) for a given txid virtual bool GetCoins(const uint256 &txid, CCoins &coins) const; @@ -371,7 +371,7 @@ protected: public: CCoinsViewBacked(CCoinsView *viewIn); bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; - bool GetNullifier(const uint256 &nullifier, NullifierType type) const; + bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; @@ -437,7 +437,7 @@ public: // Standard CCoinsView methods bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; - bool GetNullifier(const uint256 &nullifier, NullifierType type) const; + bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 981c4eb08..2a74ea9b3 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -23,7 +23,7 @@ public: return false; } - bool GetNullifier(const uint256 &nf, NullifierType type) const { + bool GetNullifier(const uint256 &nf, ShieldedType type) const { return false; } diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 710e3c600..cabeeb3a7 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -25,7 +25,7 @@ public: return false; } - bool GetNullifier(const uint256 &nf, NullifierType type) const { + bool GetNullifier(const uint256 &nf, ShieldedType type) const { return false; } diff --git a/src/main.cpp b/src/main.cpp index bca80c31a..95c8b094a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1305,13 +1305,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { - if (pool.nullifierExists(nf, SPROUT_NULLIFIER)) { + if (pool.nullifierExists(nf, SPROUT)) { return false; } } } for (const SpendDescription &spendDescription : tx.vShieldedSpend) { - if (pool.nullifierExists(spendDescription.nullifier, SAPLING_NULLIFIER)) { + if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) { return false; } } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index ae147ea08..2767112e6 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -52,14 +52,14 @@ public: } } - bool GetNullifier(const uint256 &nf, NullifierType type) const + bool GetNullifier(const uint256 &nf, ShieldedType type) const { const std::map* mapToUse; switch (type) { - case SPROUT_NULLIFIER: + case SPROUT: mapToUse = &mapSproutNullifiers_; break; - case SAPLING_NULLIFIER: + case SAPLING: mapToUse = &mapSaplingNullifiers_; break; default: @@ -215,11 +215,11 @@ BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup) void checkNullifierCache(const CCoinsViewCacheTest &cache, const TxWithNullifiers &txWithNullifiers, bool shouldBeInCache) { // Make sure the nullifiers have not gotten mixed up - BOOST_CHECK(!cache.GetNullifier(txWithNullifiers.sproutNullifier, SAPLING_NULLIFIER)); - BOOST_CHECK(!cache.GetNullifier(txWithNullifiers.saplingNullifier, SPROUT_NULLIFIER)); + BOOST_CHECK(!cache.GetNullifier(txWithNullifiers.sproutNullifier, SAPLING)); + BOOST_CHECK(!cache.GetNullifier(txWithNullifiers.saplingNullifier, SPROUT)); // Check if the nullifiers either are or are not in the cache - bool containsSproutNullifier = cache.GetNullifier(txWithNullifiers.sproutNullifier, SPROUT_NULLIFIER); - bool containsSaplingNullifier = cache.GetNullifier(txWithNullifiers.saplingNullifier, SAPLING_NULLIFIER); + bool containsSproutNullifier = cache.GetNullifier(txWithNullifiers.sproutNullifier, SPROUT); + bool containsSaplingNullifier = cache.GetNullifier(txWithNullifiers.saplingNullifier, SAPLING); BOOST_CHECK(containsSproutNullifier == shouldBeInCache); BOOST_CHECK(containsSaplingNullifier == shouldBeInCache); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 2c2f0faaf..eb3617fc6 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -52,14 +52,14 @@ bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) return read; } -bool CCoinsViewDB::GetNullifier(const uint256 &nf, NullifierType type) const { +bool CCoinsViewDB::GetNullifier(const uint256 &nf, ShieldedType type) const { bool spent = false; char dbChar; switch (type) { - case SPROUT_NULLIFIER: + case SPROUT: dbChar = DB_NULLIFIER; break; - case SAPLING_NULLIFIER: + case SAPLING: dbChar = DB_SAPLING_NULLIFIER; break; default: diff --git a/src/txdb.h b/src/txdb.h index 53f3c31c6..99ff4f31f 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -36,7 +36,7 @@ public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; - bool GetNullifier(const uint256 &nf, NullifierType type) const; + bool GetNullifier(const uint256 &nf, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 850851aad..6fde29f40 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -394,7 +394,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { - assert(!pcoins->GetNullifier(nf, SPROUT_NULLIFIER)); + assert(!pcoins->GetNullifier(nf, SPROUT)); } ZCIncrementalMerkleTree tree; @@ -413,7 +413,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const intermediates.insert(std::make_pair(tree.root(), tree)); } for (const SpendDescription &spendDescription : tx.vShieldedSpend) { - assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING_NULLIFIER)); + assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING)); } if (fDependsWait) waitingOnDependants.push_back(&(*it)); @@ -452,21 +452,21 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(it->first == it->second.ptx->vin[it->second.n].prevout); } - checkNullifiers(SPROUT_NULLIFIER); - checkNullifiers(SAPLING_NULLIFIER); + checkNullifiers(SPROUT); + checkNullifiers(SAPLING); assert(totalTxSize == checkTotal); assert(innerUsage == cachedInnerUsage); } -void CTxMemPool::checkNullifiers(NullifierType type) const +void CTxMemPool::checkNullifiers(ShieldedType type) const { const std::map* mapToUse; switch (type) { - case SPROUT_NULLIFIER: + case SPROUT: mapToUse = &mapSproutNullifiers; break; - case SAPLING_NULLIFIER: + case SAPLING: mapToUse = &mapSaplingNullifiers; break; default: @@ -582,12 +582,12 @@ bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const return true; } -bool CTxMemPool::nullifierExists(const uint256& nullifier, NullifierType type) const +bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) const { switch (type) { - case SPROUT_NULLIFIER: + case SPROUT: return mapSproutNullifiers.count(nullifier); - case SAPLING_NULLIFIER: + case SAPLING: return mapSaplingNullifiers.count(nullifier); default: throw runtime_error("Unknown nullifier type"); @@ -596,7 +596,7 @@ bool CTxMemPool::nullifierExists(const uint256& nullifier, NullifierType type) c CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } -bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, NullifierType type) const +bool CCoinsViewMemPool::GetNullifier(const uint256 &nf, ShieldedType type) const { return mempool.nullifierExists(nf, type) || base->GetNullifier(nf, type); } diff --git a/src/txmempool.h b/src/txmempool.h index 0397c6d7f..f37636efb 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -134,7 +134,7 @@ private: std::map mapSproutNullifiers; std::map mapSaplingNullifiers; - void checkNullifiers(NullifierType type) const; + void checkNullifiers(ShieldedType type) const; public: typedef boost::multi_index_container< @@ -192,7 +192,7 @@ public: void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); void ClearPrioritisation(const uint256 hash); - bool nullifierExists(const uint256& nullifier, NullifierType type) const; + bool nullifierExists(const uint256& nullifier, ShieldedType type) const; unsigned long size() { @@ -243,7 +243,7 @@ protected: public: CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn); - bool GetNullifier(const uint256 &txid, NullifierType type) const; + bool GetNullifier(const uint256 &txid, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; }; diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 53d433c86..1567ad01e 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -366,7 +366,7 @@ public: return false; } - bool GetNullifier(const uint256 &nf, NullifierType type) const { + bool GetNullifier(const uint256 &nf, ShieldedType type) const { return false; } From d455828fdc135b6086a51431013c58818a0a98db Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 25 Apr 2018 18:38:34 -0600 Subject: [PATCH 05/30] Specifically describe anchors as Sprout anchors. --- src/coins.cpp | 52 +++++++++++++++++------------------ src/coins.h | 14 +++++----- src/gtest/test_mempool.cpp | 2 +- src/gtest/test_validation.cpp | 2 +- src/test/coins_tests.cpp | 20 +++++++------- src/txdb.cpp | 10 +++---- src/txdb.h | 2 +- src/zcbenchmarks.cpp | 2 +- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 87b00a226..b31703a7d 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -51,7 +51,7 @@ uint256 CCoinsView::GetBestAnchor() const { return uint256(); }; bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } @@ -69,9 +69,9 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, - CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashAnchor, mapAnchors, mapSproutNullifiers, mapSaplingNullifiers); } + CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} @@ -85,7 +85,7 @@ CCoinsViewCache::~CCoinsViewCache() size_t CCoinsViewCache::DynamicMemoryUsage() const { return memusage::DynamicUsage(cacheCoins) + - memusage::DynamicUsage(cacheAnchors) + + memusage::DynamicUsage(cacheSproutAnchors) + memusage::DynamicUsage(cacheSproutNullifiers) + memusage::DynamicUsage(cacheSaplingNullifiers) + cachedCoinsUsage; @@ -111,8 +111,8 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { - CAnchorsMap::const_iterator it = cacheAnchors.find(rt); - if (it != cacheAnchors.end()) { + CAnchorsSproutMap::const_iterator it = cacheSproutAnchors.find(rt); + if (it != cacheSproutAnchors.end()) { if (it->second.entered) { tree = it->second.tree; return true; @@ -125,7 +125,7 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tr return false; } - CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first; + CAnchorsSproutMap::iterator ret = cacheSproutAnchors.insert(std::make_pair(rt, CAnchorsSproutCacheEntry())).first; ret->second.entered = true; ret->second.tree = tree; cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); @@ -164,17 +164,17 @@ void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) { auto currentRoot = GetBestAnchor(); // We don't want to overwrite an anchor we already have. - // This occurs when a block doesn't modify mapAnchors at all, + // This occurs when a block doesn't modify mapSproutAnchors at all, // because there are no joinsplits. We could get around this a - // different way (make all blocks modify mapAnchors somehow) + // different way (make all blocks modify mapSproutAnchors somehow) // but this is simpler to reason about. if (currentRoot != newrt) { - auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CAnchorsCacheEntry())); - CAnchorsMap::iterator ret = insertRet.first; + auto insertRet = cacheSproutAnchors.insert(std::make_pair(newrt, CAnchorsSproutCacheEntry())); + CAnchorsSproutMap::iterator ret = insertRet.first; ret->second.entered = true; ret->second.tree = tree; - ret->second.flags = CAnchorsCacheEntry::DIRTY; + ret->second.flags = CAnchorsSproutCacheEntry::DIRTY; if (insertRet.second) { // An insert took place @@ -200,10 +200,10 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt) { } // Mark the anchor as unentered, removing it from view - cacheAnchors[currentRoot].entered = false; + cacheSproutAnchors[currentRoot].entered = false; // Mark the cache entry as dirty so it's propagated - cacheAnchors[currentRoot].flags = CAnchorsCacheEntry::DIRTY; + cacheSproutAnchors[currentRoot].flags = CAnchorsSproutCacheEntry::DIRTY; // Mark the new root as the best anchor hashAnchor = newrt; @@ -315,7 +315,7 @@ void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNu bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, const uint256 &hashAnchorIn, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { assert(!hasModifier); @@ -354,29 +354,29 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, mapCoins.erase(itOld); } - for (CAnchorsMap::iterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();) + for (CAnchorsSproutMap::iterator child_it = mapSproutAnchors.begin(); child_it != mapSproutAnchors.end();) { - if (child_it->second.flags & CAnchorsCacheEntry::DIRTY) { - CAnchorsMap::iterator parent_it = cacheAnchors.find(child_it->first); + if (child_it->second.flags & CAnchorsSproutCacheEntry::DIRTY) { + CAnchorsSproutMap::iterator parent_it = cacheSproutAnchors.find(child_it->first); - if (parent_it == cacheAnchors.end()) { - CAnchorsCacheEntry& entry = cacheAnchors[child_it->first]; + if (parent_it == cacheSproutAnchors.end()) { + CAnchorsSproutCacheEntry& entry = cacheSproutAnchors[child_it->first]; entry.entered = child_it->second.entered; entry.tree = child_it->second.tree; - entry.flags = CAnchorsCacheEntry::DIRTY; + entry.flags = CAnchorsSproutCacheEntry::DIRTY; cachedCoinsUsage += entry.tree.DynamicMemoryUsage(); } else { if (parent_it->second.entered != child_it->second.entered) { // The parent may have removed the entry. parent_it->second.entered = child_it->second.entered; - parent_it->second.flags |= CAnchorsCacheEntry::DIRTY; + parent_it->second.flags |= CAnchorsSproutCacheEntry::DIRTY; } } } - CAnchorsMap::iterator itOld = child_it++; - mapAnchors.erase(itOld); + CAnchorsSproutMap::iterator itOld = child_it++; + mapSproutAnchors.erase(itOld); } ::BatchWriteNullifiers(mapSproutNullifiers, cacheSproutNullifiers); @@ -388,9 +388,9 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, } bool CCoinsViewCache::Flush() { - bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashAnchor, cacheAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); + bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); cacheCoins.clear(); - cacheAnchors.clear(); + cacheSproutAnchors.clear(); cacheSproutNullifiers.clear(); cacheSaplingNullifiers.clear(); cachedCoinsUsage = 0; diff --git a/src/coins.h b/src/coins.h index a796c9bfb..60c6963d3 100644 --- a/src/coins.h +++ b/src/coins.h @@ -273,7 +273,7 @@ struct CCoinsCacheEntry CCoinsCacheEntry() : coins(), flags(0) {} }; -struct CAnchorsCacheEntry +struct CAnchorsSproutCacheEntry { bool entered; // This will be false if the anchor is removed from the cache ZCIncrementalMerkleTree tree; // The tree itself @@ -283,7 +283,7 @@ struct CAnchorsCacheEntry DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. }; - CAnchorsCacheEntry() : entered(false), flags(0) {} + CAnchorsSproutCacheEntry() : entered(false), flags(0) {} }; struct CNullifiersCacheEntry @@ -305,7 +305,7 @@ enum ShieldedType }; typedef boost::unordered_map CCoinsMap; -typedef boost::unordered_map CAnchorsMap; +typedef boost::unordered_map CAnchorsSproutMap; typedef boost::unordered_map CNullifiersMap; struct CCoinsStats @@ -350,7 +350,7 @@ public: virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -380,7 +380,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); bool GetStats(CCoinsStats &stats) const; @@ -424,7 +424,7 @@ protected: mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; mutable uint256 hashAnchor; - mutable CAnchorsMap cacheAnchors; + mutable CAnchorsSproutMap cacheSproutAnchors; mutable CNullifiersMap cacheSproutNullifiers; mutable CNullifiersMap cacheSaplingNullifiers; @@ -446,7 +446,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 2a74ea9b3..b64683563 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -55,7 +55,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index cabeeb3a7..c4abba2bb 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -50,7 +50,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap saplingNullifiersMap) { return false; diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 2767112e6..94d11a68e 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -27,7 +27,7 @@ class CCoinsViewTest : public CCoinsView uint256 hashBestBlock_; uint256 hashBestAnchor_; std::map map_; - std::map mapAnchors_; + std::map mapSproutAnchors_; std::map mapSproutNullifiers_; std::map mapSaplingNullifiers_; @@ -43,8 +43,8 @@ public: return true; } - std::map::const_iterator it = mapAnchors_.find(rt); - if (it == mapAnchors_.end()) { + std::map::const_iterator it = mapSproutAnchors_.find(rt); + if (it == mapSproutAnchors_.end()) { return false; } else { tree = it->second; @@ -115,7 +115,7 @@ public: bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock, const uint256& hashAnchor, - CAnchorsMap& mapAnchors, + CAnchorsSproutMap& mapSproutAnchors, CNullifiersMap& mapSproutNullifiers, CNullifiersMap& mapSaplingNullifiers) { @@ -127,23 +127,23 @@ public: } mapCoins.erase(it++); } - for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end(); ) { + for (CAnchorsSproutMap::iterator it = mapSproutAnchors.begin(); it != mapSproutAnchors.end(); ) { if (it->second.entered) { std::map::iterator ret = - mapAnchors_.insert(std::make_pair(it->first, ZCIncrementalMerkleTree())).first; + mapSproutAnchors_.insert(std::make_pair(it->first, ZCIncrementalMerkleTree())).first; ret->second = it->second.tree; } else { - mapAnchors_.erase(it->first); + mapSproutAnchors_.erase(it->first); } - mapAnchors.erase(it++); + mapSproutAnchors.erase(it++); } BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_); BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_); mapCoins.clear(); - mapAnchors.clear(); + mapSproutAnchors.clear(); hashBestBlock_ = hashBlock; hashBestAnchor_ = hashAnchor; return true; @@ -161,7 +161,7 @@ public: { // Manually recompute the dynamic usage of the whole data, and compare it. size_t ret = memusage::DynamicUsage(cacheCoins) + - memusage::DynamicUsage(cacheAnchors) + + memusage::DynamicUsage(cacheSproutAnchors) + memusage::DynamicUsage(cacheSproutNullifiers) + memusage::DynamicUsage(cacheSaplingNullifiers); for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { diff --git a/src/txdb.cpp b/src/txdb.cpp index eb3617fc6..f2a27beee 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -108,7 +108,7 @@ void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { CDBBatch batch(db); @@ -127,8 +127,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, mapCoins.erase(itOld); } - for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end();) { - if (it->second.flags & CAnchorsCacheEntry::DIRTY) { + for (CAnchorsSproutMap::iterator it = mapSproutAnchors.begin(); it != mapSproutAnchors.end();) { + if (it->second.flags & CAnchorsSproutCacheEntry::DIRTY) { if (!it->second.entered) batch.Erase(make_pair(DB_ANCHOR, it->first)); else { @@ -136,8 +136,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, } // TODO: changed++? } - CAnchorsMap::iterator itOld = it++; - mapAnchors.erase(itOld); + CAnchorsSproutMap::iterator itOld = it++; + mapSproutAnchors.erase(itOld); } ::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER); diff --git a/src/txdb.h b/src/txdb.h index 99ff4f31f..b2a4f4c28 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -44,7 +44,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); bool GetStats(CCoinsStats &stats) const; diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 1567ad01e..80c726b5a 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -381,7 +381,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, + CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap& mapSaplingNullifiers) { return false; From 08f0728884afad6a352065b582f6dd3e44c25fa7 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Wed, 25 Apr 2018 19:15:30 -0600 Subject: [PATCH 06/30] Rename hashAnchor to hashSproutAnchor. --- src/chain.h | 10 +++++----- src/coins.cpp | 22 +++++++++++----------- src/coins.h | 8 ++++---- src/gtest/test_mempool.cpp | 2 +- src/gtest/test_validation.cpp | 2 +- src/main.cpp | 16 ++++++++-------- src/rpcblockchain.cpp | 2 +- src/test/coins_tests.cpp | 10 +++++----- src/txdb.cpp | 12 ++++++------ src/txdb.h | 2 +- src/wallet/wallet.cpp | 2 +- 11 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/chain.h b/src/chain.h index 906267326..df05d82e6 100644 --- a/src/chain.h +++ b/src/chain.h @@ -152,10 +152,10 @@ public: boost::optional nCachedBranchId; //! The anchor for the tree state up to the start of this block - uint256 hashAnchor; + uint256 hashSproutAnchor; //! (memory only) The anchor for the tree state up to the end of this block - uint256 hashAnchorEnd; + uint256 hashSproutAnchorEnd; //! Change in value held by the Sprout circuit over this block. //! Will be boost::none for older blocks on old nodes until a reindex has taken place. @@ -192,8 +192,8 @@ public: nChainTx = 0; nStatus = 0; nCachedBranchId = boost::none; - hashAnchor = uint256(); - hashAnchorEnd = uint256(); + hashSproutAnchor = uint256(); + hashSproutAnchorEnd = uint256(); nSequenceId = 0; nSproutValue = boost::none; nChainSproutValue = boost::none; @@ -366,7 +366,7 @@ public: READWRITE(branchId); } } - READWRITE(hashAnchor); + READWRITE(hashSproutAnchor); // block header READWRITE(this->nVersion); diff --git a/src/coins.cpp b/src/coins.cpp index b31703a7d..9a056aadf 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -50,7 +50,7 @@ uint256 CCoinsView::GetBestBlock() const { return uint256(); } uint256 CCoinsView::GetBestAnchor() const { return uint256(); }; bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; } @@ -68,10 +68,10 @@ uint256 CCoinsViewBacked::GetBestAnchor() const { return base->GetBestAnchor(); void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, - CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } + CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} @@ -181,7 +181,7 @@ void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) { cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); } - hashAnchor = newrt; + hashSproutAnchor = newrt; } } @@ -206,7 +206,7 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt) { cacheSproutAnchors[currentRoot].flags = CAnchorsSproutCacheEntry::DIRTY; // Mark the new root as the best anchor - hashAnchor = newrt; + hashSproutAnchor = newrt; } } @@ -281,9 +281,9 @@ uint256 CCoinsViewCache::GetBestBlock() const { uint256 CCoinsViewCache::GetBestAnchor() const { - if (hashAnchor.IsNull()) - hashAnchor = base->GetBestAnchor(); - return hashAnchor; + if (hashSproutAnchor.IsNull()) + hashSproutAnchor = base->GetBestAnchor(); + return hashSproutAnchor; } void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { @@ -314,7 +314,7 @@ void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNu bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, - const uint256 &hashAnchorIn, + const uint256 &hashSproutAnchorIn, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { @@ -382,13 +382,13 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, ::BatchWriteNullifiers(mapSproutNullifiers, cacheSproutNullifiers); ::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers); - hashAnchor = hashAnchorIn; + hashSproutAnchor = hashSproutAnchorIn; hashBlock = hashBlockIn; return true; } bool CCoinsViewCache::Flush() { - bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); + bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); cacheCoins.clear(); cacheSproutAnchors.clear(); cacheSproutNullifiers.clear(); diff --git a/src/coins.h b/src/coins.h index 60c6963d3..aa408e78e 100644 --- a/src/coins.h +++ b/src/coins.h @@ -349,7 +349,7 @@ public: //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -379,7 +379,7 @@ public: void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -423,7 +423,7 @@ protected: */ mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; - mutable uint256 hashAnchor; + mutable uint256 hashSproutAnchor; mutable CAnchorsSproutMap cacheSproutAnchors; mutable CNullifiersMap cacheSproutNullifiers; mutable CNullifiersMap cacheSaplingNullifiers; @@ -445,7 +445,7 @@ public: void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index b64683563..3061b4911 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -54,7 +54,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index c4abba2bb..84b107265 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -49,7 +49,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap saplingNullifiersMap) { diff --git a/src/main.cpp b/src/main.cpp index 95c8b094a..9827c1438 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2295,9 +2295,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin view.SetBestBlock(pindex->GetBlockHash()); // Before the genesis block, there was an empty tree ZCIncrementalMerkleTree tree; - pindex->hashAnchor = tree.root(); + pindex->hashSproutAnchor = tree.root(); // The genesis block contained no JoinSplits - pindex->hashAnchorEnd = pindex->hashAnchor; + pindex->hashSproutAnchorEnd = pindex->hashSproutAnchor; } return true; } @@ -2333,7 +2333,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin auto old_tree_root = view.GetBestAnchor(); // saving the top anchor in the block index as we go. if (!fJustCheck) { - pindex->hashAnchor = old_tree_root; + pindex->hashSproutAnchor = old_tree_root; } ZCIncrementalMerkleTree tree; // This should never fail: we should always be able to get the root @@ -2413,7 +2413,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin view.PushAnchor(tree); if (!fJustCheck) { - pindex->hashAnchorEnd = tree.root(); + pindex->hashSproutAnchorEnd = tree.root(); } blockundo.old_tree_root = old_tree_root; @@ -3927,12 +3927,12 @@ bool static LoadBlockIndexDB() { CBlockIndex* pindex = item.second; // - This relationship will always be true even if pprev has multiple - // children, because hashAnchor is technically a property of pprev, + // children, because hashSproutAnchor is technically a property of pprev, // not its children. // - This will miss chain tips; we handle the best tip below, and other // tips will be handled by ConnectTip during a re-org. if (pindex->pprev) { - pindex->pprev->hashAnchorEnd = pindex->hashAnchor; + pindex->pprev->hashSproutAnchorEnd = pindex->hashSproutAnchor; } } @@ -3941,8 +3941,8 @@ bool static LoadBlockIndexDB() if (it == mapBlockIndex.end()) return true; chainActive.SetTip(it->second); - // Set hashAnchorEnd for the end of best chain - it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor(); + // Set hashSproutAnchorEnd for the end of best chain + it->second->hashSproutAnchorEnd = pcoinsTip->GetBestAnchor(); PruneBlockIndexCandidates(); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index c0565a8fc..8c5afbb6a 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -155,7 +155,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("bits", strprintf("%08x", block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex())); + result.push_back(Pair("anchor", blockindex->hashSproutAnchorEnd.GetHex())); UniValue valuePools(UniValue::VARR); valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue)); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 94d11a68e..39b9a09e8 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -25,7 +25,7 @@ namespace class CCoinsViewTest : public CCoinsView { uint256 hashBestBlock_; - uint256 hashBestAnchor_; + uint256 hashBestSproutAnchor_; std::map map_; std::map mapSproutAnchors_; std::map mapSproutNullifiers_; @@ -33,7 +33,7 @@ class CCoinsViewTest : public CCoinsView public: CCoinsViewTest() { - hashBestAnchor_ = ZCIncrementalMerkleTree::empty_root(); + hashBestSproutAnchor_ = ZCIncrementalMerkleTree::empty_root(); } bool GetAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const { @@ -75,7 +75,7 @@ public: } } - uint256 GetBestAnchor() const { return hashBestAnchor_; } + uint256 GetBestAnchor() const { return hashBestSproutAnchor_; } bool GetCoins(const uint256& txid, CCoins& coins) const { @@ -114,7 +114,7 @@ public: bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock, - const uint256& hashAnchor, + const uint256& hashSproutAnchor, CAnchorsSproutMap& mapSproutAnchors, CNullifiersMap& mapSproutNullifiers, CNullifiersMap& mapSaplingNullifiers) @@ -145,7 +145,7 @@ public: mapCoins.clear(); mapSproutAnchors.clear(); hashBestBlock_ = hashBlock; - hashBestAnchor_ = hashAnchor; + hashBestSproutAnchor_ = hashSproutAnchor; return true; } diff --git a/src/txdb.cpp b/src/txdb.cpp index f2a27beee..6195d0b13 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -26,7 +26,7 @@ static const char DB_TXINDEX = 't'; static const char DB_BLOCK_INDEX = 'b'; static const char DB_BEST_BLOCK = 'B'; -static const char DB_BEST_ANCHOR = 'a'; +static const char DB_BEST_SPROUT_ANCHOR = 'a'; static const char DB_FLAG = 'F'; static const char DB_REINDEX_FLAG = 'R'; static const char DB_LAST_BLOCK = 'l'; @@ -85,7 +85,7 @@ uint256 CCoinsViewDB::GetBestBlock() const { uint256 CCoinsViewDB::GetBestAnchor() const { uint256 hashBestAnchor; - if (!db.Read(DB_BEST_ANCHOR, hashBestAnchor)) + if (!db.Read(DB_BEST_SPROUT_ANCHOR, hashBestAnchor)) return ZCIncrementalMerkleTree::empty_root(); return hashBestAnchor; } @@ -107,7 +107,7 @@ void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { @@ -145,8 +145,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, if (!hashBlock.IsNull()) batch.Write(DB_BEST_BLOCK, hashBlock); - if (!hashAnchor.IsNull()) - batch.Write(DB_BEST_ANCHOR, hashAnchor); + if (!hashSproutAnchor.IsNull()) + batch.Write(DB_BEST_SPROUT_ANCHOR, hashSproutAnchor); LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); return db.WriteBatch(batch); @@ -284,7 +284,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nFile = diskindex.nFile; pindexNew->nDataPos = diskindex.nDataPos; pindexNew->nUndoPos = diskindex.nUndoPos; - pindexNew->hashAnchor = diskindex.hashAnchor; + pindexNew->hashSproutAnchor = diskindex.hashSproutAnchor; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->hashReserved = diskindex.hashReserved; diff --git a/src/txdb.h b/src/txdb.h index b2a4f4c28..75e60d8b0 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -43,7 +43,7 @@ public: uint256 GetBestAnchor() const; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, - const uint256 &hashAnchor, + const uint256 &hashSproutAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5ab1103ff..1a1e1959c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1819,7 +1819,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ZCIncrementalMerkleTree tree; // This should never fail: we should always be able to get the tree // state on the path to the tip of our chain - assert(pcoinsTip->GetAnchorAt(pindex->hashAnchor, tree)); + assert(pcoinsTip->GetAnchorAt(pindex->hashSproutAnchor, tree)); // Increment note witness caches IncrementNoteWitnesses(pindex, &block, tree); From 691a3fa2e9d95014dab0f705dccd37871395abd9 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 14:11:32 -0600 Subject: [PATCH 07/30] Rename hashReserved to hashSaplingAnchorEnd. --- src/chain.h | 12 ++++++------ src/miner.cpp | 2 +- src/primitives/block.cpp | 4 ++-- src/primitives/block.h | 10 +++++----- src/txdb.cpp | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/chain.h b/src/chain.h index df05d82e6..4857435ed 100644 --- a/src/chain.h +++ b/src/chain.h @@ -169,7 +169,7 @@ public: //! block header int nVersion; uint256 hashMerkleRoot; - uint256 hashReserved; + uint256 hashSaplingAnchorEnd; unsigned int nTime; unsigned int nBits; uint256 nNonce; @@ -200,7 +200,7 @@ public: nVersion = 0; hashMerkleRoot = uint256(); - hashReserved = uint256(); + hashSaplingAnchorEnd = uint256(); nTime = 0; nBits = 0; nNonce = uint256(); @@ -218,7 +218,7 @@ public: nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; - hashReserved = block.hashReserved; + hashSaplingAnchorEnd = block.hashSaplingAnchorEnd; nTime = block.nTime; nBits = block.nBits; nNonce = block.nNonce; @@ -250,7 +250,7 @@ public: if (pprev) block.hashPrevBlock = pprev->GetBlockHash(); block.hashMerkleRoot = hashMerkleRoot; - block.hashReserved = hashReserved; + block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; @@ -372,7 +372,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrev); READWRITE(hashMerkleRoot); - READWRITE(hashReserved); + READWRITE(hashSaplingAnchorEnd); READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); @@ -391,7 +391,7 @@ public: block.nVersion = nVersion; block.hashPrevBlock = hashPrev; block.hashMerkleRoot = hashMerkleRoot; - block.hashReserved = hashReserved; + block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; diff --git a/src/miner.cpp b/src/miner.cpp index 44e28f82b..b0c2875a9 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -374,7 +374,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - pblock->hashReserved = uint256(); + pblock->hashSaplingAnchorEnd = uint256(); // TODO UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nSolution.clear(); diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index c2300c82a..b6c5ce9cc 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -112,12 +112,12 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMer std::string CBlock::ToString() const { std::stringstream s; - s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, hashReserved=%s, nTime=%u, nBits=%08x, nNonce=%s, vtx=%u)\n", + s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, hashSaplingAnchorEnd=%s, nTime=%u, nBits=%08x, nNonce=%s, vtx=%u)\n", GetHash().ToString(), nVersion, hashPrevBlock.ToString(), hashMerkleRoot.ToString(), - hashReserved.ToString(), + hashSaplingAnchorEnd.ToString(), nTime, nBits, nNonce.ToString(), vtx.size()); for (unsigned int i = 0; i < vtx.size(); i++) diff --git a/src/primitives/block.h b/src/primitives/block.h index f6eeebcbb..56288e10a 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -26,7 +26,7 @@ public: int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; - uint256 hashReserved; + uint256 hashSaplingAnchorEnd; uint32_t nTime; uint32_t nBits; uint256 nNonce; @@ -44,7 +44,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); - READWRITE(hashReserved); + READWRITE(hashSaplingAnchorEnd); READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); @@ -56,7 +56,7 @@ public: nVersion = CBlockHeader::CURRENT_VERSION; hashPrevBlock.SetNull(); hashMerkleRoot.SetNull(); - hashReserved.SetNull(); + hashSaplingAnchorEnd.SetNull(); nTime = 0; nBits = 0; nNonce = uint256(); @@ -118,7 +118,7 @@ public: block.nVersion = nVersion; block.hashPrevBlock = hashPrevBlock; block.hashMerkleRoot = hashMerkleRoot; - block.hashReserved = hashReserved; + block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; @@ -158,7 +158,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); - READWRITE(hashReserved); + READWRITE(hashSaplingAnchorEnd); READWRITE(nTime); READWRITE(nBits); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 6195d0b13..d14562a37 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -287,7 +287,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->hashSproutAnchor = diskindex.hashSproutAnchor; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; - pindexNew->hashReserved = diskindex.hashReserved; + pindexNew->hashSaplingAnchorEnd = diskindex.hashSaplingAnchorEnd; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; From 30325eebf5fe50c9a3820267951643c3fe041082 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 14:29:40 -0600 Subject: [PATCH 08/30] Add primitive implementation of GetSaplingAnchorEnd. --- src/chain.cpp | 7 +++++++ src/chain.h | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/chain.cpp b/src/chain.cpp index 39520cc8f..51f1c2a2d 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -7,6 +7,13 @@ using namespace std; +uint256 CBlockIndex::GetSaplingAnchorEnd() const { + // TODO: The block header's hashSaplingAnchorEnd is only guaranteed to + // be valid on or after the Sapling activation height. + + return hashSaplingAnchorEnd; +} + /** * CChain implementation */ diff --git a/src/chain.h b/src/chain.h index 4857435ed..51947ba95 100644 --- a/src/chain.h +++ b/src/chain.h @@ -321,6 +321,9 @@ public: //! Efficiently find an ancestor of this block. CBlockIndex* GetAncestor(int height); const CBlockIndex* GetAncestor(int height) const; + + //! Get the root of the Sapling merkle tree (at the end of this block) + uint256 GetSaplingAnchorEnd() const; }; /** Used to marshal pointers into hashes for db storage. */ From 8b8d70cad935137806d447a68fd489b4b2c4fdbf Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 14:34:31 -0600 Subject: [PATCH 09/30] Rename DB_ANCHOR to DB_SPROUT_ANCHOR. --- src/txdb.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index d14562a37..9b36192a4 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -17,7 +17,7 @@ using namespace std; -static const char DB_ANCHOR = 'A'; +static const char DB_SPROUT_ANCHOR = 'A'; static const char DB_NULLIFIER = 's'; static const char DB_SAPLING_NULLIFIER = 'S'; static const char DB_COINS = 'c'; @@ -47,7 +47,7 @@ bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) return true; } - bool read = db.Read(make_pair(DB_ANCHOR, rt), tree); + bool read = db.Read(make_pair(DB_SPROUT_ANCHOR, rt), tree); return read; } @@ -130,9 +130,9 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, for (CAnchorsSproutMap::iterator it = mapSproutAnchors.begin(); it != mapSproutAnchors.end();) { if (it->second.flags & CAnchorsSproutCacheEntry::DIRTY) { if (!it->second.entered) - batch.Erase(make_pair(DB_ANCHOR, it->first)); + batch.Erase(make_pair(DB_SPROUT_ANCHOR, it->first)); else { - batch.Write(make_pair(DB_ANCHOR, it->first), it->second.tree); + batch.Write(make_pair(DB_SPROUT_ANCHOR, it->first), it->second.tree); } // TODO: changed++? } From 008f4ee8e7a58b033e4f3ce417286bdef7e36a8a Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 15:00:00 -0600 Subject: [PATCH 10/30] Rename GetAnchorAt to GetSproutAnchorAt. --- src/coins.cpp | 12 +++---- src/coins.h | 6 ++-- src/gtest/test_mempool.cpp | 2 +- src/gtest/test_validation.cpp | 2 +- src/main.cpp | 6 ++-- src/rpcblockchain.cpp | 2 +- src/test/coins_tests.cpp | 36 +++++++++---------- src/txdb.cpp | 2 +- src/txdb.h | 2 +- src/txmempool.cpp | 2 +- .../asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 2 +- src/wallet/wallet.cpp | 4 +-- 13 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 9a056aadf..072d3f659 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -42,7 +42,7 @@ bool CCoins::Spend(uint32_t nPos) Cleanup(); return true; } -bool CCoinsView::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } +bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } @@ -59,7 +59,7 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } -bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); } +bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); } bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } @@ -110,7 +110,7 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const } -bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { +bool CCoinsViewCache::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { CAnchorsSproutMap::const_iterator it = cacheSproutAnchors.find(rt); if (it != cacheSproutAnchors.end()) { if (it->second.entered) { @@ -121,7 +121,7 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tr } } - if (!base->GetAnchorAt(rt, tree)) { + if (!base->GetSproutAnchorAt(rt, tree)) { return false; } @@ -196,7 +196,7 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt) { // so that its tree exists in memory. { ZCIncrementalMerkleTree tree; - assert(GetAnchorAt(currentRoot, tree)); + assert(GetSproutAnchorAt(currentRoot, tree)); } // Mark the anchor as unentered, removing it from view @@ -441,7 +441,7 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const auto it = intermediates.find(joinsplit.anchor); if (it != intermediates.end()) { tree = it->second; - } else if (!GetAnchorAt(joinsplit.anchor, tree)) { + } else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) { return false; } diff --git a/src/coins.h b/src/coins.h index aa408e78e..b774961e1 100644 --- a/src/coins.h +++ b/src/coins.h @@ -327,7 +327,7 @@ class CCoinsView { public: //! Retrieve the tree at a particular anchored root in the chain - virtual bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + virtual bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; //! Determine whether a nullifier is spent or not virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; @@ -370,7 +370,7 @@ protected: public: CCoinsViewBacked(CCoinsView *viewIn); - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -436,7 +436,7 @@ public: ~CCoinsViewCache(); // Standard CCoinsView methods - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 3061b4911..41aa5c832 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -19,7 +19,7 @@ class FakeCoinsViewDB : public CCoinsView { public: FakeCoinsViewDB() {} - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { + bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 84b107265..564767040 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -21,7 +21,7 @@ class FakeCoinsViewDB : public CCoinsView { public: FakeCoinsViewDB() {} - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { + bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } diff --git a/src/main.cpp b/src/main.cpp index 9827c1438..21d4c3992 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2338,7 +2338,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin ZCIncrementalMerkleTree tree; // This should never fail: we should always be able to get the root // that is on the tip of our chain - assert(view.GetAnchorAt(old_tree_root, tree)); + assert(view.GetSproutAnchorAt(old_tree_root, tree)); { // Consistency check: the root of the tree we're given should @@ -2692,7 +2692,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { UpdateTip(pindexDelete->pprev); // Get the current commitment tree ZCIncrementalMerkleTree newTree; - assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), newTree)); + assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), newTree)); // Let wallets know transactions went from 1-confirmed to // 0-confirmed or conflicted: BOOST_FOREACH(const CTransaction &tx, block.vtx) { @@ -2726,7 +2726,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * } // Get the current commitment tree ZCIncrementalMerkleTree oldTree; - assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree)); + assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), oldTree)); // Apply the block atomically to the chain state. int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; int64_t nTime3; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 8c5afbb6a..c4d33691d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -770,7 +770,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) obj.push_back(Pair("pruned", fPruneMode)); ZCIncrementalMerkleTree tree; - pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree); + pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), tree); obj.push_back(Pair("commitments", static_cast(tree.size()))); CBlockIndex* tip = chainActive.Tip(); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 39b9a09e8..bfe14b533 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -36,7 +36,7 @@ public: hashBestSproutAnchor_ = ZCIncrementalMerkleTree::empty_root(); } - bool GetAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const { + bool GetSproutAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const { if (rt == ZCIncrementalMerkleTree::empty_root()) { ZCIncrementalMerkleTree new_tree; tree = new_tree; @@ -339,7 +339,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) // The base contains the anchor, of course! { ZCIncrementalMerkleTree checktree; - BOOST_CHECK(cache1.GetAnchorAt(tree.root(), checktree)); + BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree)); BOOST_CHECK(checktree.root() == tree.root()); } } @@ -372,7 +372,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) // treestate... { ZCIncrementalMerkleTree checktree; - BOOST_CHECK(cache1.GetAnchorAt(tree.root(), checktree)); + BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree)); BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks. } @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); { ZCIncrementalMerkleTree checktree; - BOOST_CHECK(cache1.GetAnchorAt(tree.root(), checktree)); + BOOST_CHECK(cache1.GetSproutAnchorAt(tree.root(), checktree)); BOOST_CHECK(checktree.root() == tree.root()); // Oh, shucks. } } @@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); - BOOST_CHECK(!cache1.GetAnchorAt(tree.root(), tree)); + BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } // Also correct behavior: @@ -421,7 +421,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); cache1.Flush(); BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); - BOOST_CHECK(!cache1.GetAnchorAt(tree.root(), tree)); + BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } // Works because we bring the anchor in from parent cache. @@ -439,13 +439,13 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) { // Pop anchor. CCoinsViewCacheTest cache2(&cache1); - BOOST_CHECK(cache2.GetAnchorAt(tree.root(), tree)); + BOOST_CHECK(cache2.GetSproutAnchorAt(tree.root(), tree)); cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root()); cache2.Flush(); } BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); - BOOST_CHECK(!cache1.GetAnchorAt(tree.root(), tree)); + BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } // Was broken: @@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) } BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); - BOOST_CHECK(!cache1.GetAnchorAt(tree.root(), tree)); + BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } } @@ -502,7 +502,7 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) { CCoinsViewCacheTest cache(&base); ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); appendRandomCommitment(tree); newrt = tree.root(); @@ -514,10 +514,10 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) { CCoinsViewCacheTest cache(&base); ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); // Get the cached entry. - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); uint256 check_rt = tree.root(); @@ -615,7 +615,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) { ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); BOOST_CHECK(cache.GetBestAnchor() == tree.root()); appendRandomCommitment(tree); appendRandomCommitment(tree); @@ -636,7 +636,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) { ZCIncrementalMerkleTree confirm_same; - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), confirm_same)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), confirm_same)); BOOST_CHECK(confirm_same.root() == newrt); } @@ -650,13 +650,13 @@ BOOST_AUTO_TEST_CASE(anchors_test) BOOST_CHECK(cache.GetBestAnchor() == newrt2); ZCIncrementalMerkleTree test_tree; - BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), test_tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), test_tree)); BOOST_CHECK(tree.root() == test_tree.root()); { ZCIncrementalMerkleTree test_tree2; - cache.GetAnchorAt(newrt, test_tree2); + cache.GetSproutAnchorAt(newrt, test_tree2); BOOST_CHECK(test_tree2.root() == newrt); } @@ -664,8 +664,8 @@ BOOST_AUTO_TEST_CASE(anchors_test) { cache.PopAnchor(newrt); ZCIncrementalMerkleTree obtain_tree; - assert(!cache.GetAnchorAt(newrt2, obtain_tree)); // should have been popped off - assert(cache.GetAnchorAt(newrt, obtain_tree)); + assert(!cache.GetSproutAnchorAt(newrt2, obtain_tree)); // should have been popped off + assert(cache.GetSproutAnchorAt(newrt, obtain_tree)); assert(obtain_tree.root() == newrt); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 9b36192a4..8d07d59ba 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -40,7 +40,7 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get } -bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { +bool CCoinsViewDB::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { if (rt == ZCIncrementalMerkleTree::empty_root()) { ZCIncrementalMerkleTree new_tree; tree = new_tree; diff --git a/src/txdb.h b/src/txdb.h index 75e60d8b0..3290be28c 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -35,7 +35,7 @@ protected: public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nf, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6fde29f40..a7fc3d1f7 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -402,7 +402,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const if (it != intermediates.end()) { tree = it->second; } else { - assert(pcoins->GetAnchorAt(joinsplit.anchor, tree)); + assert(pcoins->GetSproutAnchorAt(joinsplit.anchor, tree)); } BOOST_FOREACH(const uint256& commitment, joinsplit.commitments) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index cae42019a..abc9d1338 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -429,7 +429,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() auto it = intermediates.find(prevJoinSplit.anchor); if (it != intermediates.end()) { tree = it->second; - } else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) { + } else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) { throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); } diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 73a9360d7..dae33d3f3 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -545,7 +545,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { auto it = intermediates.find(prevJoinSplit.anchor); if (it != intermediates.end()) { tree = it->second; - } else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) { + } else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) { throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1a1e1959c..0a66f1e36 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1765,7 +1765,7 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, // Consistency check: we should be able to find the current tree // in our CCoins view. ZCIncrementalMerkleTree dummy_tree; - assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree)); + assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree)); pindex = chainActive.Next(pindex); } @@ -1819,7 +1819,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ZCIncrementalMerkleTree tree; // This should never fail: we should always be able to get the tree // state on the path to the tip of our chain - assert(pcoinsTip->GetAnchorAt(pindex->hashSproutAnchor, tree)); + assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, tree)); // Increment note witness caches IncrementNoteWitnesses(pindex, &block, tree); From 2bd59e1473210c14623a680e5149b165ccdc1323 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 15:18:04 -0600 Subject: [PATCH 11/30] Rename PushAnchor to PushSproutAnchor. --- src/coins.cpp | 2 +- src/coins.h | 2 +- src/main.cpp | 2 +- src/test/coins_tests.cpp | 22 +++++++++++----------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 072d3f659..ebcc5e1a8 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -158,7 +158,7 @@ bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) return tmp; } -void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) { +void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { uint256 newrt = tree.root(); auto currentRoot = GetBestAnchor(); diff --git a/src/coins.h b/src/coins.h index b774961e1..99273786e 100644 --- a/src/coins.h +++ b/src/coins.h @@ -453,7 +453,7 @@ public: // Adds the tree to mapAnchors and sets the current commitment // root to this root. - void PushAnchor(const ZCIncrementalMerkleTree &tree); + void PushSproutAnchor(const ZCIncrementalMerkleTree &tree); // Removes the current commitment root from mapAnchors and sets // the new current root. diff --git a/src/main.cpp b/src/main.cpp index 21d4c3992..96f9b66aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2411,7 +2411,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - view.PushAnchor(tree); + view.PushSproutAnchor(tree); if (!fJustCheck) { pindex->hashSproutAnchorEnd = tree.root(); } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index bfe14b533..9382edeb2 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) tree.append(cm); // Add the anchor - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); // Remove the anchor @@ -333,7 +333,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); // Add the anchor back - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); // The base contains the anchor, of course! @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) tree.append(cm); // Add the anchor and flush to disk - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); // Remove the anchor, but don't flush yet! @@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) { CCoinsViewCacheTest cache2(&cache1); // Build cache on top - cache2.PushAnchor(tree); // Put the same anchor back! + cache2.PushSproutAnchor(tree); // Put the same anchor back! cache2.Flush(); // Flush to cache1 } @@ -398,7 +398,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) ZCIncrementalMerkleTree tree; uint256 cm = GetRandHash(); tree.append(cm); - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); @@ -415,7 +415,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) ZCIncrementalMerkleTree tree; uint256 cm = GetRandHash(); tree.append(cm); - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); @@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) ZCIncrementalMerkleTree tree; uint256 cm = GetRandHash(); tree.append(cm); - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); { @@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) ZCIncrementalMerkleTree tree; uint256 cm = GetRandHash(); tree.append(cm); - cache1.PushAnchor(tree); + cache1.PushSproutAnchor(tree); cache1.Flush(); { @@ -507,7 +507,7 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) newrt = tree.root(); - cache.PushAnchor(tree); + cache.PushSproutAnchor(tree); cache.Flush(); } @@ -631,7 +631,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) uint256 newrt = tree.root(); uint256 newrt2; - cache.PushAnchor(tree); + cache.PushSproutAnchor(tree); BOOST_CHECK(cache.GetBestAnchor() == newrt); { @@ -646,7 +646,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) newrt2 = tree.root(); - cache.PushAnchor(tree); + cache.PushSproutAnchor(tree); BOOST_CHECK(cache.GetBestAnchor() == newrt2); ZCIncrementalMerkleTree test_tree; From 18322f074ccc00361f43932267062d02249a5fb5 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 16:00:21 -0600 Subject: [PATCH 12/30] Introduce support for GetBestAnchor(SAPLING). --- src/coins.cpp | 35 ++++++++++----- src/coins.h | 10 +++-- src/gtest/test_mempool.cpp | 3 +- src/gtest/test_validation.cpp | 3 +- src/main.cpp | 12 ++--- src/rpcblockchain.cpp | 2 +- src/test/coins_tests.cpp | 45 ++++++++++++------- src/txdb.cpp | 22 +++++++-- src/txdb.h | 3 +- .../asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 2 +- .../asyncrpcoperation_shieldcoinbase.cpp | 2 +- 12 files changed, 97 insertions(+), 44 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index ebcc5e1a8..29bf04dc8 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -47,10 +47,11 @@ bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } uint256 CCoinsView::GetBestBlock() const { return uint256(); } -uint256 CCoinsView::GetBestAnchor() const { return uint256(); }; +uint256 CCoinsView::GetBestAnchor(ShieldedType type) const { return uint256(); }; bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; } @@ -64,14 +65,15 @@ bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } -uint256 CCoinsViewBacked::GetBestAnchor() const { return base->GetBestAnchor(); } +uint256 CCoinsViewBacked::GetBestAnchor(ShieldedType type) const { return base->GetBestAnchor(type); } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, - CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } + CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} @@ -161,7 +163,7 @@ bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { uint256 newrt = tree.root(); - auto currentRoot = GetBestAnchor(); + auto currentRoot = GetBestAnchor(SPROUT); // We don't want to overwrite an anchor we already have. // This occurs when a block doesn't modify mapSproutAnchors at all, @@ -186,7 +188,7 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { } void CCoinsViewCache::PopAnchor(const uint256 &newrt) { - auto currentRoot = GetBestAnchor(); + auto currentRoot = GetBestAnchor(SPROUT); // Blocks might not change the commitment tree, in which // case restoring the "old" anchor during a reorg must @@ -280,10 +282,21 @@ uint256 CCoinsViewCache::GetBestBlock() const { } -uint256 CCoinsViewCache::GetBestAnchor() const { - if (hashSproutAnchor.IsNull()) - hashSproutAnchor = base->GetBestAnchor(); - return hashSproutAnchor; +uint256 CCoinsViewCache::GetBestAnchor(ShieldedType type) const { + switch (type) { + case SPROUT: + if (hashSproutAnchor.IsNull()) + hashSproutAnchor = base->GetBestAnchor(type); + return hashSproutAnchor; + break; + case SAPLING: + if (hashSaplingAnchor.IsNull()) + hashSaplingAnchor = base->GetBestAnchor(type); + return hashSaplingAnchor; + break; + default: + throw std::runtime_error("Unknown shielded type " + type); + } } void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { @@ -315,6 +328,7 @@ void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNu bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, const uint256 &hashSproutAnchorIn, + const uint256 &hashSaplingAnchorIn, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { @@ -383,12 +397,13 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, ::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers); hashSproutAnchor = hashSproutAnchorIn; + hashSaplingAnchor = hashSaplingAnchorIn; hashBlock = hashBlockIn; return true; } bool CCoinsViewCache::Flush() { - bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); + bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); cacheCoins.clear(); cacheSproutAnchors.clear(); cacheSproutNullifiers.clear(); diff --git a/src/coins.h b/src/coins.h index 99273786e..055320056 100644 --- a/src/coins.h +++ b/src/coins.h @@ -343,13 +343,14 @@ public: virtual uint256 GetBestBlock() const; //! Get the current "tip" or the latest anchored tree root in the chain - virtual uint256 GetBestAnchor() const; + virtual uint256 GetBestAnchor(ShieldedType type) const; //! Do a bulk modification (multiple CCoins changes + BestBlock change). //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -375,11 +376,12 @@ public: bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - uint256 GetBestAnchor() const; + uint256 GetBestAnchor(ShieldedType type) const; void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -424,6 +426,7 @@ protected: mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; mutable uint256 hashSproutAnchor; + mutable uint256 hashSaplingAnchor; mutable CAnchorsSproutMap cacheSproutAnchors; mutable CNullifiersMap cacheSproutNullifiers; mutable CNullifiersMap cacheSaplingNullifiers; @@ -441,11 +444,12 @@ public: bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - uint256 GetBestAnchor() const; + uint256 GetBestAnchor(ShieldedType type) const; void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 41aa5c832..1d5999de2 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -47,7 +47,7 @@ public: return a; } - uint256 GetBestAnchor() const { + uint256 GetBestAnchor(ShieldedType type) const { uint256 a; return a; } @@ -55,6 +55,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 564767040..b76c3e77d 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -42,7 +42,7 @@ public: return a; } - uint256 GetBestAnchor() const { + uint256 GetBestAnchor(ShieldedType type) const { uint256 a; return a; } @@ -50,6 +50,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap saplingNullifiersMap) { diff --git a/src/main.cpp b/src/main.cpp index 96f9b66aa..991e34110 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2330,7 +2330,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Construct the incremental merkle tree at the current // block position, - auto old_tree_root = view.GetBestAnchor(); + auto old_tree_root = view.GetBestAnchor(SPROUT); // saving the top anchor in the block index as we go. if (!fJustCheck) { pindex->hashSproutAnchor = old_tree_root; @@ -2658,7 +2658,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { if (!ReadBlockFromDisk(block, pindexDelete)) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. - uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor(); + uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT); int64_t nStart = GetTimeMicros(); { CCoinsViewCache view(pcoinsTip); @@ -2667,7 +2667,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { assert(view.Flush()); } LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); - uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor(); + uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT); // Write the chain state to disk, if necessary. if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; @@ -2692,7 +2692,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { UpdateTip(pindexDelete->pprev); // Get the current commitment tree ZCIncrementalMerkleTree newTree; - assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), newTree)); + assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newTree)); // Let wallets know transactions went from 1-confirmed to // 0-confirmed or conflicted: BOOST_FOREACH(const CTransaction &tx, block.vtx) { @@ -2726,7 +2726,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * } // Get the current commitment tree ZCIncrementalMerkleTree oldTree; - assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), oldTree)); + assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldTree)); // Apply the block atomically to the chain state. int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; int64_t nTime3; @@ -3942,7 +3942,7 @@ bool static LoadBlockIndexDB() return true; chainActive.SetTip(it->second); // Set hashSproutAnchorEnd for the end of best chain - it->second->hashSproutAnchorEnd = pcoinsTip->GetBestAnchor(); + it->second->hashSproutAnchorEnd = pcoinsTip->GetBestAnchor(SPROUT); PruneBlockIndexCandidates(); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index c4d33691d..1633c8b72 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -770,7 +770,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) obj.push_back(Pair("pruned", fPruneMode)); ZCIncrementalMerkleTree tree; - pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(), tree); + pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree); obj.push_back(Pair("commitments", static_cast(tree.size()))); CBlockIndex* tip = chainActive.Tip(); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 9382edeb2..daae2e009 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -26,6 +26,7 @@ class CCoinsViewTest : public CCoinsView { uint256 hashBestBlock_; uint256 hashBestSproutAnchor_; + uint256 hashBestSaplingAnchor_; std::map map_; std::map mapSproutAnchors_; std::map mapSproutNullifiers_; @@ -34,6 +35,7 @@ class CCoinsViewTest : public CCoinsView public: CCoinsViewTest() { hashBestSproutAnchor_ = ZCIncrementalMerkleTree::empty_root(); + hashBestSaplingAnchor_ = ZCSaplingIncrementalMerkleTree::empty_root(); } bool GetSproutAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const { @@ -75,7 +77,18 @@ public: } } - uint256 GetBestAnchor() const { return hashBestSproutAnchor_; } + uint256 GetBestAnchor(ShieldedType type) const { + switch (type) { + case SPROUT: + return hashBestSproutAnchor_; + break; + case SAPLING: + return hashBestSaplingAnchor_; + break; + default: + throw std::runtime_error("Unknown shielded type " + type); + } + } bool GetCoins(const uint256& txid, CCoins& coins) const { @@ -115,6 +128,7 @@ public: bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock, const uint256& hashSproutAnchor, + const uint256& hashSaplingAnchor, CAnchorsSproutMap& mapSproutAnchors, CNullifiersMap& mapSproutNullifiers, CNullifiersMap& mapSaplingNullifiers) @@ -146,6 +160,7 @@ public: mapSproutAnchors.clear(); hashBestBlock_ = hashBlock; hashBestSproutAnchor_ = hashSproutAnchor; + hashBestSaplingAnchor_ = hashSaplingAnchor; return true; } @@ -402,7 +417,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.Flush(); cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); - BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); + BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } @@ -420,7 +435,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); cache1.Flush(); - BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); + BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } @@ -444,7 +459,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache2.Flush(); } - BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); + BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } @@ -467,7 +482,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache2.Flush(); } - BOOST_CHECK(cache1.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); + BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } } @@ -502,7 +517,7 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) { CCoinsViewCacheTest cache(&base); ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree)); appendRandomCommitment(tree); newrt = tree.root(); @@ -514,10 +529,10 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) { CCoinsViewCacheTest cache(&base); ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree)); // Get the cached entry. - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree)); uint256 check_rt = tree.root(); @@ -610,13 +625,13 @@ BOOST_AUTO_TEST_CASE(anchors_test) CCoinsViewTest base; CCoinsViewCacheTest cache(&base); - BOOST_CHECK(cache.GetBestAnchor() == ZCIncrementalMerkleTree::empty_root()); + BOOST_CHECK(cache.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); { ZCIncrementalMerkleTree tree; - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), tree)); - BOOST_CHECK(cache.GetBestAnchor() == tree.root()); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), tree)); + BOOST_CHECK(cache.GetBestAnchor(SPROUT) == tree.root()); appendRandomCommitment(tree); appendRandomCommitment(tree); appendRandomCommitment(tree); @@ -632,11 +647,11 @@ BOOST_AUTO_TEST_CASE(anchors_test) uint256 newrt2; cache.PushSproutAnchor(tree); - BOOST_CHECK(cache.GetBestAnchor() == newrt); + BOOST_CHECK(cache.GetBestAnchor(SPROUT) == newrt); { ZCIncrementalMerkleTree confirm_same; - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), confirm_same)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), confirm_same)); BOOST_CHECK(confirm_same.root() == newrt); } @@ -647,10 +662,10 @@ BOOST_AUTO_TEST_CASE(anchors_test) newrt2 = tree.root(); cache.PushSproutAnchor(tree); - BOOST_CHECK(cache.GetBestAnchor() == newrt2); + BOOST_CHECK(cache.GetBestAnchor(SPROUT) == newrt2); ZCIncrementalMerkleTree test_tree; - BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(), test_tree)); + BOOST_CHECK(cache.GetSproutAnchorAt(cache.GetBestAnchor(SPROUT), test_tree)); BOOST_CHECK(tree.root() == test_tree.root()); diff --git a/src/txdb.cpp b/src/txdb.cpp index 8d07d59ba..59ebbdf94 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -27,6 +27,7 @@ static const char DB_BLOCK_INDEX = 'b'; static const char DB_BEST_BLOCK = 'B'; static const char DB_BEST_SPROUT_ANCHOR = 'a'; +static const char DB_BEST_SAPLING_ANCHOR = 'x'; static const char DB_FLAG = 'F'; static const char DB_REINDEX_FLAG = 'R'; static const char DB_LAST_BLOCK = 'l'; @@ -83,10 +84,22 @@ uint256 CCoinsViewDB::GetBestBlock() const { return hashBestChain; } -uint256 CCoinsViewDB::GetBestAnchor() const { +uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const { uint256 hashBestAnchor; - if (!db.Read(DB_BEST_SPROUT_ANCHOR, hashBestAnchor)) - return ZCIncrementalMerkleTree::empty_root(); + + switch (type) { + case SPROUT: + if (!db.Read(DB_BEST_SPROUT_ANCHOR, hashBestAnchor)) + return ZCIncrementalMerkleTree::empty_root(); + break; + case SAPLING: + if (!db.Read(DB_BEST_SAPLING_ANCHOR, hashBestAnchor)) + return ZCSaplingIncrementalMerkleTree::empty_root(); + break; + default: + throw runtime_error("Unknown shielded type " + type); + } + return hashBestAnchor; } @@ -108,6 +121,7 @@ void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { @@ -147,6 +161,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, batch.Write(DB_BEST_BLOCK, hashBlock); if (!hashSproutAnchor.IsNull()) batch.Write(DB_BEST_SPROUT_ANCHOR, hashSproutAnchor); + if (!hashSaplingAnchor.IsNull()) + batch.Write(DB_BEST_SAPLING_ANCHOR, hashSaplingAnchor); LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); return db.WriteBatch(batch); diff --git a/src/txdb.h b/src/txdb.h index 3290be28c..d97f18303 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -40,10 +40,11 @@ public: bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - uint256 GetBestAnchor() const; + uint256 GetBestAnchor(ShieldedType type) const; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index abc9d1338..916ad862b 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -693,7 +693,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf uint256 anchor; { LOCK(cs_main); - anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor + anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor } return perform_joinsplit(info, witnesses, anchor); } diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index dae33d3f3..ba9f566f6 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -914,7 +914,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info uint256 anchor; { LOCK(cs_main); - anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor + anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor } return perform_joinsplit(info, witnesses, anchor); } diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index dcadc6a78..45d9321dd 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -314,7 +314,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf { LOCK(cs_main); consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - anchor = pcoinsTip->GetBestAnchor(); + anchor = pcoinsTip->GetBestAnchor(SPROUT); } From 9ea4e387b29858ee7bf35d1a11354fc5f0583a88 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 16:31:12 -0600 Subject: [PATCH 13/30] Generalize the PopAnchor implementation behavior. --- src/coins.cpp | 40 +++++++++++++++++++++++++++++++++------- src/coins.h | 9 +++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 29bf04dc8..a6c43ce6b 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -187,8 +187,15 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { } } -void CCoinsViewCache::PopAnchor(const uint256 &newrt) { - auto currentRoot = GetBestAnchor(SPROUT); +template +void CCoinsViewCache::AbstractPopAnchor( + const uint256 &newrt, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash +) +{ + auto currentRoot = GetBestAnchor(type); // Blocks might not change the commitment tree, in which // case restoring the "old" anchor during a reorg must @@ -197,21 +204,40 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt) { // Bring the current best anchor into our local cache // so that its tree exists in memory. { - ZCIncrementalMerkleTree tree; - assert(GetSproutAnchorAt(currentRoot, tree)); + Tree tree; + switch (type) { + case SPROUT: + assert(GetSproutAnchorAt(currentRoot, tree)); + break; + case SAPLING: + // TODO + assert(false); + break; + default: + throw std::runtime_error("Unknown shielded type " + type); + } } // Mark the anchor as unentered, removing it from view - cacheSproutAnchors[currentRoot].entered = false; + cacheAnchors[currentRoot].entered = false; // Mark the cache entry as dirty so it's propagated - cacheSproutAnchors[currentRoot].flags = CAnchorsSproutCacheEntry::DIRTY; + cacheAnchors[currentRoot].flags = CacheEntry::DIRTY; // Mark the new root as the best anchor - hashSproutAnchor = newrt; + hash = newrt; } } +void CCoinsViewCache::PopAnchor(const uint256 &newrt) { + AbstractPopAnchor( + newrt, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); +} + void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) { for (const JSDescription &joinsplit : tx.vjoinsplit) { for (const uint256 &nullifier : joinsplit.nullifiers) { diff --git a/src/coins.h b/src/coins.h index 055320056..f121ed2e7 100644 --- a/src/coins.h +++ b/src/coins.h @@ -524,6 +524,15 @@ private: * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache. */ CCoinsViewCache(const CCoinsViewCache &); + + //! Generalized interface for popping anchors + template + void AbstractPopAnchor( + const uint256 &newrt, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash + ); }; #endif // BITCOIN_COINS_H From 7703a673ea73301027988d77d8a70cb613501cb5 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 27 Apr 2018 16:52:33 -0600 Subject: [PATCH 14/30] Generalize the PushAnchor implementation behavior. --- src/coins.cpp | 28 ++++++++++++++++++++++------ src/coins.h | 9 +++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index a6c43ce6b..7f400ed44 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -160,10 +160,17 @@ bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) return tmp; } -void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { +template +void CCoinsViewCache::AbstractPushAnchor( + const Tree &tree, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash +) +{ uint256 newrt = tree.root(); - auto currentRoot = GetBestAnchor(SPROUT); + auto currentRoot = GetBestAnchor(type); // We don't want to overwrite an anchor we already have. // This occurs when a block doesn't modify mapSproutAnchors at all, @@ -171,22 +178,31 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { // different way (make all blocks modify mapSproutAnchors somehow) // but this is simpler to reason about. if (currentRoot != newrt) { - auto insertRet = cacheSproutAnchors.insert(std::make_pair(newrt, CAnchorsSproutCacheEntry())); - CAnchorsSproutMap::iterator ret = insertRet.first; + auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CacheEntry())); + CacheIterator ret = insertRet.first; ret->second.entered = true; ret->second.tree = tree; - ret->second.flags = CAnchorsSproutCacheEntry::DIRTY; + ret->second.flags = CacheEntry::DIRTY; if (insertRet.second) { // An insert took place cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); } - hashSproutAnchor = newrt; + hash = newrt; } } +void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { + AbstractPushAnchor( + tree, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); +} + template void CCoinsViewCache::AbstractPopAnchor( const uint256 &newrt, diff --git a/src/coins.h b/src/coins.h index f121ed2e7..b8c41e5d7 100644 --- a/src/coins.h +++ b/src/coins.h @@ -533,6 +533,15 @@ private: Cache &cacheAnchors, uint256 &hash ); + + //! Generalized interface for pushing anchors + template + void AbstractPushAnchor( + const Tree &tree, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash + ); }; #endif // BITCOIN_COINS_H From 7b6207878202f40f8f627a80feaea3ad30ad0b11 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 14:26:54 -0600 Subject: [PATCH 15/30] Remove underscores from gtest test names. --- src/gtest/test_merkletree.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index 641479054..8b453a90f 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -205,7 +205,7 @@ TEST(merkletree, vectors) { ); } -TEST(merkletree, sapling_vectors) { +TEST(merkletree, SaplingVectors) { UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots_sapling)); UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization_sapling)); UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization_sapling)); @@ -235,7 +235,7 @@ TEST(merkletree, emptyroots) { ASSERT_TRUE(INCREMENTAL_MERKLE_TREE_DEPTH <= 64); } -TEST(merkletree, emptyroots_sapling) { +TEST(merkletree, EmptyrootsSapling) { UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling)); libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots; @@ -257,7 +257,7 @@ TEST(merkletree, emptyroot) { ASSERT_TRUE(ZCIncrementalMerkleTree::empty_root() == expected); } -TEST(merkletree, emptyroot_sapling) { +TEST(merkletree, EmptyrootSapling) { // This literal is the depth-20 empty tree root with the bytes reversed to // account for the fact that uint256S() loads a big-endian representation of // an integer which converted to little-endian internally. From f2c6d214e5c2b93ac5cbdda1404924429add3b1e Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 15:19:28 -0600 Subject: [PATCH 16/30] Rename hashSaplingAnchorEnd to hashFinalSaplingRoot to match spec. --- src/chain.cpp | 4 ++-- src/chain.h | 12 ++++++------ src/miner.cpp | 2 +- src/primitives/block.cpp | 4 ++-- src/primitives/block.h | 10 +++++----- src/txdb.cpp | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index 51f1c2a2d..c9c787900 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -8,10 +8,10 @@ using namespace std; uint256 CBlockIndex::GetSaplingAnchorEnd() const { - // TODO: The block header's hashSaplingAnchorEnd is only guaranteed to + // TODO: The block header's hashFinalSaplingRoot is only guaranteed to // be valid on or after the Sapling activation height. - return hashSaplingAnchorEnd; + return hashFinalSaplingRoot; } /** diff --git a/src/chain.h b/src/chain.h index 51947ba95..76f535cea 100644 --- a/src/chain.h +++ b/src/chain.h @@ -169,7 +169,7 @@ public: //! block header int nVersion; uint256 hashMerkleRoot; - uint256 hashSaplingAnchorEnd; + uint256 hashFinalSaplingRoot; unsigned int nTime; unsigned int nBits; uint256 nNonce; @@ -200,7 +200,7 @@ public: nVersion = 0; hashMerkleRoot = uint256(); - hashSaplingAnchorEnd = uint256(); + hashFinalSaplingRoot = uint256(); nTime = 0; nBits = 0; nNonce = uint256(); @@ -218,7 +218,7 @@ public: nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; - hashSaplingAnchorEnd = block.hashSaplingAnchorEnd; + hashFinalSaplingRoot = block.hashFinalSaplingRoot; nTime = block.nTime; nBits = block.nBits; nNonce = block.nNonce; @@ -250,7 +250,7 @@ public: if (pprev) block.hashPrevBlock = pprev->GetBlockHash(); block.hashMerkleRoot = hashMerkleRoot; - block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; + block.hashFinalSaplingRoot = hashFinalSaplingRoot; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; @@ -375,7 +375,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrev); READWRITE(hashMerkleRoot); - READWRITE(hashSaplingAnchorEnd); + READWRITE(hashFinalSaplingRoot); READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); @@ -394,7 +394,7 @@ public: block.nVersion = nVersion; block.hashPrevBlock = hashPrev; block.hashMerkleRoot = hashMerkleRoot; - block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; + block.hashFinalSaplingRoot = hashFinalSaplingRoot; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; diff --git a/src/miner.cpp b/src/miner.cpp index b0c2875a9..41b54ad36 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -374,7 +374,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - pblock->hashSaplingAnchorEnd = uint256(); // TODO + pblock->hashFinalSaplingRoot = uint256(); // TODO UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nSolution.clear(); diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index b6c5ce9cc..430ac8721 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -112,12 +112,12 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMer std::string CBlock::ToString() const { std::stringstream s; - s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, hashSaplingAnchorEnd=%s, nTime=%u, nBits=%08x, nNonce=%s, vtx=%u)\n", + s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, hashFinalSaplingRoot=%s, nTime=%u, nBits=%08x, nNonce=%s, vtx=%u)\n", GetHash().ToString(), nVersion, hashPrevBlock.ToString(), hashMerkleRoot.ToString(), - hashSaplingAnchorEnd.ToString(), + hashFinalSaplingRoot.ToString(), nTime, nBits, nNonce.ToString(), vtx.size()); for (unsigned int i = 0; i < vtx.size(); i++) diff --git a/src/primitives/block.h b/src/primitives/block.h index 56288e10a..489d54711 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -26,7 +26,7 @@ public: int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; - uint256 hashSaplingAnchorEnd; + uint256 hashFinalSaplingRoot; uint32_t nTime; uint32_t nBits; uint256 nNonce; @@ -44,7 +44,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); - READWRITE(hashSaplingAnchorEnd); + READWRITE(hashFinalSaplingRoot); READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); @@ -56,7 +56,7 @@ public: nVersion = CBlockHeader::CURRENT_VERSION; hashPrevBlock.SetNull(); hashMerkleRoot.SetNull(); - hashSaplingAnchorEnd.SetNull(); + hashFinalSaplingRoot.SetNull(); nTime = 0; nBits = 0; nNonce = uint256(); @@ -118,7 +118,7 @@ public: block.nVersion = nVersion; block.hashPrevBlock = hashPrevBlock; block.hashMerkleRoot = hashMerkleRoot; - block.hashSaplingAnchorEnd = hashSaplingAnchorEnd; + block.hashFinalSaplingRoot = hashFinalSaplingRoot; block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; @@ -158,7 +158,7 @@ public: READWRITE(this->nVersion); READWRITE(hashPrevBlock); READWRITE(hashMerkleRoot); - READWRITE(hashSaplingAnchorEnd); + READWRITE(hashFinalSaplingRoot); READWRITE(nTime); READWRITE(nBits); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 59ebbdf94..f996c3551 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -303,7 +303,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->hashSproutAnchor = diskindex.hashSproutAnchor; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; - pindexNew->hashSaplingAnchorEnd = diskindex.hashSaplingAnchorEnd; + pindexNew->hashFinalSaplingRoot = diskindex.hashFinalSaplingRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; From e814be60fe8ce73b9b1506d5d910ea1faf496007 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 15:21:49 -0600 Subject: [PATCH 17/30] Rename hashSproutAnchorEnd to hashFinalSproutRoot to be consistent. --- src/chain.h | 4 ++-- src/main.cpp | 10 +++++----- src/rpcblockchain.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/chain.h b/src/chain.h index 76f535cea..017944bf8 100644 --- a/src/chain.h +++ b/src/chain.h @@ -155,7 +155,7 @@ public: uint256 hashSproutAnchor; //! (memory only) The anchor for the tree state up to the end of this block - uint256 hashSproutAnchorEnd; + uint256 hashFinalSproutRoot; //! Change in value held by the Sprout circuit over this block. //! Will be boost::none for older blocks on old nodes until a reindex has taken place. @@ -193,7 +193,7 @@ public: nStatus = 0; nCachedBranchId = boost::none; hashSproutAnchor = uint256(); - hashSproutAnchorEnd = uint256(); + hashFinalSproutRoot = uint256(); nSequenceId = 0; nSproutValue = boost::none; nChainSproutValue = boost::none; diff --git a/src/main.cpp b/src/main.cpp index 991e34110..931deb44c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2297,7 +2297,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin ZCIncrementalMerkleTree tree; pindex->hashSproutAnchor = tree.root(); // The genesis block contained no JoinSplits - pindex->hashSproutAnchorEnd = pindex->hashSproutAnchor; + pindex->hashFinalSproutRoot = pindex->hashSproutAnchor; } return true; } @@ -2413,7 +2413,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin view.PushSproutAnchor(tree); if (!fJustCheck) { - pindex->hashSproutAnchorEnd = tree.root(); + pindex->hashFinalSproutRoot = tree.root(); } blockundo.old_tree_root = old_tree_root; @@ -3932,7 +3932,7 @@ bool static LoadBlockIndexDB() // - This will miss chain tips; we handle the best tip below, and other // tips will be handled by ConnectTip during a re-org. if (pindex->pprev) { - pindex->pprev->hashSproutAnchorEnd = pindex->hashSproutAnchor; + pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor; } } @@ -3941,8 +3941,8 @@ bool static LoadBlockIndexDB() if (it == mapBlockIndex.end()) return true; chainActive.SetTip(it->second); - // Set hashSproutAnchorEnd for the end of best chain - it->second->hashSproutAnchorEnd = pcoinsTip->GetBestAnchor(SPROUT); + // Set hashFinalSproutRoot for the end of best chain + it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT); PruneBlockIndexCandidates(); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 1633c8b72..89ada7cff 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -155,7 +155,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("bits", strprintf("%08x", block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("anchor", blockindex->hashSproutAnchorEnd.GetHex())); + result.push_back(Pair("anchor", blockindex->hashFinalSproutRoot.GetHex())); UniValue valuePools(UniValue::VARR); valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue)); From 27616b9a045476e192c549b98ca494317953bfda Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 18:45:05 -0600 Subject: [PATCH 18/30] Add support for Sapling anchors in coins/txdb. --- src/coins.cpp | 125 ++++++++++++++++++++++++---------- src/coins.h | 32 ++++++++- src/gtest/test_mempool.cpp | 4 ++ src/gtest/test_validation.cpp | 4 ++ src/txdb.cpp | 45 ++++++++---- src/txdb.h | 2 + src/txmempool.cpp | 1 + 7 files changed, 163 insertions(+), 50 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 7f400ed44..5c01d8eba 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -43,6 +43,7 @@ bool CCoins::Spend(uint32_t nPos) return true; } bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } +bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { return false; } bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } @@ -53,6 +54,7 @@ bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } @@ -61,6 +63,7 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); } +bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); } bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } @@ -72,8 +75,9 @@ bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, - CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, mapSproutAnchors, mapSproutNullifiers, mapSaplingNullifiers); } + CNullifiersMap &mapSaplingNullifiers) { return base->BatchWrite(mapCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, mapSproutAnchors, mapSaplingAnchors, mapSproutNullifiers, mapSaplingNullifiers); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} @@ -88,6 +92,7 @@ CCoinsViewCache::~CCoinsViewCache() size_t CCoinsViewCache::DynamicMemoryUsage() const { return memusage::DynamicUsage(cacheCoins) + memusage::DynamicUsage(cacheSproutAnchors) + + memusage::DynamicUsage(cacheSaplingAnchors) + memusage::DynamicUsage(cacheSproutNullifiers) + memusage::DynamicUsage(cacheSaplingNullifiers) + cachedCoinsUsage; @@ -135,6 +140,29 @@ bool CCoinsViewCache::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTr return true; } +bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { + CAnchorsSaplingMap::const_iterator it = cacheSaplingAnchors.find(rt); + if (it != cacheSaplingAnchors.end()) { + if (it->second.entered) { + tree = it->second.tree; + return true; + } else { + return false; + } + } + + if (!base->GetSaplingAnchorAt(rt, tree)) { + return false; + } + + CAnchorsSaplingMap::iterator ret = cacheSaplingAnchors.insert(std::make_pair(rt, CAnchorsSaplingCacheEntry())).first; + ret->second.entered = true; + ret->second.tree = tree; + cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); + + return true; +} + bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) const { CNullifiersMap* cacheToUse; switch (type) { @@ -203,6 +231,24 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { ); } +template<> +void CCoinsViewCache::BringBestAnchorIntoCache( + const uint256 ¤tRoot, + ZCIncrementalMerkleTree &tree +) +{ + assert(GetSproutAnchorAt(currentRoot, tree)); +} + +template<> +void CCoinsViewCache::BringBestAnchorIntoCache( + const uint256 ¤tRoot, + ZCSaplingIncrementalMerkleTree &tree +) +{ + assert(GetSaplingAnchorAt(currentRoot, tree)); +} + template void CCoinsViewCache::AbstractPopAnchor( const uint256 &newrt, @@ -221,17 +267,7 @@ void CCoinsViewCache::AbstractPopAnchor( // so that its tree exists in memory. { Tree tree; - switch (type) { - case SPROUT: - assert(GetSproutAnchorAt(currentRoot, tree)); - break; - case SAPLING: - // TODO - assert(false); - break; - default: - throw std::runtime_error("Unknown shielded type " + type); - } + BringBestAnchorIntoCache(currentRoot, tree); } // Mark the anchor as unentered, removing it from view @@ -367,11 +403,45 @@ void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNu } } +template +void BatchWriteAnchors( + Map &mapAnchors, + Map &cacheAnchors, + size_t &cachedCoinsUsage +) +{ + for (MapIterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();) + { + if (child_it->second.flags & MapEntry::DIRTY) { + MapIterator parent_it = cacheAnchors.find(child_it->first); + + if (parent_it == cacheAnchors.end()) { + MapEntry& entry = cacheAnchors[child_it->first]; + entry.entered = child_it->second.entered; + entry.tree = child_it->second.tree; + entry.flags = MapEntry::DIRTY; + + cachedCoinsUsage += entry.tree.DynamicMemoryUsage(); + } else { + if (parent_it->second.entered != child_it->second.entered) { + // The parent may have removed the entry. + parent_it->second.entered = child_it->second.entered; + parent_it->second.flags |= MapEntry::DIRTY; + } + } + } + + MapIterator itOld = child_it++; + mapAnchors.erase(itOld); + } +} + bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, const uint256 &hashSproutAnchorIn, const uint256 &hashSaplingAnchorIn, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { assert(!hasModifier); @@ -410,30 +480,8 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, mapCoins.erase(itOld); } - for (CAnchorsSproutMap::iterator child_it = mapSproutAnchors.begin(); child_it != mapSproutAnchors.end();) - { - if (child_it->second.flags & CAnchorsSproutCacheEntry::DIRTY) { - CAnchorsSproutMap::iterator parent_it = cacheSproutAnchors.find(child_it->first); - - if (parent_it == cacheSproutAnchors.end()) { - CAnchorsSproutCacheEntry& entry = cacheSproutAnchors[child_it->first]; - entry.entered = child_it->second.entered; - entry.tree = child_it->second.tree; - entry.flags = CAnchorsSproutCacheEntry::DIRTY; - - cachedCoinsUsage += entry.tree.DynamicMemoryUsage(); - } else { - if (parent_it->second.entered != child_it->second.entered) { - // The parent may have removed the entry. - parent_it->second.entered = child_it->second.entered; - parent_it->second.flags |= CAnchorsSproutCacheEntry::DIRTY; - } - } - } - - CAnchorsSproutMap::iterator itOld = child_it++; - mapSproutAnchors.erase(itOld); - } + ::BatchWriteAnchors(mapSproutAnchors, cacheSproutAnchors, cachedCoinsUsage); + ::BatchWriteAnchors(mapSaplingAnchors, cacheSaplingAnchors, cachedCoinsUsage); ::BatchWriteNullifiers(mapSproutNullifiers, cacheSproutNullifiers); ::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers); @@ -445,9 +493,10 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, } bool CCoinsViewCache::Flush() { - bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); + bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSaplingAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); cacheCoins.clear(); cacheSproutAnchors.clear(); + cacheSaplingAnchors.clear(); cacheSproutNullifiers.clear(); cacheSaplingNullifiers.clear(); cachedCoinsUsage = 0; @@ -515,6 +564,8 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const return false; } + // TODO: Sapling anchor checks + return true; } diff --git a/src/coins.h b/src/coins.h index b8c41e5d7..11f758c34 100644 --- a/src/coins.h +++ b/src/coins.h @@ -286,6 +286,19 @@ struct CAnchorsSproutCacheEntry CAnchorsSproutCacheEntry() : entered(false), flags(0) {} }; +struct CAnchorsSaplingCacheEntry +{ + bool entered; // This will be false if the anchor is removed from the cache + ZCSaplingIncrementalMerkleTree tree; // The tree itself + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + }; + + CAnchorsSaplingCacheEntry() : entered(false), flags(0) {} +}; + struct CNullifiersCacheEntry { bool entered; // If the nullifier is spent or not @@ -306,6 +319,7 @@ enum ShieldedType typedef boost::unordered_map CCoinsMap; typedef boost::unordered_map CAnchorsSproutMap; +typedef boost::unordered_map CAnchorsSaplingMap; typedef boost::unordered_map CNullifiersMap; struct CCoinsStats @@ -326,9 +340,12 @@ struct CCoinsStats class CCoinsView { public: - //! Retrieve the tree at a particular anchored root in the chain + //! Retrieve the tree (Sprout) at a particular anchored root in the chain virtual bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + //! Retrieve the tree (Sapling) at a particular anchored root in the chain + virtual bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const; + //! Determine whether a nullifier is spent or not virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; @@ -352,6 +369,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -372,6 +390,7 @@ protected: public: CCoinsViewBacked(CCoinsView *viewIn); bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -383,6 +402,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); bool GetStats(CCoinsStats &stats) const; @@ -428,6 +448,7 @@ protected: mutable uint256 hashSproutAnchor; mutable uint256 hashSaplingAnchor; mutable CAnchorsSproutMap cacheSproutAnchors; + mutable CAnchorsSaplingMap cacheSaplingAnchors; mutable CNullifiersMap cacheSproutNullifiers; mutable CNullifiersMap cacheSaplingNullifiers; @@ -440,6 +461,7 @@ public: // Standard CCoinsView methods bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -451,6 +473,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); @@ -542,6 +565,13 @@ private: Cache &cacheAnchors, uint256 &hash ); + + //! Interface for bringing an anchor into the cache. + template + void BringBestAnchorIntoCache( + const uint256 ¤tRoot, + Tree &tree + ); }; #endif // BITCOIN_COINS_H diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 1d5999de2..2056950b6 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -23,6 +23,10 @@ public: return false; } + bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { + return false; + } + bool GetNullifier(const uint256 &nf, ShieldedType type) const { return false; } diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index b76c3e77d..2198f592c 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -25,6 +25,10 @@ public: return false; } + bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { + return false; + } + bool GetNullifier(const uint256 &nf, ShieldedType type) const { return false; } diff --git a/src/txdb.cpp b/src/txdb.cpp index f996c3551..68424b226 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -18,6 +18,7 @@ using namespace std; static const char DB_SPROUT_ANCHOR = 'A'; +static const char DB_SAPLING_ANCHOR = 'X'; static const char DB_NULLIFIER = 's'; static const char DB_SAPLING_NULLIFIER = 'S'; static const char DB_COINS = 'c'; @@ -53,6 +54,18 @@ bool CCoinsViewDB::GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree return read; } +bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const { + if (rt == ZCSaplingIncrementalMerkleTree::empty_root()) { + ZCSaplingIncrementalMerkleTree new_tree; + tree = new_tree; + return true; + } + + bool read = db.Read(make_pair(DB_SAPLING_ANCHOR, rt), tree); + + return read; +} + bool CCoinsViewDB::GetNullifier(const uint256 &nf, ShieldedType type) const { bool spent = false; char dbChar; @@ -118,11 +131,29 @@ void BatchWriteNullifiers(CDBBatch& batch, CNullifiersMap& mapToUse, const char& } } +template +void BatchWriteAnchors(CDBBatch& batch, Map& mapToUse, const char& dbChar) +{ + for (MapIterator it = mapToUse.begin(); it != mapToUse.end();) { + if (it->second.flags & MapEntry::DIRTY) { + if (!it->second.entered) + batch.Erase(make_pair(dbChar, it->first)); + else { + batch.Write(make_pair(dbChar, it->first), it->second.tree); + } + // TODO: changed++? + } + MapIterator itOld = it++; + mapToUse.erase(itOld); + } +} + bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { CDBBatch batch(db); @@ -141,18 +172,8 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, mapCoins.erase(itOld); } - for (CAnchorsSproutMap::iterator it = mapSproutAnchors.begin(); it != mapSproutAnchors.end();) { - if (it->second.flags & CAnchorsSproutCacheEntry::DIRTY) { - if (!it->second.entered) - batch.Erase(make_pair(DB_SPROUT_ANCHOR, it->first)); - else { - batch.Write(make_pair(DB_SPROUT_ANCHOR, it->first), it->second.tree); - } - // TODO: changed++? - } - CAnchorsSproutMap::iterator itOld = it++; - mapSproutAnchors.erase(itOld); - } + ::BatchWriteAnchors(batch, mapSproutAnchors, DB_SPROUT_ANCHOR); + ::BatchWriteAnchors(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR); ::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER); ::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER); diff --git a/src/txdb.h b/src/txdb.h index d97f18303..e8d8ed899 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -36,6 +36,7 @@ public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool GetSproutAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; + bool GetSaplingAnchorAt(const uint256 &rt, ZCSaplingIncrementalMerkleTree &tree) const; bool GetNullifier(const uint256 &nf, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -46,6 +47,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers); bool GetStats(CCoinsStats &stats) const; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a7fc3d1f7..2a96ecac9 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -413,6 +413,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const intermediates.insert(std::make_pair(tree.root(), tree)); } for (const SpendDescription &spendDescription : tx.vShieldedSpend) { + // TODO: anchor check assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING)); } if (fDependsWait) From c643ff0b51cbdf910ebb339289a90e08cdf3c862 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 19:05:11 -0600 Subject: [PATCH 19/30] Add support for PopAnchor(.., SPROUT/SAPLING) --- src/coins.cpp | 28 +++++++++++++++++++++------- src/coins.h | 2 +- src/main.cpp | 2 +- src/test/coins_tests.cpp | 14 +++++++------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 5c01d8eba..29172cb9f 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -281,13 +281,27 @@ void CCoinsViewCache::AbstractPopAnchor( } } -void CCoinsViewCache::PopAnchor(const uint256 &newrt) { - AbstractPopAnchor( - newrt, - SPROUT, - cacheSproutAnchors, - hashSproutAnchor - ); +void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) { + switch (type) { + case SPROUT: + AbstractPopAnchor( + newrt, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); + break; + case SAPLING: + AbstractPopAnchor( + newrt, + SAPLING, + cacheSaplingAnchors, + hashSaplingAnchor + ); + break; + default: + throw std::runtime_error("Unknown shielded type " + type); + } } void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) { diff --git a/src/coins.h b/src/coins.h index 11f758c34..513f9140b 100644 --- a/src/coins.h +++ b/src/coins.h @@ -484,7 +484,7 @@ public: // Removes the current commitment root from mapAnchors and sets // the new current root. - void PopAnchor(const uint256 &rt); + void PopAnchor(const uint256 &rt, ShieldedType type); // Marks nullifiers for a given transaction as spent or not. void SetNullifiers(const CTransaction& tx, bool spent); diff --git a/src/main.cpp b/src/main.cpp index 931deb44c..6a409402c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2150,7 +2150,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex } // set the old best anchor back - view.PopAnchor(blockUndo.old_tree_root); + view.PopAnchor(blockUndo.old_tree_root, SPROUT); // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index daae2e009..b7f7f6efd 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -344,7 +344,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); // Remove the anchor - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache1.Flush(); // Add the anchor back @@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(anchor_pop_regression_test) cache1.Flush(); // Remove the anchor, but don't flush yet! - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); { CCoinsViewCacheTest cache2(&cache1); // Build cache on top @@ -416,7 +416,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PushSproutAnchor(tree); cache1.Flush(); - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); } @@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) cache1.PushSproutAnchor(tree); cache1.Flush(); - cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache1.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache1.Flush(); BOOST_CHECK(cache1.GetBestAnchor(SPROUT) == ZCIncrementalMerkleTree::empty_root()); BOOST_CHECK(!cache1.GetSproutAnchorAt(tree.root(), tree)); @@ -455,7 +455,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) // Pop anchor. CCoinsViewCacheTest cache2(&cache1); BOOST_CHECK(cache2.GetSproutAnchorAt(tree.root(), tree)); - cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache2.Flush(); } @@ -478,7 +478,7 @@ BOOST_AUTO_TEST_CASE(anchor_regression_test) { // Pop anchor. CCoinsViewCacheTest cache2(&cache1); - cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root()); + cache2.PopAnchor(ZCIncrementalMerkleTree::empty_root(), SPROUT); cache2.Flush(); } @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) } { - cache.PopAnchor(newrt); + cache.PopAnchor(newrt, SPROUT); ZCIncrementalMerkleTree obtain_tree; assert(!cache.GetSproutAnchorAt(newrt2, obtain_tree)); // should have been popped off assert(cache.GetSproutAnchorAt(newrt, obtain_tree)); From 85b39f57bba852542c7b76423576af6a4aa405b2 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 21:38:45 -0600 Subject: [PATCH 20/30] Add `PushSaplingAnchor` --- src/coins.cpp | 9 +++++++++ src/coins.h | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/coins.cpp b/src/coins.cpp index 29172cb9f..c8b98d428 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -231,6 +231,15 @@ void CCoinsViewCache::PushSproutAnchor(const ZCIncrementalMerkleTree &tree) { ); } +void CCoinsViewCache::PushSaplingAnchor(const ZCSaplingIncrementalMerkleTree &tree) { + AbstractPushAnchor( + tree, + SAPLING, + cacheSaplingAnchors, + hashSaplingAnchor + ); +} + template<> void CCoinsViewCache::BringBestAnchorIntoCache( const uint256 ¤tRoot, diff --git a/src/coins.h b/src/coins.h index 513f9140b..bd5105024 100644 --- a/src/coins.h +++ b/src/coins.h @@ -478,10 +478,14 @@ public: CNullifiersMap &mapSaplingNullifiers); - // Adds the tree to mapAnchors and sets the current commitment + // Adds the tree to mapSproutAnchors and sets the current commitment // root to this root. void PushSproutAnchor(const ZCIncrementalMerkleTree &tree); + // Adds the tree to mapSaplingAnchors and sets the current commitment + // root to this root. + void PushSaplingAnchor(const ZCSaplingIncrementalMerkleTree &tree); + // Removes the current commitment root from mapAnchors and sets // the new current root. void PopAnchor(const uint256 &rt, ShieldedType type); From 1f8be05b635661a2f5472dda6c96be624d58dbcb Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 23:27:52 -0600 Subject: [PATCH 21/30] Add consensus support for Sapling merkle trees. --- src/chain.cpp | 7 ------- src/chain.h | 3 --- src/coins.cpp | 7 +++++-- src/main.cpp | 51 ++++++++++++++++++++++++++++++++++++++++----------- src/undo.h | 4 ++-- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index c9c787900..39520cc8f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -7,13 +7,6 @@ using namespace std; -uint256 CBlockIndex::GetSaplingAnchorEnd() const { - // TODO: The block header's hashFinalSaplingRoot is only guaranteed to - // be valid on or after the Sapling activation height. - - return hashFinalSaplingRoot; -} - /** * CChain implementation */ diff --git a/src/chain.h b/src/chain.h index 017944bf8..b5a1a3ba6 100644 --- a/src/chain.h +++ b/src/chain.h @@ -321,9 +321,6 @@ public: //! Efficiently find an ancestor of this block. CBlockIndex* GetAncestor(int height); const CBlockIndex* GetAncestor(int height) const; - - //! Get the root of the Sapling merkle tree (at the end of this block) - uint256 GetSaplingAnchorEnd() const; }; /** Used to marshal pointers into hashes for db storage. */ diff --git a/src/coins.cpp b/src/coins.cpp index c8b98d428..42209539e 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -585,9 +585,12 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const for (const SpendDescription &spendDescription : tx.vShieldedSpend) { if (GetNullifier(spendDescription.nullifier, SAPLING)) // Prevent double spends return false; - } - // TODO: Sapling anchor checks + ZCSaplingIncrementalMerkleTree tree; + if (!GetSaplingAnchorAt(spendDescription.anchor, tree)) { + return false; + } + } return true; } diff --git a/src/main.cpp b/src/main.cpp index 6a409402c..2851fbbbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2149,8 +2149,19 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex } } - // set the old best anchor back - view.PopAnchor(blockUndo.old_tree_root, SPROUT); + // set the old best Sprout anchor back + view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT); + + // set the old best Sapling anchor back + // We can get this from the `hashFinalSaplingRoot` of the last block + // However, this is only reliable if the last block was on or after + // the Sapling activation height. Otherwise, the last anchor was the + // empty root. + if (NetworkUpgradeActive(pindex->pprev->nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING); + } else { + view.PopAnchor(ZCSaplingIncrementalMerkleTree::empty_root(), SAPLING); + } // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); @@ -2330,22 +2341,25 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Construct the incremental merkle tree at the current // block position, - auto old_tree_root = view.GetBestAnchor(SPROUT); + auto old_sprout_tree_root = view.GetBestAnchor(SPROUT); // saving the top anchor in the block index as we go. if (!fJustCheck) { - pindex->hashSproutAnchor = old_tree_root; + pindex->hashSproutAnchor = old_sprout_tree_root; } - ZCIncrementalMerkleTree tree; + ZCIncrementalMerkleTree sprout_tree; // This should never fail: we should always be able to get the root // that is on the tip of our chain - assert(view.GetSproutAnchorAt(old_tree_root, tree)); + assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree)); { // Consistency check: the root of the tree we're given should // match what we asked for. - assert(tree.root() == old_tree_root); + assert(sprout_tree.root() == old_sprout_tree_root); } + ZCSaplingIncrementalMerkleTree sapling_tree; + assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); + // Grab the consensus branch ID for the block's height auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus()); @@ -2403,19 +2417,34 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) { // Insert the note commitments into our temporary tree. - tree.append(note_commitment); + sprout_tree.append(note_commitment); } } + BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) { + sapling_tree.append(outputDescription.cm); + } + vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - view.PushSproutAnchor(tree); + view.PushSproutAnchor(sprout_tree); + view.PushSaplingAnchor(sapling_tree); if (!fJustCheck) { - pindex->hashFinalSproutRoot = tree.root(); + pindex->hashFinalSproutRoot = sprout_tree.root(); + } + blockundo.old_sprout_tree_root = old_sprout_tree_root; + + // If Sapling is active, block.hashFinalSaplingRoot must be the + // same as the root of the Sapling tree + if (NetworkUpgradeActive(pindex->nHeight, chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) { + if (block.hashFinalSaplingRoot != sapling_tree.root()) { + return state.DoS(100, + error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"), + REJECT_INVALID, "bad-sapling-root-in-block"); + } } - blockundo.old_tree_root = old_tree_root; int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart; LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); diff --git a/src/undo.h b/src/undo.h index e01814e72..fbb350e60 100644 --- a/src/undo.h +++ b/src/undo.h @@ -67,14 +67,14 @@ class CBlockUndo { public: std::vector vtxundo; // for all but the coinbase - uint256 old_tree_root; + uint256 old_sprout_tree_root; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(vtxundo); - READWRITE(old_tree_root); + READWRITE(old_sprout_tree_root); } }; From b4ff7076056bf2be63629a467da49b741d0ff0d3 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 23:29:29 -0600 Subject: [PATCH 22/30] Add support for Sapling anchor checks in mempool consistency checks. --- src/txmempool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 2a96ecac9..a9a33602f 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -413,7 +413,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const intermediates.insert(std::make_pair(tree.root(), tree)); } for (const SpendDescription &spendDescription : tx.vShieldedSpend) { - // TODO: anchor check + ZCSaplingIncrementalMerkleTree tree; + + assert(pcoins->GetSaplingAnchorAt(spendDescription.anchor, tree)); assert(!pcoins->GetNullifier(spendDescription.nullifier, SAPLING)); } if (fDependsWait) From 31a04d2875afa57cc82b89ac524002a4cf67cd01 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sun, 6 May 2018 23:37:48 -0600 Subject: [PATCH 23/30] Calculate the correct hashFinalSaplingRoot in the miner. --- src/miner.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 41b54ad36..7c6e4140a 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -149,6 +149,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); CCoinsViewCache view(pcoinsTip); + ZCSaplingIncrementalMerkleTree sapling_tree; + assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); + // Priority order to process transactions list vOrphan; // list memory doesn't move map > mapDependers; @@ -301,6 +304,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) UpdateCoins(tx, view, nHeight); + BOOST_FOREACH(const OutputDescription &outDescription, tx.vShieldedOutput) { + sapling_tree.append(outDescription.cm); + } + // Added pblock->vtx.push_back(tx); pblocktemplate->vTxFees.push_back(nTxFees); @@ -374,7 +381,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - pblock->hashFinalSaplingRoot = uint256(); // TODO + pblock->hashFinalSaplingRoot = sapling_tree.root(); UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nSolution.clear(); From 673a0a79b382753b6194dbaa96ddd592c33a4f33 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 00:00:39 -0600 Subject: [PATCH 24/30] Adjust tests to handle Sapling anchor cache --- src/gtest/test_mempool.cpp | 1 + src/gtest/test_validation.cpp | 1 + src/test/coins_tests.cpp | 31 +++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index 2056950b6..1fd4cd7e7 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -61,6 +61,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap &mapSaplingNullifiers) { return false; diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp index 2198f592c..8609c93ba 100644 --- a/src/gtest/test_validation.cpp +++ b/src/gtest/test_validation.cpp @@ -56,6 +56,7 @@ public: const uint256 &hashSproutAnchor, const uint256 &hashSaplingAnchor, CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSproutNullifiers, CNullifiersMap saplingNullifiersMap) { return false; diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index b7f7f6efd..6f391b7ac 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -29,6 +29,7 @@ class CCoinsViewTest : public CCoinsView uint256 hashBestSaplingAnchor_; std::map map_; std::map mapSproutAnchors_; + std::map mapSaplingAnchors_; std::map mapSproutNullifiers_; std::map mapSaplingNullifiers_; @@ -54,6 +55,22 @@ public: } } + bool GetSaplingAnchorAt(const uint256& rt, ZCSaplingIncrementalMerkleTree &tree) const { + if (rt == ZCSaplingIncrementalMerkleTree::empty_root()) { + ZCSaplingIncrementalMerkleTree new_tree; + tree = new_tree; + return true; + } + + std::map::const_iterator it = mapSaplingAnchors_.find(rt); + if (it == mapSaplingAnchors_.end()) { + return false; + } else { + tree = it->second; + return true; + } + } + bool GetNullifier(const uint256 &nf, ShieldedType type) const { const std::map* mapToUse; @@ -130,6 +147,7 @@ public: const uint256& hashSproutAnchor, const uint256& hashSaplingAnchor, CAnchorsSproutMap& mapSproutAnchors, + CAnchorsSaplingMap& mapSaplingAnchors, CNullifiersMap& mapSproutNullifiers, CNullifiersMap& mapSaplingNullifiers) { @@ -152,12 +170,24 @@ public: } mapSproutAnchors.erase(it++); } + for (CAnchorsSaplingMap::iterator it = mapSaplingAnchors.begin(); it != mapSaplingAnchors.end(); ) { + if (it->second.entered) { + std::map::iterator ret = + mapSaplingAnchors_.insert(std::make_pair(it->first, ZCSaplingIncrementalMerkleTree())).first; + + ret->second = it->second.tree; + } else { + mapSaplingAnchors_.erase(it->first); + } + mapSaplingAnchors.erase(it++); + } BatchWriteNullifiers(mapSproutNullifiers, mapSproutNullifiers_); BatchWriteNullifiers(mapSaplingNullifiers, mapSaplingNullifiers_); mapCoins.clear(); mapSproutAnchors.clear(); + mapSaplingAnchors.clear(); hashBestBlock_ = hashBlock; hashBestSproutAnchor_ = hashSproutAnchor; hashBestSaplingAnchor_ = hashSaplingAnchor; @@ -177,6 +207,7 @@ public: // Manually recompute the dynamic usage of the whole data, and compare it. size_t ret = memusage::DynamicUsage(cacheCoins) + memusage::DynamicUsage(cacheSproutAnchors) + + memusage::DynamicUsage(cacheSaplingAnchors) + memusage::DynamicUsage(cacheSproutNullifiers) + memusage::DynamicUsage(cacheSaplingNullifiers); for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { From 98d2f090cac1058480816f01cdbf253cc2a3f436 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 00:16:14 -0600 Subject: [PATCH 25/30] Evict transactions with obsolete anchors from the mempool --- src/main.cpp | 15 +++++++++++---- src/txmempool.cpp | 27 +++++++++++++++++++++------ src/txmempool.h | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2851fbbbb..1a619e297 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2687,7 +2687,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { if (!ReadBlockFromDisk(block, pindexDelete)) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. - uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT); + uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT); + uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING); int64_t nStart = GetTimeMicros(); { CCoinsViewCache view(pcoinsTip); @@ -2696,7 +2697,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { assert(view.Flush()); } LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); - uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT); + uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT); + uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING); // Write the chain state to disk, if necessary. if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; @@ -2710,10 +2712,15 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) mempool.remove(tx, removed, true); } - if (anchorBeforeDisconnect != anchorAfterDisconnect) { + if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) { // The anchor may not change between block disconnects, // in which case we don't want to evict from the mempool yet! - mempool.removeWithAnchor(anchorBeforeDisconnect); + mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT); + } + if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) { + // The anchor may not change between block disconnects, + // in which case we don't want to evict from the mempool yet! + mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING); } } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a9a33602f..6debd55b8 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -206,7 +206,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem } -void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot) +void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot, ShieldedType type) { // If a block is disconnected from the tip, and the root changed, // we must invalidate transactions from the mempool which spend @@ -217,11 +217,26 @@ void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot) for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { - if (joinsplit.anchor == invalidRoot) { - transactionsToRemove.push_back(tx); - break; - } + switch (type) { + case SPROUT: + BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { + if (joinsplit.anchor == invalidRoot) { + transactionsToRemove.push_back(tx); + break; + } + } + break; + case SAPLING: + BOOST_FOREACH(const SpendDescription& spendDescription, tx.vShieldedSpend) { + if (spendDescription.anchor == invalidRoot) { + transactionsToRemove.push_back(tx); + break; + } + } + break; + default: + throw runtime_error("Unknown shielded type " + type); + break; } } diff --git a/src/txmempool.h b/src/txmempool.h index f37636efb..ec8a8518a 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -169,7 +169,7 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); - void removeWithAnchor(const uint256 &invalidRoot); + void removeWithAnchor(const uint256 &invalidRoot, ShieldedType type); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); void removeExpired(unsigned int nBlockHeight); From e390a475c1484af519a4cc51d4d055505985c7f3 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 13:43:55 -0600 Subject: [PATCH 26/30] Fix outdated comment --- src/coins.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 42209539e..508401ade 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -201,9 +201,9 @@ void CCoinsViewCache::AbstractPushAnchor( auto currentRoot = GetBestAnchor(type); // We don't want to overwrite an anchor we already have. - // This occurs when a block doesn't modify mapSproutAnchors at all, + // This occurs when a block doesn't modify mapAnchors at all, // because there are no joinsplits. We could get around this a - // different way (make all blocks modify mapSproutAnchors somehow) + // different way (make all blocks modify mapAnchors somehow) // but this is simpler to reason about. if (currentRoot != newrt) { auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CacheEntry())); From 8c57bbac15728655363449320375b9f1892a0d42 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 13:49:17 -0600 Subject: [PATCH 27/30] Fix broken error messages. --- src/coins.cpp | 6 +++--- src/test/coins_tests.cpp | 4 ++-- src/txdb.cpp | 4 ++-- src/txmempool.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 508401ade..0ae74af1d 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -173,7 +173,7 @@ bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) cacheToUse = &cacheSaplingNullifiers; break; default: - throw std::runtime_error("Unknown nullifier type"); + throw std::runtime_error("Unknown shielded type"); } CNullifiersMap::iterator it = cacheToUse->find(nullifier); if (it != cacheToUse->end()) @@ -309,7 +309,7 @@ void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) { ); break; default: - throw std::runtime_error("Unknown shielded type " + type); + throw std::runtime_error("Unknown shielded type"); } } @@ -396,7 +396,7 @@ uint256 CCoinsViewCache::GetBestAnchor(ShieldedType type) const { return hashSaplingAnchor; break; default: - throw std::runtime_error("Unknown shielded type " + type); + throw std::runtime_error("Unknown shielded type"); } } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 6f391b7ac..c1bd8a553 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -82,7 +82,7 @@ public: mapToUse = &mapSaplingNullifiers_; break; default: - throw std::runtime_error("Unknown nullifier type"); + throw std::runtime_error("Unknown shielded type"); } std::map::const_iterator it = mapToUse->find(nf); if (it == mapToUse->end()) { @@ -103,7 +103,7 @@ public: return hashBestSaplingAnchor_; break; default: - throw std::runtime_error("Unknown shielded type " + type); + throw std::runtime_error("Unknown shielded type"); } } diff --git a/src/txdb.cpp b/src/txdb.cpp index 68424b226..0f1382e6c 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -77,7 +77,7 @@ bool CCoinsViewDB::GetNullifier(const uint256 &nf, ShieldedType type) const { dbChar = DB_SAPLING_NULLIFIER; break; default: - throw runtime_error("Unknown nullifier type"); + throw runtime_error("Unknown shielded type"); } return db.Read(make_pair(dbChar, nf), spent); } @@ -110,7 +110,7 @@ uint256 CCoinsViewDB::GetBestAnchor(ShieldedType type) const { return ZCSaplingIncrementalMerkleTree::empty_root(); break; default: - throw runtime_error("Unknown shielded type " + type); + throw runtime_error("Unknown shielded type"); } return hashBestAnchor; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6debd55b8..703806667 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -235,7 +235,7 @@ void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot, ShieldedType type) } break; default: - throw runtime_error("Unknown shielded type " + type); + throw runtime_error("Unknown shielded type"); break; } } From f6f97dfb1c9dabcfeb495aba24bdc71aa1216093 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 14:30:20 -0600 Subject: [PATCH 28/30] Fix miner tests --- src/test/miner_tests.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 152919510..3f6a0af77 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -260,6 +260,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) } */ + // These tests assume null hashFinalSaplingRoot (before Sapling) + pblock->hashFinalSaplingRoot = uint256(); + CValidationState state; BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); BOOST_CHECK_MESSAGE(state.IsValid(), state.GetRejectReason()); From fcbe7eef8dd5be61bd1275022c8316c3a6d61549 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 18:56:55 -0600 Subject: [PATCH 29/30] Update sapling-crypto and librustzcash --- depends/packages/crate_sapling_crypto.mk | 4 ++-- depends/packages/librustzcash.mk | 4 ++-- depends/patches/librustzcash/cargo.config | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/depends/packages/crate_sapling_crypto.mk b/depends/packages/crate_sapling_crypto.mk index 376fca9a3..2a721ab27 100644 --- a/depends/packages/crate_sapling_crypto.mk +++ b/depends/packages/crate_sapling_crypto.mk @@ -3,8 +3,8 @@ $(package)_crate_name=sapling-crypto $(package)_download_path=https://github.com/zcash-hackworks/$($(package)_crate_name)/archive/ $(package)_file_name=$(package)-$($(package)_git_commit).tar.gz $(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=5eb4040bc223a689341b3f1a1fc53d6064c4c032b23ae0c2c653b063e1da24db -$(package)_git_commit=e554b473dd10885d232f42237c13282f5b6fee43 +$(package)_sha256_hash=5062b9e752066ad959f14063d496b0a156ce96004a13a6823494249793c01f96 +$(package)_git_commit=7beeb52730e24724ee10ea2458ecf7776cb59c58 $(package)_crate_versioned_name=$($(package)_crate_name) define $(package)_preprocess_cmds diff --git a/depends/packages/librustzcash.mk b/depends/packages/librustzcash.mk index b08cd2c83..96f3143d1 100644 --- a/depends/packages/librustzcash.mk +++ b/depends/packages/librustzcash.mk @@ -3,8 +3,8 @@ $(package)_version=0.1 $(package)_download_path=https://github.com/zcash/$(package)/archive/ $(package)_file_name=$(package)-$($(package)_git_commit).tar.gz $(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=b63ba98d569d332764f27706038c04d03ac7e2c836dc15dc4eaa24b04b8c7f4a -$(package)_git_commit=6cc1813ae3bb1e42224fd8ca0a8977b95c576738 +$(package)_sha256_hash=c5442a57d8961aab12fd395a5004edbb96b973511fab3949a087faa2a865a002 +$(package)_git_commit=ef676eff5084d394e6c6eaf2b9d9817effe662a7 $(package)_dependencies=rust $(rust_crates) $(package)_patches=cargo.config diff --git a/depends/patches/librustzcash/cargo.config b/depends/patches/librustzcash/cargo.config index c0229a9cc..23e6b808a 100644 --- a/depends/patches/librustzcash/cargo.config +++ b/depends/patches/librustzcash/cargo.config @@ -8,7 +8,7 @@ replace-with = "vendored-sources" [source."https://github.com/zcash-hackworks/sapling-crypto"] git = "https://github.com/zcash-hackworks/sapling-crypto" -rev = "e554b473dd10885d232f42237c13282f5b6fee43" +rev = "7beeb52730e24724ee10ea2458ecf7776cb59c58" replace-with = "vendored-sources" [source.vendored-sources] From 40bfb9e5b90db9e34fe1799dda7e8667465627a8 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Mon, 7 May 2018 18:57:04 -0600 Subject: [PATCH 30/30] Swap bit endianness of test vectors --- src/gtest/test_merkletree.cpp | 2 +- src/gtest/test_pedersen_hash.cpp | 6 +- src/test/data/merkle_commitments_sapling.json | 32 +-- src/test/data/merkle_path_sapling.json | 240 ++++++++-------- src/test/data/merkle_roots_empty_sapling.json | 126 ++++---- src/test/data/merkle_roots_sapling.json | 32 +-- .../data/merkle_serialization_sapling.json | 32 +-- .../merkle_witness_serialization_sapling.json | 272 +++++++++--------- 8 files changed, 371 insertions(+), 371 deletions(-) diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index 8b453a90f..166bbaf6d 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -261,7 +261,7 @@ TEST(merkletree, EmptyrootSapling) { // This literal is the depth-20 empty tree root with the bytes reversed to // account for the fact that uint256S() loads a big-endian representation of // an integer which converted to little-endian internally. - uint256 expected = uint256S("56f5903dbfe4e7356e55f13b2e6e3180a8f7056c7d8814511f797487b398ee42"); + uint256 expected = uint256S("427719cde12e9ef88a2811be36a0ef15018c7674dc8faa76ace727fdbc09af6a"); ASSERT_TRUE(ZCSaplingIncrementalMerkleTree::empty_root() == expected); } diff --git a/src/gtest/test_pedersen_hash.cpp b/src/gtest/test_pedersen_hash.cpp index 7a9eb04fd..608d8b448 100644 --- a/src/gtest/test_pedersen_hash.cpp +++ b/src/gtest/test_pedersen_hash.cpp @@ -3,13 +3,13 @@ #include "uint256.h" TEST(PedersenHash, TestAPI) { - const uint256 a = uint256S("0acaa62d40fcdd9192ed35ea9df31660ccf7f6c60566530faaa444fb5d0d410e"); - const uint256 b = uint256S("6041357de59ba64959d1b60f93de24dfe5ea1e26ed9e8a73d35b225a1845ba70"); + const uint256 a = uint256S("7082b0badf222555f0ca66a0636fef330668cfb957acb74989bb3f02b4655350"); + const uint256 b = uint256S("0e5da2185a44dacbce5179b7647857a7fb247bc9f06d8b9a9265d9a7beac8206"); uint256 result; librustzcash_merkle_hash(25, a.begin(), b.begin(), result.begin()); - uint256 expected_result = uint256S("4253b36834b3f64cc6182f1816911e1c9460cb88afeafb155244dd0038ad4717"); + uint256 expected_result = uint256S("e8e2b51c00bb224aa8df57f511d306293878896818f41863326fcd2c16cdca42"); ASSERT_TRUE(result == expected_result); } diff --git a/src/test/data/merkle_commitments_sapling.json b/src/test/data/merkle_commitments_sapling.json index 00a2de809..2303b5026 100644 --- a/src/test/data/merkle_commitments_sapling.json +++ b/src/test/data/merkle_commitments_sapling.json @@ -1,18 +1,18 @@ [ - "0dc4084f07e1a7dabfe0f77a2474dce177ba0093d54a6f78d62ba4429f5cf6aa", - "44eae2cfadab5b2da725241ff8a19320ffc21476f0fc0b7e0f1d6365e48d281b", - "3e7c0558765cbc09f39ab31e79620e22adb31ed734213316689f062eb670c037", - "0a42b8363429eab85f55c85af28fda9f681678bd4603277c96c79d60210b050d", - "5537c6615c55d074dc019042d9bbbba27a9a7df60233d5115e4cd7194e7c3f49", - "1fe6122b307aa79fa526f2743e1f59a5267a51009b87b2f28bc95b50c4bbe06f", - "3d517ae368e2823a1c40c06d81ef8ece66cf0a68868a44a46d3b7c48783fd075", - "5b58bb45337bc98187888a16364878fe4a8b5999209c68387ead959fd2a7a589", - "5ce47fabdb3de2ba1c016c701cc63111f49b4dce6d183fc28c609106c1ef2e63", - "1353f1beefbf999e0cf41ca13b9bd58176021fab8825d10591d822064dbdb83e", - "0f5fec1760dcc8b92c446228f423713e300a0b6534e96ea1910726662e34ec40", - "672beb161a290bd84cef0781d518910c7d36d4f96e6b21defe1c74bcbbeb6310", - "31d7eddc17c162b618cb0d0396094a70019d6c225034f98b219b54f860231765", - "445f1d3ddb11a8b2fd1aeeb578b4fed82ad813a537d84a6406a91cc89c433ec1", - "2f7c5c3586a7e5ca60b4b2a010433657af2703a3d1c5936a8720ad4bf3e62338", - "5c6c863d48ed646293d26393e4691798ca197a67b40195376ca29595ea0235a8" + "556f3af94225d46b1ef652abc9005dee873b2e245eef07fd5be587e0f21023b0", + "d814b127a6c6b8f07ed03f0f6e2843ff04c9851ff824a4e5b4dad5b5f3475722", + "ec030e6d7460f91668cc842ceb78cdb54470469e78cd59cf903d3a6e1aa03e7c", + "b0a0d08406b9e3693ee4c062bd1e6816f95bf14f5a13aafa1d57942c6c1d4250", + "92fc3e7298eb327a88abcc406fbe595e45dddd9b4209803b2e0baa3a8663ecaa", + "f607dd230ada93d14f4de1d9008a5e64a59af87c2e4f64a5f9e55e0cd44867f8", + "ae0bfc1e123edcb6252251611650f3667371f781b60302385c414716c75e8abc", + "91a5e54bf9a9b57e1c163904999ad1527f1e126c685111e18193decca2dd1ada", + "c674f7836089063143fc18b673b2d92f888c63380e3680385d47bcdbd5fe273a", + "7c1dbdb260441b89a08ba411d5f8406e81abd9dc85382f307999fdf77d8fcac8", + "02372c746664e0898576972ca6d0500c7c8ec42f144622349d133b06e837faf0", + "08c6d7dd3d2e387f7b84d6769f2b6cbe308918ab81e0f7321bd0945868d7d4e6", + "a6e8c4061f2ad984d19f2c0a4436b9800e529069c0b0d3186d4683e83bb7eb8c", + "837cc2391338956026521beca5c81b541b7f2d1ead7758bf4d1588dbbcb8fa22", + "1cc467cfd2b504e156c9a38bc5c0e4f5ea6cc208054d2d0653a7e561ac3a3ef4", + "15ac4057a9a94536eca9802de65e985319e89627c9c64bc94626b712bc61363a" ] diff --git a/src/test/data/merkle_path_sapling.json b/src/test/data/merkle_path_sapling.json index b4b9118b4..847625164 100644 --- a/src/test/data/merkle_path_sapling.json +++ b/src/test/data/merkle_path_sapling.json @@ -1,122 +1,122 @@ [ - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820546d643b52f4193e63bb3cf0bfb51466013e8ae17f447cf848df22b12a0f2a03201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820546d643b52f4193e63bb3cf0bfb51466013e8ae17f447cf848df22b12a0f2a0320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a0205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a0205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a020531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b44320043bdc4c4d6be93e04bfd343d505600a2cd69c2292495dfa71ac9dff9a6f20a020531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce20531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432022039314b35fb24b7f99d9667840f4606324e0d6f48ffa912d78a9629c68a8ce20531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a923205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a923205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a92320531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432055ededc6088d5a46e08b0bbe788ce884c5e21d77c17bf84e5e11ddd9ebb4a92320531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982063ca4ecc29131ee8be94a5b198f3c6ea30aa2204dafc4cc9bfb9b74de2608523206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982063ca4ecc29131ee8be94a5b198f3c6ea30aa2204dafc4cc9bfb9b74de260852320493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b4432071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "0420690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "042038c3c924e2bc52bfe70e170ce8921a25557fbceb1bcde9bd230281b92a7e88fc206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd762071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "04205b9fb83603f040418c255ec57558a5e38373bcac4f61f73ff6ff03e46518cd76206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "0420126dd50dcc2a50b0b8d46dc5836bb2bd93dc922d1248db8ff5dc73c2d9addd1e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8206e1eb21c1bd59e43c9dce633d56130ca98b863ee439f4467d0b36d3701b8b893203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8206e1eb21c1bd59e43c9dce633d56130ca98b863ee439f4467d0b36d3701b8b89320632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db3640312071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "042006420ba434081b6734c6e1f2a228a9c10f13d5e9cf2c56b037bc1950db364031206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6206843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee62071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "04203cc0805e780a406ba965be365c44e3d1ac676b4ecb1cba74f90d48685e043ee6206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e20081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e20081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6203ffb6fe2d9797062ace80728f384d283e37296f96406886438ee0cf49fcde82e205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c042071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "04202348f9288f0f1848ffdff167dbc40d01847ecbdba4a71804053922ff3c5e0c04206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f7820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f7820081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f78205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6201e38e316283704061799e451da3dca286f2e79f7b86b915750d9d745c8294f78205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b203dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f20c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e2071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "04206c6296ec76e065d1786a0896bceb038e51203f704270c6f0484c5ac59d2dc92e206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c3920081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c3920081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c39205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6205631adb95960a9b3cb67b4b1e106cc3232123b3a6eb44b5bf5f9efbf5fd10c39205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b205054731cb36c4669cc15aea3f18af91aa2465ff1f32a6996621b661e2a728e2420c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b205054731cb36c4669cc15aea3f18af91aa2465ff1f32a6996621b661e2a728e242065172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310d00000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3201b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8205aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd320aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0100000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056200d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0200000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb0492071d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b820531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0562037c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0300000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440206fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0400000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe982064286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444020493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550500000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62089a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0600000000000000", - "042000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb049206784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98202c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba62075d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0700000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1120081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187203eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130800000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1120081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218720632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0900000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a11205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8201063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b670a00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62040757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a11205b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d82040ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0b00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b200d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd20c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440c00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b200d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd2065172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310d00000000000000", - "042023502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b62051ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b2071d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f573620a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c0e00000000000000" + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620fe60df1ce575aaab663d158a20f9e560f7bdc5179f1527b3a33e4f587b44ffbc20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620c054f0548d44fb121f3e22fe87517c806628adfd0f3cddc67c982f4adc26b62a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620c054f0548d44fb121f3e22fe87517c806628adfd0f3cddc67c982f4adc26b62a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c216206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096200504f659ffb9358e5fba924944396b345006a0abc2cbfd207c97d6b2323bdc2020cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096200504f659ffb9358e5fba924944396b345006a0abc2cbfd207c97d6b2323bdc2020cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096200504f659ffb9358e5fba924944396b345006a0abc2cbfd207c97d6b2323bdc20206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096200504f659ffb9358e5fba924944396b345006a0abc2cbfd207c97d6b2323bdc20206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096207315163946951eb4895ff12f6b0724c6062f021e669b99fed24dfacd28c9c04420cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096207315163946951eb4895ff12f6b0724c6062f021e669b99fed24dfacd28c9c04420cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096207315163946951eb4895ff12f6b0724c6062f021e669b99fed24dfacd28c9c044206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096207315163946951eb4895ff12f6b0724c6062f021e669b99fed24dfacd28c9c044206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620fe60df1ce575aaab663d158a20f9e560f7bdc5179f1527b3a33e4f587b44ffbc20f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620c4952dd79bbb887a721fde83eeb847a32117311e7dd0d107625ab11063b7b7aa20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620c4952dd79bbb887a721fde83eeb847a32117311e7dd0d107625ab11063b7b7aa20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620c4952dd79bbb887a721fde83eeb847a32117311e7dd0d107625ab11063b7b7aa206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620c4952dd79bbb887a721fde83eeb847a32117311e7dd0d107625ab11063b7b7aa206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620c4a10647b2ed9dfd93323f5b2044550c5763cf198da5297d1778c894337253c620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620c4a10647b2ed9dfd93323f5b2044550c5763cf198da5297d1778c894337253c620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "0420c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff09620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "04203f117e549d8140c4bd97b3d8d73dfeaaa458491730e870e7fd4a3d472493c31c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "04206eb318a627c0ff6ffcef86f2353dcec1c7a51aaea37aa43182020fc06c1df9da20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620fe60df1ce575aaab663d158a20f9e560f7bdc5179f1527b3a33e4f587b44ffbc20c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb648201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb648201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb648201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb648201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb64820197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb64820197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb64820197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "042078bbb59b43ce3baff1db1248b4493bc9bd4dd6c1a3b62b1d0d0a5433b0abb64820197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620c91d1d80ecb6cd0be622f9c277c61d19530c86abcc673b93c279abd8384d787620c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620c91d1d80ecb6cd0be622f9c277c61d19530c86abcc673b93c279abd8384d7876203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d04260201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d04260201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d04260201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d04260201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d0426020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d0426020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d0426020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "04208c026cdb0a983dec0d6a34f397abc8f0839514454f87632ce6d8102c25d0426020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381020c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c21620e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa3810203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c216201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "0420677c207a1612b09f2e5d38d372d6e6358bc7223a6c7da695d602501e7a01033c20197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4207417b3f92f30771c261160269f694ec7c14b21cf14e01735460e9e9b47f6dffc20e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381020c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4207417b3f92f30771c261160269f694ec7c14b21cf14e01735460e9e9b47f6dffc20e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa3810203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4207417b3f92f30771c261160269f694ec7c14b21cf14e01735460e9e9b47f6dffc201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4207417b3f92f30771c261160269f694ec7c14b21cf14e01735460e9e9b47f6dffc201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c4201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c4201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c4201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c4201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c420197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c420197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c420197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "042020307a3cff449ca02018e525dbd37e2180b023dbe68ffbff1218f0f1149f12c420197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201ef29413a2eb9b0aea89d61def9e74f61453bc5b8a2799e86020ec1468c71c7820e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381020c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201ef29413a2eb9b0aea89d61def9e74f61453bc5b8a2799e86020ec1468c71c7820e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa3810203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201ef29413a2eb9b0aea89d61def9e74f61453bc5b8a2799e86020ec1468c71c78201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4201ef29413a2eb9b0aea89d61def9e74f61453bc5b8a2799e86020ec1468c71c78201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a20fe60df1ce575aaab663d158a20f9e560f7bdc5179f1527b3a33e4f587b44ffbc2022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c830c00000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e37694636201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e37694636201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e37694636201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e37694636201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e3769463620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e3769463620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e3769463620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "04207493b4b9a35a32120f630e420efc048a71c0d73d6910561e8ba6076e3769463620197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4209c308bfafdf79fafdad22d765cdc484c4c3360878d2de6d3cd95069a9db58c6a20e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381020c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4209c308bfafdf79fafdad22d765cdc484c4c3360878d2de6d3cd95069a9db58c6a20e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa3810203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4209c308bfafdf79fafdad22d765cdc484c4c3360878d2de6d3cd95069a9db58c6a201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4209c308bfafdf79fafdad22d765cdc484c4c3360878d2de6d3cd95069a9db58c6a201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a2024714e547866d846699654cf8ffa6245589f518fc575a833966236cd38ce2a0a2022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c830c00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a2024714e547866d846699654cf8ffa6245589f518fc575a833966236cd38ce2a0a208cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60d00000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d40800201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80000000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d40800201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e20cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a20b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d40800201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca2050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00200000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d40800201dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e206a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0300000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60400000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e620022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142620aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920500000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910600000000000000", + "0420920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080020197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e62065d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0700000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4208850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0220e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381020c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0800000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4208850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0220e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa3810203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60900000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4208850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae02201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4208850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae02201be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda20f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a20bbb52416fefd25274a8a4e9513319cd7b85fa96244796ff402755618d717a1b02022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c830c00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a20bbb52416fefd25274a8a4e9513319cd7b85fa96244796ff402755618d717a1b0208cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60d00000000000000", + "04206de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac420d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a206ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e203a3661bc12b72646c94bc6c92796e81953985ee62d80a9ec3645a9a95740ac150e00000000000000" ] diff --git a/src/test/data/merkle_roots_empty_sapling.json b/src/test/data/merkle_roots_empty_sapling.json index 3518da50d..1357a463a 100644 --- a/src/test/data/merkle_roots_empty_sapling.json +++ b/src/test/data/merkle_roots_empty_sapling.json @@ -1,65 +1,65 @@ [ - "0000000000000000000000000000000000000000000000000000000000000001", - "3dff22de1af27cc5cde4a8f9e8a3bdef06a79f0451a8bc66d555aea738fb067f", - "6843183254d04c094fb8a3c466c48c629e808d5b1b017b372fe9b0a60f0864f8", - "690ff0e5fedd160456936f92fff6609a4a7932659c1f022c32150d0ed3b0b443", - "48afd9db45da4ad47d125d1fbf3faf5ad49bc5800203c9e7f56d98e7f962a74a", - "52664866130ed4307f2039e0230fa0e058b7a315eade184cb423bd558cd06a0c", - "2bf8be233a7a17394bb681c3b9c71114a5e223a1c273b767bac8f320a98556a0", - "68e7d5c0986103474c4343b272b5a5bf79e2da7abd29b1389ac83f8b866301ff", - "6abc7c2e7004ec7850f41a26cae44a322f1c7dd080f8a497cbd61c9ab8c41f5b", - "4c2b46542b96e217e85741ba892989852bc1b2fad76d66019b72e0c3384e28fd", - "23f8ca3569b110fdf40631ce9b8f295bbedf2ef6fe096a69fe7451db1cd4c07e", - "170ed2b7666437569b4bf18b5a038c7d113f8e1b8300a32d914f852689fd5a48", - "6aaf3bfe56ec4bc562fa8640c86888edbe9b2fdf1af0a085223447336cebbf96", - "2ced08116ee1c7607e527fb5d0b34aaca1662703286a807fabe73512b69ac18f", - "5021a742f430467ee691af6fe0dfa842cd2db9bef16c619e0e0675a2230e24b3", - "64066ab77eda0bf616519cda48cc7bc1b9f91b33b0b0debe47d86bec68ef9b3b", - "43a2743ab11d31df45b31bdb1275a4dfc673fddd41b7880405a273e1d934a80d", - "320108cefd4c869f77d675c820a2be828a8ace3f85d20d955082c6ab5d3bd8e8", - "2cf95d6d9b3d401d0fc54a6451e854720ce30e0a4674d690241693a6b41cc2a5", - "488a46044deb7d0d996e388afc53e01ca3793c9d3358944cce36a97aea11d8fe", - "18d8f93549181e2a6b3cd98baa878b0a96c5709c32a9d3dc4168f15f0af00d55", - "3999232c33f87188ae601567558bd3dec6a9c9d243c19870af3cc577ddf691ce", - "0aeade0ee89bb5de407fc4f6213ba1d492ac0628a085cbe9dca9edae9cec1987", - "392094db210b0362be62b65b9de2c038a7cb3d4a43118d0ba1d42bd9da7b7317", - "6ec7712d4d8e8f74c05c1c9706e1d63a0d249bbc3fb088b827d0c31bde3f3685", - "0d5de4e6e2bcb6854c1f34c304ec1ad896b5ba03532e090757b9a8ff4bf57122", - "6576e977682211e28332c97dcf35edfd32845da5db3a6b96822551bd16da96da", - "1e7f2ef5bd82f2fab8a44fd6701b59cf4baf8732c41f92495914cfdf597c2282", - "2a7816907971106d3b93b59dc874da22ec96da002a1653bd6bd56ba8ead5c3e9", - "3f454d16b6837bee1f74aa3e909701ba3330050fb9d0100f83e4c8dfd1349159", - "50ee5be3d5b41522eb84667e970af0803f5cd607e6f6cdead4e9885afe20d688", - "544d516b6cb28e0d904e17a7b80c8b5ee060d11ab0ff5b1ea01577c54ae4ba11", - "42ee98b38774791f5114887d6c05f7a880316e2e3bf1556e35e7e4bf3d90f556", - "1d51c8775f138982a6bda3ae24a60af0b1b706515dc72aed3dc3348908c29ae9", - "6545b76b426c072c2412315fadc0325a9c84cd6c0aed674ce9651a0e4eb1cee5", - "51d771e1e94c31708c6a83e553c0b819a535c93846fd1ed3c8788c8b3ab221c3", - "6c2478acf47f394fe7bc35cdb4b68bcb57a383eaa76d845ff5b5f92a9f16319e", - "5cd44b509881237dc34837f808ffdf79df6cc8e0291c01c9647b3602bb368de1", - "2f06fa6ae0b78cde4741546491c743872c27fc6f4715eb6d5404d8b06fabaa06", - "17cc4c7b7808464a6f0e1fa0af4da7fc833a7f5daea1ce9c46c7c83be24fdfd6", - "1c3e646bf45a89d1f25d9ef007a2a641cafdea18768ef389189d08101d9643ea", - "4ff4278d5b80439fa6282544078b33fd13dde3c7e811472adc1e07fac813d691", - "131c34f77cf89f23905e6912a5c42b978ef82d4a4132b21c317adfccff5acb02", - "3f1b3bc3cd88999836d769437c4b3df8796f042e85e8940c61eb5d2b7002c014", - "33d0bcd7d43158dceae0a9ad695c60661441091bf34a85425e413734c19f7dda", - "1fcfb94450205f2cb8804e932cd6c0302842c3e1cd77969a9e2c07437ae9b58e", - "079eb2637bf551408ea6623a465418007913b38a0bf6cb01f5e89e6409347bca", - "3e48ac5a702faff90b02c3ad9e2788b5a255652461ac68b385fcb00ac99c8ef9", - "69c87915df1e7857ee6d349bf1c6935deb3ce38f0f0cd71af56eb96ea58f72a0", - "186f22a2ff9d27f0b9c9a687e47b3ab45705735a8d4a735fb0050439858c1ba2", - "06495d4ffe824f1dd7272121f4fcf40e7a52fd6bf236f4162ab3039dd26fccd5", - "3d43ba549713dc6aecd6ddac831b523d0df574f9e0d94794ba164de779273327", - "38117f7f9cb1a38d236a01ba12141d0321cabe9e401f19e0dd5fc7b821d946ae", - "3cd5df8545eec9e3a44bd85d32fb690b44e1ea850afea3eb715320c49f56571c", - "4f2edd4af5e97d96d29baec6e80d039b915ae5eaab15bcef431e7fefd0d500cf", - "1a4e1c67131ffc1c27ff5a67889dc89e1146d88c26d2d6534756fad6a932a1c4", - "341b5d3787df25236b512c3434b64c04d30199ffcb82b05b45b52be66292d09c", - "1e48812555a81e5f64729946d34dede7e72d7df32f9611def06089a8951eaacd", - "5c7c7f875becfdc759a78bc08ccdac50ce1b66c9ade1ca9f1004a9efd2bedef5", - "5a14eb62c6c12fee6b70f21030d6f4a7296a83eb4e5c270b8bc7229f50295d24", - "5426249303bb9428453aef640c3bfc0b8ca58034a9b9a8af7390d30071d05602", - "444c299c479546193d7eabdb3a513ff628e5ecbc7c34a0a7ea9750370ea999e1", - "624175dcc2cbc405792d77f78ead1d460fb4d833d9ca33e2025da71738a1eff5" + "8000000000000000000000000000000000000000000000000000000000000000", + "fe60df1ce575aaab663d158a20f9e560f7bdc5179f1527b3a33e4f587b44ffbc", + "1f2610f0650d97f4ecde80d8dab101794631236623c51df290320b2a4c18c216", + "c22d0dcb70b0a84c3440f839a64c9e5259066fff49f6c96a2068bb7fa70ff096", + "52e5469fe719b6afe793c04001a3d92b5af5fcfdf8ba48be2b525ba2db9bf512", + "30560b31aabdc42d32187b57a8c5ed1a0705f0c4079c04fe0c2b70c86612664a", + "056aa19504cf135de6edce4385c447a52888e39dc3816dd29ce85e5cc47d1fd4", + "ff80c661d1fc13591c8d94bd5e5b479efda5ad4e4dc2c232e2c0861903abe716", + "daf8231d59386bd3e9251f010bbe38f44c52275364582f0a1e37200e743e3d56", + "bf14721cc3074ed98066b6eb5f4d83d4a19194915d82ea17e84769d42a62d432", + "7e032b38db8a2e7f9656907f6f74fb7dda94f1d9738c602fbf088d96ac531fc4", + "125abf9164a1f289b4c500c1d871fc88be31c05ad18fd2d96aec2666ed4b70e8", + "69fdd736cce22c44a1050f58fbf4d97db711161302615f46a3d2376a7fdcf556", + "f183596d48ace7d5fe015614c0e466853552cd0badfe4a7e06e387768810b734", + "cd2470c445ae60707986368f7d9db4b34215fb07f6f589677e620c2f42e5840a", + "dcd9f71637d61be27d7b0d0dccd89f9d83de33125b398a686fd05b7eed566026", + "b0152c9b87ce45a02011ed82bbbfce63fb25ae48dbd8cda2fb8cb88d5c2e45c2", + "171bdcbad563410aa9b04ba1fc735151417d450413ae6beef96132bf7310804c", + "a543382d65c96824096b2e625070c7304e2a178a2652a3f0b802bcd9b6ba9f34", + "7f1b88575e956c7332291accb93c9ec53807ca3f511c7699b0bed7b220625112", + "aab00f50fa8f16823bcb954c390ea36950d1e155d19b3cd654781892ac9f1b18", + "73896fbbeea33cf50e1983c24b9395637bcbd1aae6a80675118e1fcc34c4999c", + "e198373975b7953b97d3a105146035492b85dc846f23fe027badd917707b5750", + "e8cede5b9bd42b85d0b188c252bcd3e51c0347b9da6d467d46c0d084db29049c", + "a16cfc7bd8c30be41d110dfc3dd924b05c6b8760e9383a032ef171b2b48ee376", + "448eafd2ff159deae09074cac05dad691b583720c32cf832a16d3d476727bab0", + "5b695b68bd8aa44169d65cdba5ba214cbfb7acf3be934cc147884416ee976ea6", + "41443e9afbf3289a9249f8234ce1f5d2f39ad80e6bf2251d5f4f41bdaf74fe78", + "97c3ab5715d6abd6bdca6854005b6937445b2e13b9adc9dcb6088e9e09681e54", + "9a892c8bfb1327c1f0080b9df0a00ccc5d80e9097c552ef877dec16d68b2a2fc", + "116b047f5a11972b57b36f67e06b3afc010f50e97e6621d744a82dabc7da770a", + "885d2752a3eea80578daff0d588b06077ad1301de5e87209b0714d36d68ab22a", + "6aaf09bcfd27e7ac76aa8fdc74768c0115efa036be11288af89e2ee1cd197742", + "97594310912cc3bcb754e3ba8a60ed8d0f50652475c5bd654191c8faee138ab8", + "a7738d727058a69732e6b75036b321395a4c03b5fa8c482434e03642d6eda2a6", + "c3844d5cd1311e13cb78bf621c93aca5981d03caa7c156310e8c3297878eeb8a", + "798c68f9549fadaffa21b6e557c1c5ead3d16d2db3ac3de7f29cfe2f351e2436", + "87b16cdd406cde2693803894071336fb9efbff101fec12c3bec481190ad22b3a", + "6055d5f60d1b202ab6d7a8e2f63fe434e1c2e389262a82e27b31ed07565f60f4", + "6bfbf247dc13e36239738575bafe5cc13fe5b2f505f870f65262101ede3233e8", + "57c269b80810b91891cf716e1857bf53826545e00f79ba4f8b915a2fd6267c38", + "896bc8135fe0783b54e28817e3c7bbc8bfccd1e022a41465f9c201dab1e42ff2", + "40d35aff33fb5e8c384d4c8252b41f71e9d423a548967a09c4f91f3eef2c38c8", + "2803400ed4bad786302917a17420f69e1fbcd23ec296eb6c199911b3c3dcd8fc", + "5bbef9832cec827a42a152cfd890822866063a96b59507573b1a8c2beb3d0bcc", + "71ad975ec2e034795969eeb387c342140c036b34c972011d34fa040a229df3f8", + "53de2c90267917af80d36fd051cdc89e00182a625c466571028aafdec64d79e0", + "9f713993500d3fa1cd16358624a6aa45ad11e479b5c340d09ff5f40e5a35127c", + "054ef1a5769d76af58eb30f0f1c73cd7bac9638fd92cb677ea1e78fba89e1396", + "45d831a19c20a00dface52b15acea0ea2d5cde27e165939d0fe4b9ff4544f618", + "ab33f64bb9c0cd54682f6c4fd6bf4a5e702f3f2f8484e4ebb8f2417ff2ba9260", + "e4cce49ee7b2685d29e29b079f2eafb0bc4ad8c135bb6b37563bc8e92a5dc2bc", + "75629b841de3fabb0798f802797d5384c0b828485d8056c4b1c58d39fefe881c", + "38ea6af92304ca8ed7c57f50a1578722d096df4cba1bd225c79377a2a1fbab3c", + "f300ab0bf7fe78c2f73da8d557a75a89d9c0b0176375d94b69be97af52bb74f2", + "23854c956b5f6ae2ca6b4b64311b62887913b911e65affe4383ff8c8e6387258", + "390b494667d4ada2da0d41d3ff9980cb20326d2c2c348ad6c4a4fbe1ecbad82c", + "b35578a91591060f7b8869f4cfbeb4e7e7b7b2cb62994e26fa7815aaa4811278", + "af7b7d4bf7952008f95387b59366d8730a35b33103d1e59ae3bf37dae1fe3e3a", + "24ba940af944e3d1d0e43a72d7c15694e52f6b0c084f0ed677f4836346d7285a", + "406a0b8e00cb09cef5159d952c01a531d03fdc3026f75ca21429ddc0c924642a", + "87999570ec0ae957e5052c3e3d37a7146ffc8a5cdbd57ebc9862a9e239943222", + "aff7851ce8e5ba4047cc539bcc1b2df062b8b571efeeb49ea023d3433bae8246" ] diff --git a/src/test/data/merkle_roots_sapling.json b/src/test/data/merkle_roots_sapling.json index 501896530..441b7eb59 100644 --- a/src/test/data/merkle_roots_sapling.json +++ b/src/test/data/merkle_roots_sapling.json @@ -1,18 +1,18 @@ [ - "382658a9ab75efa73c7183b5056b0a534ecd60cc0e2e3f2e77a7e12adae80aab", - "646c930ce6b9728c03d6497e6822104a0130ea64300898790da6f3ee3b5b85f3", - "1b0bfb478e292a2984a01b4c322f7ea3b5f0e96cb8b75a8755f1814a1bbf585e", - "549213b3d562fd5ed171dd5104b24298210b3183260b2a472de165e9acf92652", - "60c5b03aa7f54703e5b97f6b287be542ac2922907e0ff46ec11454575246d1bd", - "45dd233ae03630ac5cc158319af450fe4d1e784229b09d96a7770a3f4b30f5b0", - "194c51e5fcc56fba776f4d550159b727a65e13406ed47464e48a5f150fc1cf63", - "0ffd35b7621625f87dd6cd9166c780d9217b5375a899665fd491a30eced9758b", - "0ed077643316f173744bbdf3d7bd4be20d720dc4eaa2dc23c9019312798fc410", - "04226b0cff412d5c56808152117ca6f91c5fb93df0f4c088bd500c08cd8ab82a", - "560a5929da194ddd246e3375f2c1eda7ebc5b3594723ffa319d881f3ff0f9541", - "32cd6ec036c2e6379bda75d8f10fe47168c89bfa7d55f3ad6fdd48c26237db4c", - "55cfd0476d4d9ac7008e554b6556d3d44d509ff6833da748e889d18a5c740248", - "6db5f557d3a24b1f7dd510bdf18326de30d0d4022049b96c7027f3977f6a75c0", - "39dec1fc21c2879f629257306132005b294ea6acdef2cd8f9d199ac444b43993", - "53b68c58e26345358d8929d0bf3e3a30eefdca77f2c07920c99c10e52f7639ab" + "d550175b5487e5ee74fc74703306b372ca50d6a0adc18e3ce5f7aed5951a641c", + "cfa1dadc77cf65b09e19100c26570c80520844167e926bc0314e9d6730c93626", + "7a1afdd852818faae15aed1d36970fadc57ef44c32d8052194549471e2dfd0d8", + "4a649f3597a687b4e254d064c18cd08419424d208abb8e8b7abf46abcdc8492a", + "bd8b624aea2a2883762ff07e0944943542a7de14d6fe9da7c0e2afe55c0da306", + "0daf0cd2fc50eee569b90d94421e78b27f0a2f598c1a833a350c6c075cc4bba2", + "c6f383f0a8fa5127262e2b7602c87a65e4ed9a80aab2f6ee5df6a33fa78a3298", + "d1ae9b7370c5892bfa669915aecade849b01e36689b36bbe1fa46846edacbff0", + "0823f19e48c98093c43b455723b04eb047d2bdebcfbdd22ece8f68cc26ee0b70", + "541d51b310300abd11032f0fbc9dfa389f653e884a81016a3ab482ff30d64420", + "82a9f0ffcf811b98c5ffc4e29acda3d7e5b7834faecc7624bbb2985b949a506a", + "32dbec464312bbf6b5cfaabe5fd913168e27f08f1bae5bd9ec67436c0376b34c", + "12402e3a518b911712e5bcc16ff90ab22bcb6aa6d2aa7100e359b2b6e20bf3aa", + "03ae56fee9cfe40e369d9204402b0b0c7b64c18fbd08abbef8d245cbeaafadb6", + "c99c2d22235998b9f1b34f7b35657294da004c860cea4946f9e143843f837b9c", + "d59c6ef4a7083993049e034fee53bf770c5c7cfd0b9491b1aca2c6471a316dca" ] diff --git a/src/test/data/merkle_serialization_sapling.json b/src/test/data/merkle_serialization_sapling.json index ca767b40f..da1445e67 100644 --- a/src/test/data/merkle_serialization_sapling.json +++ b/src/test/data/merkle_serialization_sapling.json @@ -1,18 +1,18 @@ [ - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6", - "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f01a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6" + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d800", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60803011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "01f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0003016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4", + "01f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c013a3661bc12b72646c94bc6c92796e81953985ee62d80a9ec3645a9a95740ac1503016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4" ] diff --git a/src/test/data/merkle_witness_serialization_sapling.json b/src/test/data/merkle_witness_serialization_sapling.json index 53e9f874b..ea936b26b 100644 --- a/src/test/data/merkle_witness_serialization_sapling.json +++ b/src/test/data/merkle_witness_serialization_sapling.json @@ -1,138 +1,138 @@ [ - "00000001aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d00", - "00000002aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400", - "00000002aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea44010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea44010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea440000010137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e0000", - "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd300", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a00", - "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056000101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c637550000", - "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd30101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056000101493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f00", - "00000003aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000021b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400015aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd3010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f05600010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0001012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0000", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0000", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b00", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98000101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c0000", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b80101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc944400101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b0101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98000101632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef1531300", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0001015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0000", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0000", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218700", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218700", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6700", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310002000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b67010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310000", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b8010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc94440010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe9800010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4402000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb2187010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b67010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b600010165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4400", - "00000004aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000031b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400025aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056020d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560171d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b801013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98026fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980164286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b01013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00020171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6023eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6701013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00010171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f5736", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4401013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f0000", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60001013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f0000", - "00000005aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d1b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d0000041b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea445aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "01aaf65c9f42a42bd6786f4ad59300ba77e1dc74247af7e0bfdaa7e1074f08c40d011b288de465631d0f7e0bfcf07614c2ff2093a1f81f2425a72d5babadcfe2ea4400035aaff96e7fb8c9354f77aa33880d9bbecd64ec34a1e7828621b386c89a2fecd371d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e000101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f056030d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a71d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "0137c070b62e069f6816332134d71eb3ad220e62791eb39af309bc5c7658057c3e010d050b21609dc7967c270346bd7816689fda8ff25ac8555fb8ea293436b8420a0101531ccefdb9693ef33121bbdb5ab88a207316099b617b4906c41de3a30b45f0560271d567fb66b5ec8fad553286ef1887e9856710cd0de0da60b875d25d9290d5b800102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755000200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe98036fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f64286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "01493f7c4e19d74c5e11d53302f67d9a7aa2bbbbd9429001dc74d0555c61c63755016fe0bbc4505bc98bf2b2879b00517a26a5591f3e74f226a59fa77a302b12e61f0200016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980264286abf81f96f9a02ebae7afc50f3ef13a8876b6c758b93d4ed6c126bc9444000102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0002012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980289a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b00102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "0175d03f78487c3b6da4448a86680acf66ce8eef816dc0401c3a82e268e37a513d0189a5a7d29f95ad7e38689c2099598b4afe784836168a888781c97b3345bb585b02012c74d72aa2537bfd12c8e280ac0b1adbe3d18f94c977747ba95f7272ac5f0ba6016784862630b32be19e6bc2b6f384497260d6582a9851f3a22d89d7c2d65bfe980100102b930824bcd85c69686fdbe0a522b174eedda9201eb2d083208efd8eb04900", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c000300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6033eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef15313081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", - "01632eefc10691608cc23f186dce4d9bf41131c61c706c011cbae23ddbab7fe45c013eb8bd4d0622d89105d12588ab1f027681d59b3ba11cf40c9e99bfefbef153130300000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b602081c5fdd6f23a8807ff09978ebdcbac34ad674d1a533ee48d27f904ecedb218740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f0003015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6021063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6740757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", - "0140ec342e66260791a16ee934650b0a303e7123f42862442cb9c8dc6017ec5f0f011063ebbbbc741cfede216b6ef9d4367d0c9118d58107ef4cd80b291a16eb2b6703015b3be3d8a1375fefbe951251e524c6a0c27d0b3e2ff3f70a6b3cc4d376eda7d8000123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b60140757eac6d138b1a2e93d27000183e0799f1eb7b50823b24ef13f20178350a1100", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd7310003000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b602c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f440d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd00", - "0165172360f8549b218bf93450226c9d01704a0996030dcb18b662c117dcedd73101c13e439cc81ca906644ad837a513d82ad8feb478b5ee1afdb2a811db3d1d5f4403000151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b6010d85e8eb186aae402ff69e224695fa1deb398cc8a9725152e4a4bf7f6824addd00", - "013823e6f34bad20876a93c5d1a30327af57364310a0b2b460cae5a786355c7c2f00030171d638ea4b7cebbc033bfd20b8bc7477a70115ed7970ed72d8ba8541075f57360151ed4088967e2a2bc028eaafe5c03d0fd728aae8e7d6a76e60466bcd8dc9720b0123502c78f4f9117f83fb0be623fe59771ed31f05593e34c4e94fdfa88a5107b601a83502ea9595a26c379501b4677a19ca981769e49363d2936264ed483d866c5c00" + "00000001b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5500", + "00000002b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d800", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000001225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d800", + "00000002b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d801017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000001225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d801017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8000001017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0000", + "00000003b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000002225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80001cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a00", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b000", + "00000003b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000002225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80001cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca000101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc920000", + "00000003b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000002225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80001cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca000101aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f600", + "00000003b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00010165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e34", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000002225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00010165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e34", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80001cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a0101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00010165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e34", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b00101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00010165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e34", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca000101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00010165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e34", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f60101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0000", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6000101bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae0000", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e00", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e00", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e00", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142600", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142600", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a59100", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a59101013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e60001013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c60000", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a59101013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e60001013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c00", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6000101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020001011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020000", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4000101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020000", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6000101f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7ce184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381000", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381000", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60800", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a59101018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e60001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7ce184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60000", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60000", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60000", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60803011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac40001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60000", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e01018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd56142601018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a59101018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e60001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83020001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7ce184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c8300", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa381001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c8300", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60801018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c8300", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60803011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac40001018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c8300", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac40122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c8300", + "00000004b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000003225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80002cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0250421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca011dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e0101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd5614260101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5910101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e6000101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0002016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7ce184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa38100101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0001016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa38100101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0001016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0001016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60803011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4000101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0001016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac40122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c830101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0000", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4000101f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0000", + "00000005b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f55000004225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d8cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f5501225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114d80003cb37f4591361cd846141e7852c3726b37dd9b011cc55eef2ac931dfe769ff55a1dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca0350421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b01dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "017c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e03ec0150421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0b001016a0fa2d0c5c7b8236092de86d99068ce04511d5adbdd848ccf7c969dbf7338ca021dab0949ba4bae1d065b07b0b308e6a197e118f7614caab5f137ad66dfe6ab8e920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9200020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e603f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd561426920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc9201f86748d40c5ee5f9a5644f2e7cf89aa5645e8a00d9e14d4fd193da0a23dd07f6020001197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602022293d64836b72bc9d1ae36d6e115c8f7cf0a3f5e75d74059f69f81fd561426920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae00020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e602da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "01bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0bae01da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a591020165d0fa354e4efa95de2eee9329f18bc7db58d03501471348bfdeca4554eb2e3401197fda6b43eb91b445cf8a19541a6b064e9221cf6d43d67987d4cd0c646121e601920d71bf7104c10b4d780495bb772e8d44a507dbf616963a1b3d2410c9d4080000", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c600030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac403c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7ce184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa38108850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0200", + "013a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774c601c8ca8f7df7fd9979302f3885dcd9ab816e40f8d511a48ba0891b4460b2bd1d7c030000016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402e184db737209fe4b1277cca58b2e6b52c35d3bd71e990ffe0115c4f6bbfa38108850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0200", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020003011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac402e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6088850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0200", + "01f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c370201e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c60803011be5b76ecb233cd650efcff47cd0be43056324a78a48a97df7faec851bc7dcda00016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4018850ac1e804fc8f724dc410aded78f99e07c18000e4bc97458d1c8b6357eae0200", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a600030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac40222fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83bbb52416fefd25274a8a4e9513319cd7b85fa96244796ff402755618d717a1b000", + "018cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8a60122fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c83030001d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac401bbb52416fefd25274a8a4e9513319cd7b85fa96244796ff402755618d717a1b000", + "01f43e3aac61e5a753062d4d0508c26ceaf5e4c0c58ba3c956e104b5d2cf67c41c0003016ceafae082a15d1b4eb70e9eb7a880e5ee2e3d1d04bfdcc03dd73ed2571c6b8e01d04e93b1b3d6620676e56be7175514ebf0bc03a7f5571403d4547e691102b78a016de08a5115fbf297232c7c9aa0f8cb78ee9a7fc467d0dfc1fe889f2f1e340ac4013a3661bc12b72646c94bc6c92796e81953985ee62d80a9ec3645a9a95740ac1500" ]