mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
* Merge #10757: RPC: Introduce getblockstats to plot things 41d0476f62269027ec2193a5f80d508d789de8aa Tests: Add data file (Anthony Towns) 4cbfb6aad9ba8fa17b5e7ed3e9a36dc8a24f1fcf Tests: Test new getblockstats RPC (Jorge Timón) 35e77a0288bcac5594ff25c10c9679a161cb730b RPC: Introduce getblockstats (Jorge Timón) cda8e36f019dd181e5c3774961b4f1335e5602cb Refactor: RPC: Separate GetBlockChecked() from getblock() (Jorge Timón) Pull request description: It returns per block statistics about several things. It should be easy to add more if people think of other things to add or remove some if I went too far (but once written, why not keep it? EDIT: answer: not to test or maintain them). The currently available options are: minfee,maxfee,totalfee,minfeerate,maxfeerate,avgfee,avgfeerate,txs,ins,outs (EDIT: see updated list in the rpc call documentation) For the x axis, one can use height or block.nTime (I guess I could add mediantime if there's interest [EDIT: nobody showed interest but I implemented mediantime nonetheless, in fact there's no distinction between x or y axis anymore, that's for the caller to judge]). To calculate fees, -txindex is required. Tree-SHA512: 2b2787a3c7dc4a11df1fce62c8a4c748f5347d7f7104205d5f0962ffec1e0370c825b49fd4d58ce8ce86bf39d8453f698bcd46206eea505f077541ca7d59b18c * Replace get_mocktime() usage with self.mocktime
This commit is contained in:
parent
3d5eabcfbb
commit
f2dcac3a4f
@ -15,6 +15,7 @@
|
||||
#include "consensus/validation.h"
|
||||
#include "validation.h"
|
||||
#include "core_io.h"
|
||||
// #include "index/txindex.h"
|
||||
#include "policy/feerate.h"
|
||||
#include "policy/policy.h"
|
||||
#include "primitives/transaction.h"
|
||||
@ -37,6 +38,7 @@
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/thread.hpp> // boost::thread::interrupt
|
||||
|
||||
#include <mutex>
|
||||
@ -835,6 +837,26 @@ UniValue getblockheaders(const JSONRPCRequest& request)
|
||||
return arrHeaders;
|
||||
}
|
||||
|
||||
static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
|
||||
{
|
||||
CBlock block;
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) {
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
|
||||
}
|
||||
|
||||
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
|
||||
// Block not found on disk. This could be because we have the block
|
||||
// header in our index but don't have the block (for example if a
|
||||
// non-whitelisted node sends us an unrequested long chain of valid
|
||||
// blocks, we add the headers to our index, but don't accept the
|
||||
// block).
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
UniValue getmerkleblocks(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
|
||||
@ -881,21 +903,8 @@ UniValue getmerkleblocks(const JSONRPCRequest& request)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Count is out of range");
|
||||
}
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) {
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
|
||||
}
|
||||
|
||||
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) {
|
||||
// Block not found on disk. This could be because we have the block
|
||||
// header in our index but don't have the block (for example if a
|
||||
// non-whitelisted node sends us an unrequested long chain of valid
|
||||
// blocks, we add the headers to our index, but don't accept the
|
||||
// block).
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
|
||||
}
|
||||
CBlock block = GetBlockChecked(pblockindex);
|
||||
|
||||
UniValue arrMerkleBlocks(UniValue::VARR);
|
||||
|
||||
@ -993,19 +1002,8 @@ UniValue getblock(const JSONRPCRequest& request)
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
|
||||
// Block not found on disk. This could be because we have the block
|
||||
// header in our index but don't have the block (for example if a
|
||||
// non-whitelisted node sends us an unrequested long chain of valid
|
||||
// blocks, we add the headers to our index, but don't accept the
|
||||
// block).
|
||||
throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk");
|
||||
const CBlock block = GetBlockChecked(pblockindex);
|
||||
|
||||
if (verbosity <= 0)
|
||||
{
|
||||
@ -1804,6 +1802,259 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T CalculateTruncatedMedian(std::vector<T>& scores)
|
||||
{
|
||||
size_t size = scores.size();
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::sort(scores.begin(), scores.end());
|
||||
if (size % 2 == 0) {
|
||||
return (scores[size / 2 - 1] + scores[size / 2]) / 2;
|
||||
} else {
|
||||
return scores[size / 2];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline bool SetHasKeys(const std::set<T>& set) {return false;}
|
||||
template<typename T, typename Tk, typename... Args>
|
||||
static inline bool SetHasKeys(const std::set<T>& set, const Tk& key, const Args&... args)
|
||||
{
|
||||
return (set.count(key) != 0) || SetHasKeys(set, args...);
|
||||
}
|
||||
|
||||
// outpoint (needed for the utxo index) + nHeight + fCoinBase
|
||||
static constexpr size_t PER_UTXO_OVERHEAD = sizeof(COutPoint) + sizeof(uint32_t) + sizeof(bool);
|
||||
|
||||
static UniValue getblockstats(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) {
|
||||
throw std::runtime_error(
|
||||
"getblockstats hash_or_height ( stats )\n"
|
||||
"\nCompute per block statistics for a given window. All amounts are in duffs.\n"
|
||||
"It won't work for some heights with pruning.\n"
|
||||
"It won't work without -txindex for utxo_size_inc, *fee or *feerate stats.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hash_or_height\" (string or numeric, required) The block hash or height of the target block\n"
|
||||
"2. \"stats\" (array, optional) Values to plot, by default all values (see result below)\n"
|
||||
" [\n"
|
||||
" \"height\", (string, optional) Selected statistic\n"
|
||||
" \"time\", (string, optional) Selected statistic\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
"\nResult:\n"
|
||||
"{ (json object)\n"
|
||||
" \"avgfee\": xxxxx, (numeric) Average fee in the block\n"
|
||||
" \"avgfeerate\": xxxxx, (numeric) Average feerate (in duffs per byte)\n"
|
||||
" \"avgtxsize\": xxxxx, (numeric) Average transaction size\n"
|
||||
" \"blockhash\": xxxxx, (string) The block hash (to check for potential reorgs)\n"
|
||||
" \"height\": xxxxx, (numeric) The height of the block\n"
|
||||
" \"ins\": xxxxx, (numeric) The number of inputs (excluding coinbase)\n"
|
||||
" \"maxfee\": xxxxx, (numeric) Maximum fee in the block\n"
|
||||
" \"maxfeerate\": xxxxx, (numeric) Maximum feerate (in duffs per byte)\n"
|
||||
" \"maxtxsize\": xxxxx, (numeric) Maximum transaction size\n"
|
||||
" \"medianfee\": xxxxx, (numeric) Truncated median fee in the block\n"
|
||||
" \"medianfeerate\": xxxxx, (numeric) Truncated median feerate (in duffs per byte)\n"
|
||||
" \"mediantime\": xxxxx, (numeric) The block median time past\n"
|
||||
" \"mediantxsize\": xxxxx, (numeric) Truncated median transaction size\n"
|
||||
" \"minfee\": xxxxx, (numeric) Minimum fee in the block\n"
|
||||
" \"minfeerate\": xxxxx, (numeric) Minimum feerate (in duffs per byte)\n"
|
||||
" \"mintxsize\": xxxxx, (numeric) Minimum transaction size\n"
|
||||
" \"outs\": xxxxx, (numeric) The number of outputs\n"
|
||||
" \"subsidy\": xxxxx, (numeric) The block subsidy\n"
|
||||
" \"time\": xxxxx, (numeric) The block time\n"
|
||||
" \"total_out\": xxxxx, (numeric) Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])\n"
|
||||
" \"total_size\": xxxxx, (numeric) Total size of all non-coinbase transactions\n"
|
||||
" \"totalfee\": xxxxx, (numeric) The fee total\n"
|
||||
" \"txs\": xxxxx, (numeric) The number of transactions (excluding coinbase)\n"
|
||||
" \"utxo_increase\": xxxxx, (numeric) The increase/decrease in the number of unspent outputs\n"
|
||||
" \"utxo_size_inc\": xxxxx, (numeric) The increase/decrease in size for the utxo index (not discounting op_return and similar)\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'")
|
||||
+ HelpExampleRpc("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'")
|
||||
);
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
CBlockIndex* pindex;
|
||||
if (request.params[0].isNum()) {
|
||||
const int height = request.params[0].get_int();
|
||||
const int current_tip = chainActive.Height();
|
||||
if (height < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d is negative", height));
|
||||
}
|
||||
if (height > current_tip) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d after current tip %d", height, current_tip));
|
||||
}
|
||||
|
||||
pindex = chainActive[height];
|
||||
} else {
|
||||
const uint256 hash = ParseHashV(request.params[0], "parameter 1");
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
pindex = mapBlockIndex[hash];
|
||||
// pindex = LookupBlockIndex(hash);
|
||||
// if (!pindex) {
|
||||
// throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
// }
|
||||
if (!chainActive.Contains(pindex)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString()));
|
||||
}
|
||||
}
|
||||
|
||||
assert(pindex != nullptr);
|
||||
|
||||
std::set<std::string> stats;
|
||||
if (!request.params[1].isNull()) {
|
||||
const UniValue stats_univalue = request.params[1].get_array();
|
||||
for (unsigned int i = 0; i < stats_univalue.size(); i++) {
|
||||
const std::string stat = stats_univalue[i].get_str();
|
||||
stats.insert(stat);
|
||||
}
|
||||
}
|
||||
|
||||
const CBlock block = GetBlockChecked(pindex);
|
||||
|
||||
const bool do_all = stats.size() == 0; // Calculate everything if nothing selected (default)
|
||||
const bool do_mediantxsize = do_all || stats.count("mediantxsize") != 0;
|
||||
const bool do_medianfee = do_all || stats.count("medianfee") != 0;
|
||||
const bool do_medianfeerate = do_all || stats.count("medianfeerate") != 0;
|
||||
const bool loop_inputs = do_all || do_medianfee || do_medianfeerate ||
|
||||
SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate");
|
||||
const bool loop_outputs = do_all || loop_inputs || stats.count("total_out");
|
||||
const bool do_calculate_size = do_all || do_mediantxsize ||
|
||||
SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize", "maxtxsize", "avgfeerate", "medianfeerate", "minfeerate", "maxfeerate");
|
||||
|
||||
CAmount maxfee = 0;
|
||||
CAmount maxfeerate = 0;
|
||||
CAmount minfee = MAX_MONEY;
|
||||
CAmount minfeerate = MAX_MONEY;
|
||||
CAmount total_out = 0;
|
||||
CAmount totalfee = 0;
|
||||
int64_t inputs = 0;
|
||||
int64_t maxtxsize = 0;
|
||||
int64_t mintxsize = MaxBlockSize(true);
|
||||
int64_t outputs = 0;
|
||||
int64_t total_size = 0;
|
||||
int64_t utxo_size_inc = 0;
|
||||
std::vector<CAmount> fee_array;
|
||||
std::vector<CAmount> feerate_array;
|
||||
std::vector<int64_t> txsize_array;
|
||||
|
||||
for (const auto& tx : block.vtx) {
|
||||
outputs += tx->vout.size();
|
||||
|
||||
CAmount tx_total_out = 0;
|
||||
if (loop_outputs) {
|
||||
for (const CTxOut& out : tx->vout) {
|
||||
tx_total_out += out.nValue;
|
||||
utxo_size_inc += GetSerializeSize(out, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx->IsCoinBase()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inputs += tx->vin.size(); // Don't count coinbase's fake input
|
||||
total_out += tx_total_out; // Don't count coinbase reward
|
||||
|
||||
int64_t tx_size = 0;
|
||||
if (do_calculate_size) {
|
||||
|
||||
tx_size = tx->GetTotalSize();
|
||||
if (do_mediantxsize) {
|
||||
txsize_array.push_back(tx_size);
|
||||
}
|
||||
maxtxsize = std::max(maxtxsize, tx_size);
|
||||
mintxsize = std::min(mintxsize, tx_size);
|
||||
total_size += tx_size;
|
||||
}
|
||||
|
||||
if (loop_inputs) {
|
||||
|
||||
if (!fTxIndex) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "One or more of the selected stats requires -txindex enabled");
|
||||
}
|
||||
CAmount tx_total_in = 0;
|
||||
for (const CTxIn& in : tx->vin) {
|
||||
CTransactionRef tx_in;
|
||||
uint256 hashBlock;
|
||||
if (!GetTransaction(in.prevout.hash, tx_in, Params().GetConsensus(), hashBlock, false)) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, std::string("Unexpected internal error (tx index seems corrupt)"));
|
||||
}
|
||||
|
||||
CTxOut prevoutput = tx_in->vout[in.prevout.n];
|
||||
|
||||
tx_total_in += prevoutput.nValue;
|
||||
utxo_size_inc -= GetSerializeSize(prevoutput, SER_NETWORK, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD;
|
||||
}
|
||||
|
||||
CAmount txfee = tx_total_in - tx_total_out;
|
||||
assert(MoneyRange(txfee));
|
||||
if (do_medianfee) {
|
||||
fee_array.push_back(txfee);
|
||||
}
|
||||
maxfee = std::max(maxfee, txfee);
|
||||
minfee = std::min(minfee, txfee);
|
||||
totalfee += txfee;
|
||||
|
||||
CAmount feerate = tx_size ? txfee / tx_size : 0;
|
||||
if (do_medianfeerate) {
|
||||
feerate_array.push_back(feerate);
|
||||
}
|
||||
maxfeerate = std::max(maxfeerate, feerate);
|
||||
minfeerate = std::min(minfeerate, feerate);
|
||||
}
|
||||
}
|
||||
|
||||
UniValue ret_all(UniValue::VOBJ);
|
||||
ret_all.pushKV("avgfee", (block.vtx.size() > 1) ? totalfee / (block.vtx.size() - 1) : 0);
|
||||
ret_all.pushKV("avgfeerate", total_size ? totalfee / total_size : 0); // Unit: sat/byte
|
||||
ret_all.pushKV("avgtxsize", (block.vtx.size() > 1) ? total_size / (block.vtx.size() - 1) : 0);
|
||||
ret_all.pushKV("blockhash", pindex->GetBlockHash().GetHex());
|
||||
ret_all.pushKV("height", (int64_t)pindex->nHeight);
|
||||
ret_all.pushKV("ins", inputs);
|
||||
ret_all.pushKV("maxfee", maxfee);
|
||||
ret_all.pushKV("maxfeerate", maxfeerate);
|
||||
ret_all.pushKV("maxtxsize", maxtxsize);
|
||||
ret_all.pushKV("medianfee", CalculateTruncatedMedian(fee_array));
|
||||
ret_all.pushKV("medianfeerate", CalculateTruncatedMedian(feerate_array));
|
||||
ret_all.pushKV("mediantime", pindex->GetMedianTimePast());
|
||||
ret_all.pushKV("mediantxsize", CalculateTruncatedMedian(txsize_array));
|
||||
ret_all.pushKV("minfee", (minfee == MAX_MONEY) ? 0 : minfee);
|
||||
ret_all.pushKV("minfeerate", (minfeerate == MAX_MONEY) ? 0 : minfeerate);
|
||||
ret_all.pushKV("mintxsize", mintxsize == MaxBlockSize(true) ? 0 : mintxsize);
|
||||
ret_all.pushKV("outs", outputs);
|
||||
ret_all.pushKV("subsidy", pindex->pprev ? GetBlockSubsidy(pindex->pprev->nBits, pindex->pprev->nHeight, Params().GetConsensus()) : 50 * COIN);
|
||||
ret_all.pushKV("time", pindex->GetBlockTime());
|
||||
ret_all.pushKV("total_out", total_out);
|
||||
ret_all.pushKV("total_size", total_size);
|
||||
ret_all.pushKV("totalfee", totalfee);
|
||||
ret_all.pushKV("txs", (int64_t)block.vtx.size());
|
||||
ret_all.pushKV("utxo_increase", outputs - inputs);
|
||||
ret_all.pushKV("utxo_size_inc", utxo_size_inc);
|
||||
|
||||
if (do_all) {
|
||||
return ret_all;
|
||||
}
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
for (const std::string& stat : stats) {
|
||||
const UniValue& value = ret_all[stat];
|
||||
if (value.isNull()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid selected statistic %s", stat));
|
||||
}
|
||||
ret.pushKV(stat, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue getspecialtxes(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 5)
|
||||
@ -1871,14 +2122,8 @@ UniValue getspecialtxes(const JSONRPCRequest& request)
|
||||
if (mapBlockIndex.count(hash) == 0)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||
|
||||
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
|
||||
|
||||
if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus()))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
|
||||
const CBlock block = GetBlockChecked(pblockindex);
|
||||
|
||||
int nTxNum = 0;
|
||||
UniValue result(UniValue::VARR);
|
||||
@ -1916,6 +2161,7 @@ static const CRPCCommand commands[] =
|
||||
// --------------------- ------------------------ ----------------------- ------ ----------
|
||||
{ "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} },
|
||||
{ "blockchain", "getchaintxstats", &getchaintxstats, true, {"nblocks", "blockhash"} },
|
||||
{ "blockchain", "getblockstats", &getblockstats, true, {"hash_or_height", "stats"} },
|
||||
{ "blockchain", "getbestblockhash", &getbestblockhash, true, {} },
|
||||
{ "blockchain", "getblockcount", &getblockcount, true, {} },
|
||||
{ "blockchain", "getblock", &getblock, true, {"blockhash","verbosity|verbose"} },
|
||||
|
@ -135,6 +135,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "importmulti", 1, "options" },
|
||||
{ "verifychain", 0, "checklevel" },
|
||||
{ "verifychain", 1, "nblocks" },
|
||||
{ "getblockstats", 0, "hash_or_height" },
|
||||
{ "getblockstats", 1, "stats" },
|
||||
{ "pruneblockchain", 0, "height" },
|
||||
{ "keypoolrefill", 0, "newsize" },
|
||||
{ "getrawmempool", 0, "verbose" },
|
||||
|
192
test/functional/data/rpc_getblockstats.json
Normal file
192
test/functional/data/rpc_getblockstats.json
Normal file
@ -0,0 +1,192 @@
|
||||
{
|
||||
"blocks": [
|
||||
"010000000000000000000000000000000000000000000000000000000000000000000000c762a6567f3cc092f0684bb62b7e00a84890b990f07cc71a6bb58d64b98e02e0b9968054ffff7f20ffba10000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6204ffff001d01044c5957697265642030392f4a616e2f3230313420546865204772616e64204578706572696d656e7420476f6573204c6976653a204f76657273746f636b2e636f6d204973204e6f7720416363657074696e6720426974636f696e73ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000",
|
||||
"000000202e3df23eec5cd6a86edd509539028e2c3a3dc05315eb28f2baa43218ca080000d95bb928a2b4d3efb01ceb96a9d4d11f9ef238c189f43ab970b5819c4e5397feba968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207fcf56a1a310cc4105b6b815fa8b2d11dc50c1a7896886a6b6836667e0132c7dbaa1d7dc2bc6a35265e613348723653552ad0db810346ed10af24ea90d1b4c39bb968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000208e27356a6e97c5edf4bc661b4713462e238560029346c4966102dd6ad6869e24e578c0ebcda8b67ad71142c25b50802a6a292253ac3584be187c229b2e8f48d3bb968054ffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020b6a89f04f71289c39585f5f6f9529a472d9e233cea6a66a1cc4992e6506650669cc0cd7aad221ffcf3c17c42c99c1c6b9af43ebf87de78f5b74ad5bc8ad7fcc7bc968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020067660919c37f6517850647faf69df27477528e543133b05a8545d560e7142048ce7479a046e59174bdda33e31bc5298a26ca02f0797603a3b011f0122b9026fbc968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000202110f07ef7f230fd8e3f09d8455fc56aa4c789730f501ab06de5467f6d4cf91c9a445c5f674b7c10739957ebeb1d14942656dd1253f2cc67a4d0912cba11cf21bc968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002019aa592464cecd9e1da8ee4bb7cc45aa1b0b5ced7ad0fb9b56603f096d008365059e39106cc7eaf51838014b4bf60b351f7102b81dcde08d046da1e94bfdebbbbc968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000200d00164ed9c1e1260fcb9f792b6245de1f005cd7c317209fd80bea526ca50f4f34b08d41fe4b10354ae2ad53ff03b40bf52123c215f7a2128fba218f9c8aedefbd968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000208555657f1f767d8684901a9cc2c0e7d3a58e2862897ef69269b11d5a35d53f2d8c277833310f206a698042adcdf4546d3e37c2e9bf22759fee027a9f98bb4045bd968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000201bb32c3e1e30e3fe233a298a4046504b58d4027168feee92782ca933b12229683ff642613e755030d0e05a999cb734dca8c2997fb785e64976db49f2bf20b1f6bd968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002093ea7db83c1b00f767c5d9a8444a89e673c76650fcd236641d779273f33b8c6a20b271d972a916aec8287502ac54c3ac5d70bf512ef5a14e5fc9b48a29e9fa8ebd968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020ed0a183573cb44513ed1406d5778cb297bee55e23601639215997e9fa2947074fcb51d5ead454819a55dbde18a7dd11deefdd8b398608368491a740cc17d40d4bd968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000202d020ee433c6b6b3b57e6860445624fe3261ebe8c1a896ed7ad771fa4fe53828b0eab16e3b711bf20a45f7496afaa97b7cb61f741a2575ff67d41c0cc41061a9bd968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020a6618af38c19782cb86f4ae9523e25122c83f7d4ad86c3de6269b03cc277552dee036f8b7ea9aa003b00779651b9b1d15ebb1fa325a2fe7907da3a973e7ece68be968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000209f2a2e0e63ebe21dae0e544d869a6681a2ce1a8d32a9bb61efbbfb60bf9d0068bd8c6b5d05955040983240f7320f2f6350c31f3dd6bf269f233c44c85416fa27be968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020dae294386f34ebefd5600a489a42468bd77b9d9a94f9f0047bffdb6d85147e5ef923d9baf7b33b22335e78698e1ad814ce326e0c8d58a85ed5d76f3a43661e01be968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000203f153035956b92074431af6c4ab48215b5dfa73ded1d66e0af608503faf3937a96682d1bbc49b8b2b7820e9c1baac0194739e7107648db2cccdbd73d9fd90d7dbe968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020eb9b52c5bad46a2cccf1c6b455fa1c71108a247d861ffef731d64ffe9349d77d1bb4965dc2f60f4f10c0a4fcf6d32f8f7967a6a6f9ff4ff0081d35365e8f8ca7be968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000209198a452354ce3d41c31251984c9bde0774936c008729109eab8f87189ff2649905e51b5a9a28498667a927d54643a42650d7f92bcb9881c04f0afd68a432e4fbe968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020db8504d154d783caba552cda6517a7f467393c8208a00ae7df9706cfa4728f30d9e8beb25174e5bff0a57c75395a2e8d59b77a255450f4778be4ca45efaa5258bf968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000208e52e044a1a5b3e55ceea15d4463862bb06c429eea8b698ca4cd62559cfe3f7b7aa8e1c0db4603a9a4fafe4b8557c2b6b4d894a6b2329b652f075607e5df6ad4bf968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002070d4304efdb679ae5591e14753d318ef6db3d311576b51257f29626915b6860ed8f54db28d10cca91740b47776ca83c1ac7f5bd96fd0941bea3c2543f75f4f42bf968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020b18da05265704504a19343d8c799074b6a750fbe25671f2598801fb32ba3a22b5abeebb1cdff271f6ab4f1c0a2ca36847c21f489165a3dc7aafcc8901a201511bf968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020ffa6c8d91068a66b3d0cfe6cddbdb5c18a2d888b5ecd63c5a85203f062c0fe3b255b8aefb34245268d17b5cc88f59adc1a46383fdc3df5d9878e27aee0df9c7ebf968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000206bcb560d13c12b0f5b7f2eb035248c3020ff6b576d77204fab40d38833b49627e84cd4791a83f46d7571ba998f89d14cce2a588f133d04fc3153dc07b5448265bf968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020bcea973bde6a30d912996ca008e164c59e840b27d4cc99578ce9ff39e1dc676ff415730295094f95726c8a39a4adb431d4de1d176482c20c6f17166c846fd8b1c0968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020e3a41004882bc5ad6a67b59033eab40d52a2f4e7b988ebb6948cfab531b5e92eaba53a44c76230dd29b1a10bee19b6960d30d32f3abbbd490b5489b7bf5495bec0968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207f50cddfa5645e01402425d702643ff4cdfcaf2f78cdb0f04054e9713a524e09602706e93374f1c07e9902e0e97df0107f415ef58478a6b5d4072a7c5a38cdffc0968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020d0d1df53efaeed01e846f93085245daaf95b6eceb70fb2d6a5097dedde99b049eac1aad944efb3384318c64ad869f7b5fe68840d6d1d043e6cc43c0b743efacac0968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002009c4d650f5b21f072b23a3a51724a1f91ce39396d2882ccca3f8b14b21a7b56d4a668bbb125670902b49ede6cd4e2f5c0da12165627b68be2bf8595748282422c0968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020a68f7ec4f61e611a85f1c8bac0758bd8b96382b51b1b89d464ac2707d080192ff9cec0863d5e1241557a580cdd8843bf6c995e8caaec8f8e84b10f1c8f9529d7c0968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002018c6071e1e2e04480634a8c1567e9a608c874ac1da2aed1d41ec227908148a3029a5b5cb57fd440de434b181085a6fcd9edb11b3f39faaf64fa938b158ca2678c1968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020e3e21313f5dff437e8d214028aa4686962bb39b0e07036495c59d15fc6098c4e517de3e01b55d9ffca6ca146796b8f615956ec068fdc9e09e900ae7fb8f93750c1968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020e45c518bdd7df129efab4ffdcce28b341bc34865815f79805b71c09f48f7345ff27efb73f28f7bde71db1e77423375a3db091d3079cf4f1ad262bae64bb3b876c1968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000202c3defd4604f5a44d619e2b4a7778c71e245b3b946dc8a0df72eb231f1e34f4dc38fd422d26fa5bdee5ecb507afffc55276f4d4631831548a25056e63b0764f1c1968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002044d5a4767d099d1ce66db9cea8ad0b0269886aadda67f5cd456810ac4c9be61a4d8eee55635eb72a3063015d1b253fc6736d9171e205faf2dd7849bf431928cbc1968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020df1c63486eef1b1fcaf66298bc72c4ca3fa18cdfc9ae16fcc44e2fb476a8d374579c409f4a869c944257bcb84425b3314266efb09df739745faddffd6caf88e0c1968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000204b95c58d49293ee93c829caf0e168c5d4dc351b3f03c5cfd90d783fc23ecb26c256d8d1d5d652172154f66af36a2941e2dd64a5c72e1c164325e6791e970ea7ac2968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020b98f8c9019c2f15fc20e9feac7be5a34c8aee095c892d856fb03404c957c8e07fefb7e7f058744a84fa66f8a01ad7497a21a214cfaf0273a91fe3e52bc25724fc2968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020ef4a19c437935069b145e84a07be7e4674e6d67631c51e8d70d57dbd14f0a40fc63d7525b75f0539d56997c22d0991cf123dfbd04793824c2aacc62f77b917d1c2968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000208b1f0937d79bbbded175ac9ae9a7a0071ce3889175b3d56e50813f3d953cdb394e4c4bffcd52b7b921311c27ee643fde75453ba0d9355a5a29bcf2a8d9a6c865c2968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002059d9defc2c41ecd3472b27bb624c19fed2e898c95d1f31c961f34383e03ca31bf6d098c6397a08116cfaa80d75088f0e5348b8290b29fd0b4c9b17407ce8fb61c2968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020fcf24d49e1cd74612ecce9d2f98769638f68d8cb40191330e2d1e418d7c4a93e3bd0172c8fe1869be148ed31276d50beed3278dc1b579bcf1dd18369f8b045b9c2968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002096b5ce0c70ea0c4700b3ec1c3ffe2c9ef8d7dd1b69208657d9142d832785b6674283d2ce1f7c63664d1a76ca64d0149cb7ac04c7445b5b2cd62da985b4820a6fc3968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002025713aacb9c435d23ef2c6451f28ac7c450169143f26f097fc9ab82d561f5c58d0fd6d62f513609348ff1bac5426fcd91688b7271dcc82451389e7a9240f1988c3968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000201e57b1039b3c12a9b4cae4c4c6c3eb4bd9e8172237f3b66307c628962efab336f4dc0e0f0c7ec239f3699a537b353d93fa0423c15d6a2f6f479bb7490adab0c3c3968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020a10993c816215503a3e33ecb4c13252cd7f3b2d779385e3e8fbae114c6479c3ad8cdc73f080baff2ba3e233fbb3f11a3de923bd209da3e58451f4e56c9bdb5a2c3968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002080c814a4fe681dfbbb6acdd01dc109d7738bbfa98de412815df7986b2ae22d67585ca5c8c31b252069b7027639be58d96f7cbfe70c0a490b22f925a07ecd8ce8c3968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000206e4a5ce81b8d7ddf16161d374dc83131904c546dac3b733263768309de76276c22d27317a6e4067d9b0e67b30321acc5d5a6b5ddc3721077e898a6b0c859795ec3968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020cf3eb1d6e5e4b794b6791ada605f5212c5116fb9a2b5a071f082dedc59c2523b894e3a27194ac986fd643de4118d6192760556b03b5dae801986102ac772c278c4968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020448ce084a8e488210ed86a85800239f32c148041e164ae01b9833f1ec581d649970486e728fe3d0f0651e6949c6650f761961ce908bb70a6c13968f84cbde132c4968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000202cc74bf3b3a16026333164df71543790d964f9b6f1bec0ddc9f843edfa10f57dab5af2b5f11840097f80ead19ccfe621046660f0caec2fb907894651c349f439c4968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020fc0b565f57b248b00a1c72d6ef2d045c772ab6f2ed4b8550a6692a98fef8dc3403b1c2d42d9365dc8dc709c04b3bd389eef6d8050f2fe28a2a59c15d46c35dfec4968054ffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000206581c8b5f8e3271301eca1f650f4b12bf7a6ef4389be521245c153d3e6c84223a8c6c146ff1f8d0f4bb420c6bff5224087e9d8758d3cb1220757d53dc7db000fc4968054ffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000209c8b4e77d2ec79b70059a12eea0ed2c3a1892d340229b85073c685b4b0e63927fa7ac8eff9288431cabbddfc66772542833362113e2e9713016df1547254025bc4968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020c559a9e1086d9d2f2b66b0db9386daf061d8b470fa6251e850a0011d6d968a46843397dd87173632f1c2585ef83023f25f48dbd9b89f6a73a1238e4d5ffce787c5968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207a2c3bd37d5e59cfae2df7c985460fbf5df3827078fedcb07505c3e595e7d40389c0538d91d5d275093b8b7e094beb7a6b00ff8d1e413bc9b9c68f062a4ff463c5968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002094a48b7cec0d18270314893209cb581e50cf6f1eb667a01c9ec7835f3b437066ab7ab7241cdebe6a5a201a464a08a7126f1410fa3a0021800ea4d1a46d7d7db4c5968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002001fbc84b7f31fc9b01e81f19e14c22d4f386e210e9b25d0f410c12f1078e7c3d5db275b1f9fd2cffeeaececf5a6d41c5de4e227d3f0e426e6784cd342b935de4c5968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002003c254f2b65b6bfdb0f1b66cb9c8f17a0a0833eaffcff66d784761ef7ee8e027f0cce75f6f59dbb3bfc080068b62f622c61878942fc64fc29e76a6cfa97768afc5968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000209ac5170773ab5950842d8c05800cd9142009fd2f2e43bad0ac009c172377db790d58126e684e40cd2fe623a424c9ff680e9367d992337a69b1d085d3b74a406bc5968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000206a6f17881995afada19a945de7805948f1bde48ae2655a8763b47e0ad7e3c01005024958a8dfc1e0adcedf31eba27ac3ef2a0b8b574f41a881c605337bc4a1bbc6968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020dfb95e17c85412abe164ff43d302c5567b42f15c8e0b73a041db2aa12080240e49107bf761371cda528ca44e189ffd07c9de4a64f835112339da62afd22441d1c6968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002066a951d878d002478d15fd59ea9961a7212f10cc8ba22c7252af27a9b421a74da875ffeee73ae312d8172be74230d2afdb1c79e3c50d24faf0d177b7e4e614d5c6968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020413728bfba18a95203077c7c3627349d88ac8a3ad981902e15b908b45c4cde197d834d320ae121a1ccfb0fbd24147625c206eef436351e4eec1b16b8501366cdc6968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020e20b4be2808d8f3877bbd9bce136dc05e510da48d98524316dca6613f44d437907924ff519cbd7172368c08dd3c61e17339ceb956f77fd97259f09bffa71183cc6968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000201e15a9985bfd9ced0a9d3fb0f4452e8e7ca86fd565f1a31f737e90f153ba9d224abe9a27b9eafc06ce5cd7d8adf71527839a2e616c0885d85a6dfb8c455efcc5c6968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020da2914eff086f2780c7e052050d3613ce867dabf271c8f6655a12b2d8830d056ad8bd9f1f53ce32fa39e662339e5cab0d494f023e43297d9a024f927fd494d05c7968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020a9bebba4f45297a617a24ceaff1a8e52c7e4f5e8c36f7ce2b3ddee1829ce8e3f1ad6d7241335b6164c70f3546721aee27077db1fb7eee5bc4fcf31dd480352e0c7968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020b99f49545d15c5606479e40bcd827ee78ae30426d77602d340c5cdd23519e267e90fbf303e1dbd36d9866892fe7c324790cb67183213edf4932472ba51be2e9cc7968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002019f2cfe65a501beb47554ba482b4ecf350fa75da95675af923609239cd27f672ff4c208b9cedec0547042f592e7f0429ecbf6b672c7ccac45ac087ed27857886c7968054ffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000201a07c5c0b11c184f7688eec5f4765b330d2785fb0a6eed4544e6a3befeb347639374ef3bc633c5ac02654a1944db2c2c068e3da5fa95f2ff0cbb83c8d0d4c45fc7968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002018809dc9b6de89bcfc75ed7c285153c2f3b25ec4f95869efbb4c0999f97878594038a7a99b60afde6a17ca7f7cbf734e8faf7dd7a341fb02a2af9356a196bde7c7968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000204d72257f642fb619e59ebf687692cc72f968106b9eead697dd9bb021af65f142d622d78a617b738a5bb9606678eb25b5f0884e6268531ba9296a761c569f788bc8968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002094dfad4e8b5e63cd9e39a307dcfcee019e151a972543471f61f805c539252140fefdd16c208e8633a05b864bf60a4a93ee71b98a7b8125e25681442d7c9bf538c8968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000204935a3ff051219232abb3b604baa911383ce24ead00ae3a3c6063464860040013f7818eae4a13b712ff945e9fdf3b3eb37bcaeb33df8fd80243b4bc9d287b5c0c8968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000202c330267a4ed9436d24ef59cf8d6d1bdc6942046b2451917b1d3145ecadf993bbaa22905da24f918eea8853976ebf2836aa4acacc51d41822b6917f756147f98c8968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020dd73782c4f8a93663e23e8be418b4e50268c0de7226a77ae36a573fbc0f16870173d3d33a8ac186e969d9bc1c4b74c5a5f50944c703d185be7ef0c71b1730214c8968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207485444d5feed9bb2e3765e776bf2aa691fc31ac79ac65781768579bf9b60c632225485f95794701b7a8f2399673b4d1003ea87fa80a4a1351573c52db8576c3c8968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020480950162d22b925aebc47b43acebb4cf06f79091360159161ae122c6da01654c260b195d5418320d60e3d51496a3e87f7aa321a04a4afb5c0e755b09e993243c9968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207de07a24bb6e7d8019cf7f4d31316abe4c18b769c4fbb9b6bb2941ab49612a42225be312165cefb753433a394fb735d8ae21d788738ffdf64cd28780a0abf25dc9968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020b57350a195f62cbd292965acd1c0cb92be4a429bd4e4bab926c75ce83901ea64dab8796f9c1b80684d27dee14df3ad211d75ceb9afbb5d4a894942b3cc7c3102c9968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020bb3252615f4249f23caec5f76059ed424334328267ae1d3197cbeb285b115b613390c34632cc17ddd721aceed4c62dd5ba49f186b8324bc26a0ca982a68d6434c9968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000204bbf8b03fc9ce8993e48484b7db67188b6e9b646a51e16bd644ab00e4dbe24773ad044d19eafefdb6b4c6d65ececa7337a0a0064f3196b1d46fd4af4343275acc9968054ffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020a0b1eaac5fbf6ab980465a5be1d8f31db4196903067ed5b859030f3dca4dc95981889dd07230b24a75ee5cd2fcb3e45895e80850cbe7fc7ab78e5b08f1357601c9968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000204162aa81039c26c262accee0bd8371d1d2d6b677f07b1ab529928de10ba8de757ffa4ca475962e0bda93321757c41a6a5f515a7b5c0f7de6a28840de23216bb8ca968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000207aca991bb589dba9951725740e66e5594515ddae23f2ef2893388c26712087602857bc58f1f998c468a532c8626554fd04b878e3350ddff0caf628e1a806148aca968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020960bdf6bfc82efb561e5c4b471ea78807fdb8b157660371b16f1e4dac96e5f063596d3c5267468af37d63aa993274092dd3be81f98360867979230c454d10a4dca968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000203baaed5d8e61fbdc450bab30fe5272b039609905b222592788a1c5a58447957ebf3ac597821a09206b918da40cc25cbade47cdd5225752641974bebace56edc8ca968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020dd1e1a5d30b17205f9bb909cffde17256e652946cf4b00a7d61e24c1393d36703a0a1f7021f029b359d76e54b669d67ceb2c49f6dbbd3d904f0edc5867144a8dca968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020d4df9e6bfb3bdbd4141b3b23e05feccd1d4aa5571921f20714a0b7c7ffca251aaa5455bf04393250685f9c1c0584644fe3f14ee8155229b0e2f81059dd461201ca968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020c79f05a1e07d74455841f6ad39b1c3d1ae21082b01f51f1f479fac41e16e8923bc27a86f966b1cdb51e7ccefdda6d065171b63e22a5e0b9a22ee2df893e44e5fcb968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020dc1eeeb842e3fd10f5fc87c9ea4a80b469edb444b0c467075ffbc84bf5ec33289697c074dfcafeb6b820702f76af188afcf515e2f1be613378cf005c1e82a9efcb968054ffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000203f9c492a4a4685c0e566b550f6fe9916111e7db45bb57b371234e57d60243242e27cfb5e0923a0307ea05506a8f68db3d1df04d7f3f9ab19762bc3a5878642a4cb968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020863e87e6652dfe6b59836492bc0f3fb37a82ef2529ff15a1aede36d2063dd331c451fad00de58fbcb3a1b8ffdb6e1e2b7c90a81c0c2fb0a7d55bd16bce1d90a7cb968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000205385df1f1536c3605f689c63cb703c8dd5172b6397b1ba70d20e7906b57fa93cc27d3af5e7f96c2fc6b3e4d78273ebfb637f7eab33b35d55f290586267e3e398cb968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020ed05b823ddf4554fd9045193277a0faab20a70e891027f0596e3b249174d264bba1779eccc576afc207a3cc6a8e557c02bd9cbe3a8ce5ae54167749a1002448fcb968054ffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"000000201efffecbd5318020fe163d345818b7d65aaa360455ccb7355cea82b12d55de42587b4d615f41213977e4cd1afa8db8d348faa48db853356b58dc96db003af152cc968054ffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002010ecbaf4182ceb024d15fc78746de38eeec04534b080062ae68c8479cbb012229dc232c0f7c87d468b95f6828a6f8352adc1f6d943daf591819a9c0197e8888acc968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020908845e301e51d871ef682c4af4fce6b3c4ed3fcf19d75cde19be1732ed0430a5a5dc14043b54478caee581965be5e03ba18ae204953a5f912eb7e55d1aeecf6cc968054ffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"00000020970b5854877f7185951a7533c1eab484f9fedb0f1f2777f75ceab6c4a623f462150382883dab55e415bc27930cab432681f6ef4026d261a455ca753159c32548cc968054ffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0100743ba40b000000232102caa63f5d3c98e3c3288bf2d48781a37310413e5ae8bd1739fcdc5acf2a531df6ac00000000",
|
||||
"0000002099a4c0d31444c28fd4342ca134b6b48cd631fe035becde97bd25101a564f6501ce6e718907f6b9b8a5c3d1f3da745ae701009300608ef96c525bdc69f0cc2f8bcc968054ffff7f20010000000202000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff01c0743ba40b0000002321032db0e0841321363240d1d23c080293af0d09d513738ee265c1bf28afe7676352ac000000000200000001d95bb928a2b4d3efb01ceb96a9d4d11f9ef238c189f43ab970b5819c4e5397fe00000000494830450221009a83977e9c09f8689812d8ab9e4abaf8a165f949ed7fd7518210153705dba8b6022007cce45c49b9d1f0b38e1135f02474943f904d5f889b5b40c1ed4b93c4908d0c01feffffff0240c99a3b000000001976a914ee3d2fdcc2a2e196f8cd2926d4f2ab35db622b2188ac00aaa0680b0000001976a914521eb1d6939e11bb510cbce081a0a47db46b92c488ac65000000",
|
||||
"00000020431436f4c273aefda5852964afb7db65472a6e77479c62b230a96902a8a09c6595e4787454c7977ef362bae2e9337221222ef86ee3a5883ce21f773c81c5c84acc968054ffff7f20010000000402000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff017a7e3ca40b00000023210287d435ce15fb58e759a59d3521ecfc60c460dcd1ef5626a53302e50c54f904e6ac000000000200000001d1d98a1afcd724adf7d8562332bf354076a34fbe01c7ffd9d9e398a7e556f9ed000000006b483045022100fb7d906e086c85817f0a825db10476fd2d05fe7643262afe3498af7af220dbe102202de82497c0834ab6ef4ec67d06df0a898dbfd6c2f6001e90c13fb8d08674e08701210385d80e72a67e94af5ef2b1b7bb597bee585b60ff75b1dbe1637c1eb2c68c8dc7feffffff0228d8f405000000001976a914cf21eeb09f8459175ef0423ef2aa77a01d279baf88ac40e8a435000000001976a9145ac57136a313e96730372a674a8c989e18d699c288ac660000000200000001d1d98a1afcd724adf7d8562332bf354076a34fbe01c7ffd9d9e398a7e556f9ed010000006a473044022038360e9581bb1029736b9f53dedc6cb2fd6ef4ed9daf40ceb3f070c7c2c49c9e022032fdba975c5f2a390010e04f30dbfc05d8b6bfab8804b8b8fbc03c8cb9a955b401210304de6780a2a0d390c31f9a6955aab2e4bb723e7ce360fa506c7c13f8b61f95ebfeffffff021ec99a3b000000001976a9148054f981b25c1df6e135681cad224509520e16b588ac00e0052d0b0000001976a91443a569f0e4d6d476dcb63906c90017c17b0ac6b988ac0d0000000200000001baa1d7dc2bc6a35265e613348723653552ad0db810346ed10af24ea90d1b4c39000000004948304502210085fc86a66d6f9ef0f792f9ba1bb3bb5d66af88aa3d78a1c7d09bc095556c89a1022043dc7c73643930ac1a78b4f8210a35c35182683f0303c95927a877274c80847b01feffffff0200ca9a3b000000001976a9140be309740066ab801360d8fff294d1d1e3049e5488ac40a9a0680b0000001976a9149ec13209532c8315efd4f4fc92c1b840fb3ec99988ac25000000"
|
||||
],
|
||||
"mocktime": 1417713337,
|
||||
"stats": [
|
||||
{
|
||||
"avgfee": 0,
|
||||
"avgfeerate": 0,
|
||||
"avgtxsize": 0,
|
||||
"blockhash": "01654f561a1025bd97deec5b03fe31d68cb4b634a12c34d48fc24414d3c0a499",
|
||||
"height": 101,
|
||||
"ins": 0,
|
||||
"maxfee": 0,
|
||||
"maxfeerate": 0,
|
||||
"maxtxsize": 0,
|
||||
"medianfee": 0,
|
||||
"medianfeerate": 0,
|
||||
"mediantime": 1417713355,
|
||||
"mediantxsize": 0,
|
||||
"minfee": 0,
|
||||
"minfeerate": 0,
|
||||
"mintxsize": 0,
|
||||
"outs": 1,
|
||||
"subsidy": 50000000000,
|
||||
"time": 1417713356,
|
||||
"total_out": 0,
|
||||
"total_size": 0,
|
||||
"totalfee": 0,
|
||||
"txs": 1,
|
||||
"utxo_increase": 1,
|
||||
"utxo_size_inc": 85
|
||||
},
|
||||
{
|
||||
"avgfee": 192,
|
||||
"avgfeerate": 1,
|
||||
"avgtxsize": 192,
|
||||
"blockhash": "659ca0a80269a930b2629c47776e2a4765dbb7af642985a5fdae73c2f4361443",
|
||||
"height": 102,
|
||||
"ins": 1,
|
||||
"maxfee": 192,
|
||||
"maxfeerate": 1,
|
||||
"maxtxsize": 192,
|
||||
"medianfee": 192,
|
||||
"medianfeerate": 1,
|
||||
"mediantime": 1417713355,
|
||||
"mediantxsize": 192,
|
||||
"minfee": 192,
|
||||
"minfeerate": 1,
|
||||
"mintxsize": 192,
|
||||
"outs": 3,
|
||||
"subsidy": 50000000000,
|
||||
"time": 1417713356,
|
||||
"total_out": 49999999808,
|
||||
"total_size": 192,
|
||||
"totalfee": 192,
|
||||
"txs": 2,
|
||||
"utxo_increase": 2,
|
||||
"utxo_size_inc": 150
|
||||
},
|
||||
{
|
||||
"avgfee": 22739,
|
||||
"avgfeerate": 106,
|
||||
"avgtxsize": 214,
|
||||
"blockhash": "1be37db8b04b80d607631fe5d77351b27eabee984140a790bd1b852a715f0e6d",
|
||||
"height": 103,
|
||||
"ins": 3,
|
||||
"maxfee": 67800,
|
||||
"maxfeerate": 300,
|
||||
"maxtxsize": 226,
|
||||
"medianfee": 226,
|
||||
"medianfeerate": 1,
|
||||
"mediantime": 1417713356,
|
||||
"mediantxsize": 225,
|
||||
"minfee": 192,
|
||||
"minfeerate": 1,
|
||||
"mintxsize": 192,
|
||||
"outs": 7,
|
||||
"subsidy": 50000000000,
|
||||
"time": 1417713356,
|
||||
"total_out": 99999931590,
|
||||
"total_size": 643,
|
||||
"totalfee": 68218,
|
||||
"txs": 4,
|
||||
"utxo_increase": 4,
|
||||
"utxo_size_inc": 300
|
||||
}
|
||||
]
|
||||
}
|
181
test/functional/rpc_getblockstats.py
Executable file
181
test/functional/rpc_getblockstats.py
Executable file
@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2017-2017 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test getblockstats rpc call
|
||||
#
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_jsonrpc,
|
||||
)
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
TESTSDIR = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
class GetblockstatsTest(BitcoinTestFramework):
|
||||
|
||||
start_height = 101
|
||||
max_stat_pos = 2
|
||||
STATS_NEED_TXINDEX = [
|
||||
'avgfee',
|
||||
'avgfeerate',
|
||||
'maxfee',
|
||||
'maxfeerate',
|
||||
'medianfee',
|
||||
'medianfeerate',
|
||||
'minfee',
|
||||
'minfeerate',
|
||||
'totalfee',
|
||||
'utxo_size_inc',
|
||||
]
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option('--gen-test-data', dest='gen_test_data',
|
||||
default=False, action='store_true',
|
||||
help='Generate test data')
|
||||
parser.add_option('--test-data', dest='test_data',
|
||||
default='data/rpc_getblockstats.json',
|
||||
action='store', metavar='FILE',
|
||||
help='Test data file')
|
||||
|
||||
# def set_test_params(self):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [['-txindex'], ['-txindex=0', '-paytxfee=0.003']]
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def get_stats(self):
|
||||
return [self.nodes[0].getblockstats(hash_or_height=self.start_height + i) for i in range(self.max_stat_pos+1)]
|
||||
|
||||
def generate_test_data(self, filename):
|
||||
self.nodes[0].generate(101)
|
||||
|
||||
self.nodes[0].sendtoaddress(address=self.nodes[1].getnewaddress(), amount=10, subtractfeefromamount=True)
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
|
||||
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=10, subtractfeefromamount=True)
|
||||
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=10, subtractfeefromamount=False)
|
||||
self.nodes[1].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=1, subtractfeefromamount=True)
|
||||
self.sync_all()
|
||||
self.nodes[0].generate(1)
|
||||
|
||||
self.expected_stats = self.get_stats()
|
||||
|
||||
blocks = []
|
||||
tip = self.nodes[0].getbestblockhash()
|
||||
blockhash = None
|
||||
height = 0
|
||||
while tip != blockhash:
|
||||
blockhash = self.nodes[0].getblockhash(height)
|
||||
blocks.append(self.nodes[0].getblock(blockhash, 0))
|
||||
height += 1
|
||||
|
||||
to_dump = {
|
||||
'blocks': blocks,
|
||||
'mocktime': int(self.mocktime),
|
||||
'stats': self.expected_stats,
|
||||
}
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(to_dump, f, sort_keys=True, indent=2)
|
||||
|
||||
def load_test_data(self, filename):
|
||||
with open(filename, 'r') as f:
|
||||
d = json.load(f)
|
||||
blocks = d['blocks']
|
||||
self.mocktime = d['mocktime']
|
||||
self.expected_stats = d['stats']
|
||||
|
||||
# Set the timestamps from the file so that the nodes can get out of Initial Block Download
|
||||
self.nodes[0].setmocktime(self.mocktime)
|
||||
self.nodes[1].setmocktime(self.mocktime)
|
||||
|
||||
for b in blocks:
|
||||
self.nodes[0].submitblock(b)
|
||||
|
||||
def run_test(self):
|
||||
test_data = os.path.join(TESTSDIR, self.options.test_data)
|
||||
if self.options.gen_test_data:
|
||||
self.generate_test_data(test_data)
|
||||
else:
|
||||
self.load_test_data(test_data)
|
||||
|
||||
self.sync_all()
|
||||
stats = self.get_stats()
|
||||
expected_stats_noindex = []
|
||||
for stat_row in stats:
|
||||
expected_stats_noindex.append({k: v for k, v in stat_row.items() if k not in self.STATS_NEED_TXINDEX})
|
||||
|
||||
# Make sure all valid statistics are included but nothing else is
|
||||
expected_keys = self.expected_stats[0].keys()
|
||||
assert_equal(set(stats[0].keys()), set(expected_keys))
|
||||
|
||||
assert_equal(stats[0]['height'], self.start_height)
|
||||
assert_equal(stats[self.max_stat_pos]['height'], self.start_height + self.max_stat_pos)
|
||||
|
||||
for i in range(self.max_stat_pos+1):
|
||||
self.log.info('Checking block %d\n' % (i))
|
||||
assert_equal(stats[i], self.expected_stats[i])
|
||||
|
||||
# Check selecting block by hash too
|
||||
blockhash = self.expected_stats[i]['blockhash']
|
||||
stats_by_hash = self.nodes[0].getblockstats(hash_or_height=blockhash)
|
||||
assert_equal(stats_by_hash, self.expected_stats[i])
|
||||
|
||||
# Check with the node that has no txindex
|
||||
stats_no_txindex = self.nodes[1].getblockstats(hash_or_height=blockhash, stats=list(expected_stats_noindex[i].keys()))
|
||||
assert_equal(stats_no_txindex, expected_stats_noindex[i])
|
||||
|
||||
# Make sure each stat can be queried on its own
|
||||
for stat in expected_keys:
|
||||
for i in range(self.max_stat_pos+1):
|
||||
result = self.nodes[0].getblockstats(hash_or_height=self.start_height + i, stats=[stat])
|
||||
assert_equal(list(result.keys()), [stat])
|
||||
if result[stat] != self.expected_stats[i][stat]:
|
||||
self.log.info('result[%s] (%d) failed, %r != %r' % (
|
||||
stat, i, result[stat], self.expected_stats[i][stat]))
|
||||
assert_equal(result[stat], self.expected_stats[i][stat])
|
||||
|
||||
# Make sure only the selected statistics are included (more than one)
|
||||
some_stats = {'minfee', 'maxfee'}
|
||||
stats = self.nodes[0].getblockstats(hash_or_height=1, stats=list(some_stats))
|
||||
assert_equal(set(stats.keys()), some_stats)
|
||||
|
||||
# Test invalid parameters raise the proper json exceptions
|
||||
tip = self.start_height + self.max_stat_pos
|
||||
assert_raises_jsonrpc(-8, 'Target block height %d after current tip %d' % (tip+1, tip),
|
||||
self.nodes[0].getblockstats, hash_or_height=tip+1)
|
||||
assert_raises_jsonrpc(-8, 'Target block height %d is negative' % (-1),
|
||||
self.nodes[0].getblockstats, hash_or_height=-1)
|
||||
|
||||
# Make sure not valid stats aren't allowed
|
||||
inv_sel_stat = 'asdfghjkl'
|
||||
inv_stats = [
|
||||
[inv_sel_stat],
|
||||
['minfee' , inv_sel_stat],
|
||||
[inv_sel_stat, 'minfee'],
|
||||
['minfee', inv_sel_stat, 'maxfee'],
|
||||
]
|
||||
for inv_stat in inv_stats:
|
||||
assert_raises_jsonrpc(-8, 'Invalid selected statistic %s' % inv_sel_stat,
|
||||
self.nodes[0].getblockstats, hash_or_height=1, stats=inv_stat)
|
||||
|
||||
# Make sure we aren't always returning inv_sel_stat as the culprit stat
|
||||
assert_raises_jsonrpc(-8, 'Invalid selected statistic aaa%s' % inv_sel_stat,
|
||||
self.nodes[0].getblockstats, hash_or_height=1, stats=['minfee' , 'aaa%s' % inv_sel_stat])
|
||||
|
||||
assert_raises_jsonrpc(-8, 'One or more of the selected stats requires -txindex enabled',
|
||||
self.nodes[1].getblockstats, hash_or_height=self.start_height + self.max_stat_pos)
|
||||
|
||||
# Mainchain's genesis block shouldn't be found on regtest
|
||||
assert_raises_jsonrpc(-5, 'Block not found', self.nodes[0].getblockstats,
|
||||
hash_or_height='000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f')
|
||||
|
||||
if __name__ == '__main__':
|
||||
GetblockstatsTest().main()
|
@ -126,6 +126,7 @@ BASE_SCRIPTS= [
|
||||
'p2p-leaktests.py',
|
||||
'p2p-compactblocks.py',
|
||||
'sporks.py',
|
||||
'rpc_getblockstats.py',
|
||||
'p2p-fingerprint.py',
|
||||
'wallet-encryption.py',
|
||||
'uptime.py',
|
||||
|
Loading…
Reference in New Issue
Block a user