From d18e246a92db14b5dc704a46484d3b229c78ef65 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 14:21:20 -0400 Subject: [PATCH 01/63] Remove unused sprout datastructures --- src/wallet/asyncrpcoperation_sendmany.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 340c0c4cb..f71c6d2e2 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -96,16 +96,9 @@ private: SpendingKey spendingkey_; CScript opret_ = CScript(); - uint256 joinSplitPubKey_; - unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; - - // The key is the result string from calling JSOutPoint::ToString() - std::unordered_map jsopWitnessAnchorMap; - std::vector t_outputs_; std::vector z_outputs_; std::vector t_inputs_; - //std::vector z_sprout_inputs_; std::vector z_sapling_inputs_; TransactionBuilder builder_; From bd730cb92780d4aa3712e6bef84b07b93d30b593 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 14:47:43 -0400 Subject: [PATCH 02/63] Lock zins inside z_sendmany async operation --- src/wallet/asyncrpcoperation_sendmany.cpp | 46 +++++++++++++++++++++++ src/wallet/asyncrpcoperation_sendmany.h | 5 +++ 2 files changed, 51 insertions(+) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 311fc217c..f46a458dd 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -119,6 +119,11 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( } else { LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } + + // Lock UTXOs + //lock_utxos(); + // Lock shielded input notes + lock_notes(); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { @@ -185,6 +190,9 @@ void AsyncRPCOperation_sendmany::main() { s += strprintf(", error=%s)\n", getErrorMessage()); } LogPrintf("%s",s); + + //unlock_utxos(); // clean up + unlock_notes(); // clean up } // Notes: @@ -781,3 +789,41 @@ UniValue AsyncRPCOperation_sendmany::getStatus() const { obj.push_back(Pair("params", contextinfo_ )); return obj; } + +/* TODO: support locking taddr utxo inputs + +// Lock input utxos + void AsyncRPCOperation_sendmany::lock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : t_inputs_) { + COutPoint outpt(utxo.txid, utxo.vout); + pwalletMain->LockCoin(outpt); + } +} + +// Unlock input utxos +void AsyncRPCOperation_sendmany::unlock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : t_inputs_) { + COutPoint outpt(utxo.txid, utxo.vout); + pwalletMain->UnlockCoin(outpt); + } +} + +*/ + +// Lock input notes +void AsyncRPCOperation_sendmany::lock_notes() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto note : z_sapling_inputs_) { + pwalletMain->LockNote(note.op); + } +} + +// Unlock input notes +void AsyncRPCOperation_sendmany::unlock_notes() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto note : z_sapling_inputs_) { + pwalletMain->UnlockNote(note.op); + } +} diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index f71c6d2e2..8684cf97c 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -112,6 +112,11 @@ private: bool main_impl(); void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error + + void lock_utxos(); + void unlock_utxos(); + void lock_notes(); + void unlock_notes(); }; From 8980fceadf79c9158a572448a63355165682a74a Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 16:07:10 -0400 Subject: [PATCH 03/63] Add logging for the locking+unlocking of zins --- src/wallet/asyncrpcoperation_sendmany.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index f46a458dd..77c090d3a 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -124,6 +124,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( //lock_utxos(); // Lock shielded input notes lock_notes(); + LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId()); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { @@ -193,6 +194,7 @@ void AsyncRPCOperation_sendmany::main() { //unlock_utxos(); // clean up unlock_notes(); // clean up + LogPrint("zrpc", "%s: z_sendmany input notes unlocked\n", getId()); } // Notes: From 1b527bc8389a9907d959e6f1ac3dead3a77ce1fe Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 16:07:47 -0400 Subject: [PATCH 04/63] Add 'locked' key to the output of z_listunspent --- src/wallet/rpcwallet.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ef1be630a..5433df6af 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4218,8 +4218,12 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) libzcash::SaplingFullViewingKey fvk; pwalletMain->GetSaplingIncomingViewingKey(boost::get(entry.address), ivk); pwalletMain->GetSaplingFullViewingKey(ivk, fvk); - bool hasSaplingSpendingKey = pwalletMain->HaveSaplingSpendingKey(fvk); + const bool hasSaplingSpendingKey = pwalletMain->HaveSaplingSpendingKey(fvk); obj.push_back(Pair("spendable", hasSaplingSpendingKey)); + + const bool isLocked = pwalletMain->IsLockedNote(entry.op); + obj.push_back(Pair("locked", isLocked)); + obj.push_back(Pair("address", EncodePaymentAddress(entry.address))); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); // note.value() is equivalent to plaintext.value() obj.push_back(Pair("memo", HexStr(entry.memo))); From 8d93e5dfb42c8b9c0fcaab0e8680873928af6ecc Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 16:11:09 -0400 Subject: [PATCH 05/63] Add locked key to z_listunspent rpc docs --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5433df6af..d66922437 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4113,6 +4113,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"outindex\" (sapling) : n (numeric) the output index\n" " \"confirmations\" : n (numeric) the number of confirmations\n" " \"spendable\" : true|false (boolean) true if note can be spent by wallet, false if note has zero confirmations, false if address is watchonly\n" + " \"locked\" : true|false (boolean) true if note is part of an in-process async operation to spend it, such as z_mergetoaddress/z_sendmany/etc\n" " \"address\" : \"address\", (string) the shielded address\n" " \"amount\": xxxxx, (numeric) the amount of value in the note\n" " \"memo\": xxxxx, (string) hexademical string representation of memo field\n" From 40337a04b3bfbb4eb318cb1cb11ae486db758e42 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 16:57:29 -0400 Subject: [PATCH 06/63] Remove unused joinsplit variables --- src/wallet/asyncrpcoperation_shieldcoinbase.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index bd606e23e..b9a49611d 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -74,9 +74,6 @@ private: CAmount fee_; PaymentAddress tozaddr_; - uint256 joinSplitPubKey_; - unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; - std::vector inputs_; TransactionBuilder builder_; @@ -87,7 +84,6 @@ private: void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error void lock_utxos(); - void unlock_utxos(); }; From 982986bb707d0046361b1c4358d3e338e49cbd69 Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 17:00:28 -0400 Subject: [PATCH 07/63] Remove unused joinsplit variables from z_mergetoaddress --- src/wallet/asyncrpcoperation_mergetoaddress.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index f4360e13c..ab4a949eb 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -90,9 +90,6 @@ private: CTxDestination toTaddr_; PaymentAddress toPaymentAddress_; - uint256 joinSplitPubKey_; - unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; - std::vector utxoInputs_; std::vector saplingNoteInputs_; From dcdc9b4d693367885e8bb5f2145676789d8e03fc Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 17:37:25 -0400 Subject: [PATCH 08/63] We no longer need to include this joinsplit header --- src/wallet/asyncrpcoperation_sendmany.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 8684cf97c..316b7ac32 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -25,7 +25,6 @@ #include "amount.h" #include "primitives/transaction.h" #include "transaction_builder.h" -#include "zcash/JoinSplit.hpp" #include "zcash/Address.hpp" #include "wallet.h" From 532b15b45e0c5ed27bdfab2f2b595659704f2a6a Mon Sep 17 00:00:00 2001 From: Duke Date: Sun, 18 May 2025 17:38:03 -0400 Subject: [PATCH 09/63] Lock and unlock sapling notes during consolidations --- ...asyncrpcoperation_saplingconsolidation.cpp | 32 +++++++++++++++++++ .../asyncrpcoperation_saplingconsolidation.h | 5 +++ 2 files changed, 37 insertions(+) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 41455d360..755564492 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -74,6 +74,8 @@ void AsyncRPCOperation_saplingconsolidation::main() { } LogPrintf("%s", s); + unlock_notes(); // clean up + LogPrint("zrpc", "%s: consolidation input notes unlocked\n", getId()); } bool AsyncRPCOperation_saplingconsolidation::main_impl() { @@ -102,6 +104,11 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { return true; } + // store sapling inputs so we can correctly lock and unlock them + for (auto entry : saplingEntries) { + z_sapling_inputs_.push_back(entry); + } + if (fConsolidationMapUsed) { const vector& v = mapMultiArgs["-consolidatesaplingaddress"]; for(int i = 0; i < v.size(); i++) { @@ -233,6 +240,10 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { break; } + // Lock shielded input notes + lock_notes(); + LogPrint("zrpc", "%s: consolidation input notes locked\n", getId()); + if(pwalletMain->CommitAutomatedTx(tx)) { LogPrintf("%s: Committed consolidation transaction with txid=%s\n",opid, tx.GetHash().ToString()); amountConsolidated += actualAmountToSend; @@ -240,10 +251,15 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { numTxCreated++; } else { LogPrintf("%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n",opid , tx.GetHash().ToString()); + + unlock_notes(); + LogPrint("zrpc", "%s: consolidatoin input notes unlocked\n", getId()); + setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); status = false; break; } + } } @@ -275,3 +291,19 @@ UniValue AsyncRPCOperation_saplingconsolidation::getStatus() const { obj.push_back(Pair("target_height", targetHeight_)); return obj; } + +// Lock input notes +void AsyncRPCOperation_saplingconsolidation::lock_notes() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto note : z_sapling_inputs_) { + pwalletMain->LockNote(note.op); + } +} + +// Unlock input notes +void AsyncRPCOperation_saplingconsolidation::unlock_notes() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto note : z_sapling_inputs_) { + pwalletMain->UnlockNote(note.op); + } +} diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.h b/src/wallet/asyncrpcoperation_saplingconsolidation.h index 4cc370431..675a56ad7 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.h +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.h @@ -8,6 +8,7 @@ #include "univalue.h" #include "zcash/Address.hpp" #include "zcash/zip32.h" +#include "wallet.h" // for SaplingNoteEntry //Default fee used for consolidation transactions, in puposhis static const CAmount DEFAULT_CONSOLIDATION_FEE = 10000; @@ -32,10 +33,14 @@ public: virtual UniValue getStatus() const; + void lock_notes(); + void unlock_notes(); + private: int targetHeight_; bool main_impl(); + std::vector z_sapling_inputs_; void setConsolidationResult(int numTxCreated, const CAmount& amountConsolidated, const std::vector& consolidationTxIds); From 2bd3b510ed6596036be0a49aee6170b47382f65a Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 19 May 2025 08:56:53 -0400 Subject: [PATCH 10/63] Also lock transparent input utxos in z_sendmany, like z_mergetoaddress already does --- src/wallet/asyncrpcoperation_sendmany.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 77c090d3a..f5809c58d 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -121,7 +121,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( } // Lock UTXOs - //lock_utxos(); + lock_utxos(); // Lock shielded input notes lock_notes(); LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId()); @@ -192,7 +192,7 @@ void AsyncRPCOperation_sendmany::main() { } LogPrintf("%s",s); - //unlock_utxos(); // clean up + unlock_utxos(); // clean up unlock_notes(); // clean up LogPrint("zrpc", "%s: z_sendmany input notes unlocked\n", getId()); } @@ -792,13 +792,14 @@ UniValue AsyncRPCOperation_sendmany::getStatus() const { return obj; } -/* TODO: support locking taddr utxo inputs - // Lock input utxos void AsyncRPCOperation_sendmany::lock_utxos() { LOCK2(cs_main, pwalletMain->cs_wallet); for (auto utxo : t_inputs_) { - COutPoint outpt(utxo.txid, utxo.vout); + uint256 txid = std::get<0>(utxo); + int vout = std::get<1>(utxo); + + COutPoint outpt(txid, vout); pwalletMain->LockCoin(outpt); } } @@ -807,13 +808,14 @@ UniValue AsyncRPCOperation_sendmany::getStatus() const { void AsyncRPCOperation_sendmany::unlock_utxos() { LOCK2(cs_main, pwalletMain->cs_wallet); for (auto utxo : t_inputs_) { - COutPoint outpt(utxo.txid, utxo.vout); + uint256 txid = std::get<0>(utxo); + int vout = std::get<1>(utxo); + + COutPoint outpt(txid, vout); pwalletMain->UnlockCoin(outpt); } } -*/ - // Lock input notes void AsyncRPCOperation_sendmany::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); From cb1b3df55301309e37b13a4c6d8560f5e28ca201 Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 19 May 2025 09:20:54 -0400 Subject: [PATCH 11/63] Remove unused sprout junk --- src/wallet/asyncrpcoperation_sendmany.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 316b7ac32..42ae2e505 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -45,12 +45,6 @@ typedef std::tuple SendManyRecipient; // Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase) typedef std::tuple SendManyInputUTXO; -// A struct to help us track the witness and anchor for a given JSOutPoint -struct WitnessAnchorData { - boost::optional witness; - uint256 anchor; -}; - class AsyncRPCOperation_sendmany : public AsyncRPCOperation { public: AsyncRPCOperation_sendmany( @@ -169,6 +163,4 @@ public: } }; - #endif /* ASYNCRPCOPERATION_SENDMANY_H */ - From d7fe1d43cad5794d8560b8a049fb982578dcbb48 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 29 May 2025 18:43:30 -0400 Subject: [PATCH 12/63] Debug logs when locking/unlocking a note --- src/wallet/wallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b4bb6ded9..30f3fe714 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4587,12 +4587,14 @@ void CWallet::LockNote(const SaplingOutPoint& output) { AssertLockHeld(cs_wallet); setLockedSaplingNotes.insert(output); + fprintf(stderr,"%s: locking note\n", __func__); } void CWallet::UnlockNote(const SaplingOutPoint& output) { AssertLockHeld(cs_wallet); setLockedSaplingNotes.erase(output); + fprintf(stderr,"%s: unlocking note\n", __func__); } void CWallet::UnlockAllSaplingNotes() From b43a4f26531a27ee47fdad4a1c415c5afdafb102 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 30 May 2025 08:22:16 -0400 Subject: [PATCH 13/63] Remove unused code and formatting --- .../asyncrpcoperation_mergetoaddress.cpp | 30 +++++-------------- src/wallet/asyncrpcoperation_sendmany.cpp | 24 +-------------- 2 files changed, 8 insertions(+), 46 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index e09068ac4..c2784d5a2 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -53,13 +53,13 @@ using namespace libzcash; extern UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( - boost::optional builder, - CMutableTransaction contextualTx, - std::vector utxoInputs, - std::vector saplingNoteInputs, - MergeToAddressRecipient recipient, - CAmount fee, - UniValue contextInfo) : + boost::optional builder, + CMutableTransaction contextualTx, + std::vector utxoInputs, + std::vector saplingNoteInputs, + MergeToAddressRecipient recipient, + CAmount fee, + UniValue contextInfo) : tx_(contextualTx), utxoInputs_(utxoInputs), saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo) { if (fee < 0 || fee > MAX_MONEY) { @@ -192,22 +192,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() size_t numInputs = utxoInputs_.size(); - /* - // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects - size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); - { - LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { - limit = 0; - } - } - if (limit > 0 && numInputs > limit) { - throw JSONRPCError(RPC_WALLET_ERROR, - strprintf("Number of transparent inputs %d is greater than mempooltxinputlimit of %d", - numInputs, limit)); - } - */ - CAmount t_inputs_total = 0; for (MergeToAddressInputUTXO& t : utxoInputs_) { t_inputs_total += std::get<1>(t); diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index f5809c58d..b796b101f 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -205,12 +205,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { assert(isfromtaddr_ != isfromzaddr_); - /* TODO: this needs to allow DPoW addresses. Consensus-time checks do it correctly. - if(t_outputs_.size() > 0) { - throw JSONRPCError(RPC_WALLET_ERROR, "Extreme Privacy! You cannot send to a transparent address."); - } - */ - bool isSingleZaddrOutput = (t_outputs_.size()==0 && z_outputs_.size()==1); bool isMultipleZaddrOutput = (t_outputs_.size()==0 && z_outputs_.size()>=1); bool isPureTaddrOnlyTx = (isfromtaddr_ && z_outputs_.size() == 0); @@ -319,23 +313,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { t_inputs_ = selectedTInputs; t_inputs_total = selectedUTXOAmount; - /* - // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects - const size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); - { - LOCK(cs_main); - if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { - limit = 0; - } - } - if (limit > 0) { - size_t n = t_inputs_.size(); - if (n > limit) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Too many transparent inputs %zu > limit %zu", n, limit)); - } - } - */ - // update the transaction with these inputs if (isUsingBuilder_) { CScript scriptPubKey; @@ -680,6 +657,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_); } + // store sapling inputs so we can correctly lock and unlock them for (auto entry : saplingEntries) { z_sapling_inputs_.push_back(entry); std::string data(entry.memo.begin(), entry.memo.end()); From 88143a87fc659851ca191709b2e5fb68bb9888dc Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 30 May 2025 08:22:31 -0400 Subject: [PATCH 14/63] Clean up locks if z_sendmany is cancelled --- src/wallet/asyncrpcoperation_sendmany.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index b796b101f..a78fefb51 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -131,8 +131,13 @@ AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { } void AsyncRPCOperation_sendmany::main() { - if (isCancelled()) + + // clean up locks if we are cancelled + if (isCancelled()) { + unlock_utxos(); + unlock_notes(); return; + } set_state(OperationStatus::EXECUTING); start_execution_clock(); @@ -797,6 +802,7 @@ void AsyncRPCOperation_sendmany::unlock_utxos() { // Lock input notes void AsyncRPCOperation_sendmany::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); + fprintf(stderr,"%s: found %d notes to lock\n", z_sapling_inputs_.count() ); for (auto note : z_sapling_inputs_) { pwalletMain->LockNote(note.op); } @@ -805,6 +811,7 @@ void AsyncRPCOperation_sendmany::lock_notes() { // Unlock input notes void AsyncRPCOperation_sendmany::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); + fprintf(stderr,"%s: found %d notes to unlock\n", z_sapling_inputs_.count() ); for (auto note : z_sapling_inputs_) { pwalletMain->UnlockNote(note.op); } From dba46b2ba63a728fba2195bf2ac12e775d5d47c9 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 30 May 2025 08:40:42 -0400 Subject: [PATCH 15/63] Wait until after find_unspent_notes() to lock notes in z_sendmany --- src/wallet/asyncrpcoperation_sendmany.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index a78fefb51..03507c7d5 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -120,11 +120,6 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } - // Lock UTXOs - lock_utxos(); - // Lock shielded input notes - lock_notes(); - LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId()); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { @@ -240,6 +235,15 @@ bool AsyncRPCOperation_sendmany::main_impl() { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); } + // Now that find_unspent_notes() has run, we now know which + // notes need to be locked + + // Lock UTXOs + lock_utxos(); + // Lock shielded input notes + lock_notes(); + LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId()); + CAmount t_inputs_total = 0; for (SendManyInputUTXO & t : t_inputs_) { t_inputs_total += std::get<2>(t); @@ -802,7 +806,7 @@ void AsyncRPCOperation_sendmany::unlock_utxos() { // Lock input notes void AsyncRPCOperation_sendmany::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %d notes to lock\n", z_sapling_inputs_.count() ); + fprintf(stderr,"%s: found %lu notes to lock\n", __func__, z_sapling_inputs_.size() ); for (auto note : z_sapling_inputs_) { pwalletMain->LockNote(note.op); } @@ -811,7 +815,7 @@ void AsyncRPCOperation_sendmany::lock_notes() { // Unlock input notes void AsyncRPCOperation_sendmany::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %d notes to unlock\n", z_sapling_inputs_.count() ); + fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, z_sapling_inputs_.size() ); for (auto note : z_sapling_inputs_) { pwalletMain->UnlockNote(note.op); } From e38e10acddb573f1dbe4d2079c7b511d22bdaf54 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 30 May 2025 09:54:44 -0400 Subject: [PATCH 16/63] Show a prefix of the first 8 chars of the hash for note debug lines --- src/wallet/wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 30f3fe714..1ab4447cc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1840,7 +1840,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, auto noteData = mapWallet[note.hash].mapSaplingNoteData; auto nWitnesses = noteData[note].witnesses.size(); if (mapWallet.count(note.hash) && noteData.count(note) && nWitnesses > 0) { - fprintf(stderr,"%s: Found %lu witnesses for note %s\n", __func__, nWitnesses, note.hash.ToString().c_str() ); + fprintf(stderr,"%s: Found %lu witnesses for note %s...\n", __func__, nWitnesses, note.hash.ToString().substr(0,8).c_str() ); witnesses[i] = noteData[note].witnesses.front(); if (!rt) { //fprintf(stderr,"%s: Setting witness root\n",__func__); @@ -4587,14 +4587,14 @@ void CWallet::LockNote(const SaplingOutPoint& output) { AssertLockHeld(cs_wallet); setLockedSaplingNotes.insert(output); - fprintf(stderr,"%s: locking note\n", __func__); + fprintf(stderr,"%s: locking note %s...\n", __func__, output.hash.ToString().substr(0,8).c_str() ); } void CWallet::UnlockNote(const SaplingOutPoint& output) { AssertLockHeld(cs_wallet); setLockedSaplingNotes.erase(output); - fprintf(stderr,"%s: unlocking note\n", __func__); + fprintf(stderr,"%s: unlocking note %s...\n", __func__, output.hash.ToString().substr(0,8).c_str() ); } void CWallet::UnlockAllSaplingNotes() From 46070c65fd94fca4118b7f6ec9251dda1722de04 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 30 May 2025 13:56:38 -0400 Subject: [PATCH 17/63] Remove comment which is no longer correct, z_mergetoaddress has locked notes for a long time now --- src/wallet/asyncrpcoperation_mergetoaddress.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index c2784d5a2..6c8975b23 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -182,7 +182,6 @@ void AsyncRPCOperation_mergetoaddress::main() // Notes: // 1. #1359 Currently there is no limit set on the number of inputs+outputs, so size of tx could be invalid. -// 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them. bool AsyncRPCOperation_mergetoaddress::main_impl() { assert(isToTaddr_ != isToZaddr_); From 4fde93960ba833eca0bdf3e17d64131edb79b87c Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 31 May 2025 10:09:24 -0400 Subject: [PATCH 18/63] Upstream zec issue 1360 is mostly about sprout and sending to taddrs, which is not relevant --- src/wallet/asyncrpcoperation_sendmany.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 03507c7d5..349e2e010 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -199,8 +199,7 @@ void AsyncRPCOperation_sendmany::main() { // Notes: // 1. #1159 Currently there is no limit set on the number of shielded spends, so size of tx could be invalid. -// 2. #1360 Note selection is not optimal -// 3. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them +// 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them bool AsyncRPCOperation_sendmany::main_impl() { assert(isfromtaddr_ != isfromzaddr_); From b5db300aed06112a4060ba14a5edd3512778ff47 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 31 May 2025 11:07:52 -0400 Subject: [PATCH 19/63] Clean up some comments --- src/wallet/rpcwallet.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fab9db288..4db196f7d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5131,7 +5131,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) fprintf(stderr,"%s: Selecting one of %lu potential source zaddrs\n", __func__, nPotentials); fromaddress = vPotentialAddresses[ GetRandInt(nPotentials) ]; } else { - // Automagic zaddr source election failed, exit honorably + // Automagic zaddr source selection failed, exit honorably throw JSONRPCError(RPC_INVALID_PARAMETER, "No single zaddr currently has enough funds to make that transaction, you may need to wait for confirmations."); } } else { @@ -5295,18 +5295,6 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; mtx.nVersion = SAPLING_TX_VERSION; unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING; - /* - const bool sapling = true; //NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { - if (!sapling) { - if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { - mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; - mtx.nVersion = OVERWINTER_TX_VERSION; - } else { - mtx.fOverwintered = false; - mtx.nVersion = 2; - } - } - */ // As a sanity check, estimate and verify that the size of the transaction will be valid. // Depending on the input notes, the actual tx size may turn out to be larger and perhaps invalid. @@ -5956,7 +5944,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp // Contextual transaction we will build on CMutableTransaction contextualTx; //= CreateNewContextualCMutableTransaction( Params().GetConsensus(), nextBlockHeight); - // Builder (used if Sapling addresses are involved) + // Builder (used if zaddrs are involved) boost::optional builder; if (isToSaplingZaddr || saplingNoteInputs.size() > 0) { builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); From 007f2b31af9a15fd497d0bc932ff719dca2a0809 Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 31 May 2025 11:50:38 -0400 Subject: [PATCH 20/63] Keep a list of notes we are spending and must lock which is different from the list of all notes we might spend --- src/wallet/asyncrpcoperation_sendmany.cpp | 33 +++++++++++++---------- src/wallet/asyncrpcoperation_sendmany.h | 4 +++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 349e2e010..f97795ab6 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -234,14 +234,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); } - // Now that find_unspent_notes() has run, we now know which - // notes need to be locked - // Lock UTXOs lock_utxos(); - // Lock shielded input notes - lock_notes(); - LogPrint("zrpc", "%s: z_sendmany input notes locked\n", getId()); CAmount t_inputs_total = 0; for (SendManyInputUTXO & t : t_inputs_) { @@ -412,7 +406,14 @@ bool AsyncRPCOperation_sendmany::main_impl() { std::vector ops; std::vector notes; CAmount sum = 0; - for (auto t : z_sapling_inputs_) { + + //NOTE: z_sapling_inputs_ is a list of all potential notes to spend + // saplingNoteInputs_ is a list of notes we will actually spend + // and need to lock. It is a subset of z_sapling_inputs_ + for (const auto t : z_sapling_inputs_) { + // keep track of notes to lock later on in lock_notes() + saplingNoteInputs_.emplace_back(t.op, t.note, t.note.value() ); + ops.push_back(t.op); notes.push_back(t.note); sum += t.note.value(); @@ -421,6 +422,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { } } + // Lock shielded input notes (zins) stored in saplingNoteInputs + lock_notes(); + // Fetch Sapling anchor and witnesses //LogPrintf("%s: Gathering anchors and witnesses\n", __FUNCTION__); uint256 anchor; @@ -665,9 +669,10 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_); } - // store sapling inputs so we can correctly lock and unlock them + for (auto entry : saplingEntries) { z_sapling_inputs_.push_back(entry); + std::string data(entry.memo.begin(), entry.memo.end()); LogPrint("zrpcunsafe", "%s: found unspent Sapling note (txid=%s, vShieldedSpend=%d, amount=%s, memo=%s)\n", getId(), @@ -805,17 +810,17 @@ void AsyncRPCOperation_sendmany::unlock_utxos() { // Lock input notes void AsyncRPCOperation_sendmany::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %lu notes to lock\n", __func__, z_sapling_inputs_.size() ); - for (auto note : z_sapling_inputs_) { - pwalletMain->LockNote(note.op); + fprintf(stderr,"%s: found %lu notes to lock\n", __func__, saplingNoteInputs_.size() ); + for (auto note : saplingNoteInputs_) { + pwalletMain->LockNote(std::get<0>(note)); } } // Unlock input notes void AsyncRPCOperation_sendmany::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, z_sapling_inputs_.size() ); - for (auto note : z_sapling_inputs_) { - pwalletMain->UnlockNote(note.op); + fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, saplingNoteInputs_.size() ); + for (auto note : saplingNoteInputs_) { + pwalletMain->UnlockNote(std::get<0>(note)); } } diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 42ae2e505..271daba3d 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -45,6 +45,9 @@ typedef std::tuple SendManyRecipient; // Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase) typedef std::tuple SendManyInputUTXO; +// Input note is a tuple of output, note, amount +typedef std::tuple SendManyInputSaplingNote; + class AsyncRPCOperation_sendmany : public AsyncRPCOperation { public: AsyncRPCOperation_sendmany( @@ -93,6 +96,7 @@ private: std::vector z_outputs_; std::vector t_inputs_; std::vector z_sapling_inputs_; + std::vector saplingNoteInputs_; TransactionBuilder builder_; CTransaction tx_; From 2b3f9ed33f15a30012eed8b3d95cd97e549a90bc Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 8 Aug 2025 16:09:32 -0400 Subject: [PATCH 21/63] Add -ac_clearnet=0 option so an entire chain can disable clearnet connection, instead of -clearnet=0 which only applies to a single node --- src/hush_defs.h | 1 + src/hush_globals.h | 1 + src/hush_utils.h | 8 +++++++- src/init.cpp | 5 +++-- src/main.cpp | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hush_defs.h b/src/hush_defs.h index 720fa70b5..f60aad8df 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -562,6 +562,7 @@ static const char *notaries_list[NUM_HUSH_SEASONS][NUM_HUSH_NOTARIES][2] = //#define PRICES_DAYWINDOW (7) //#endif +extern uint8_t ASSETCHAINS_CLEARNET; extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; extern int8_t ASSETCHAINS_ADAPTIVEPOW; int32_t MAX_BLOCK_SIZE(int32_t height); diff --git a/src/hush_globals.h b/src/hush_globals.h index 128d719da..4079f5cca 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -50,6 +50,7 @@ int32_t HUSH_INSYNC,HUSH_LASTMINED,prevHUSH_LASTMINED,HUSH_CCACTIVATE; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,ASSETCHAINS_MARMARA; int8_t ASSETCHAINS_ADAPTIVEPOW; +uint8_t ASSETCHAINS_CLEARNET = 1; uint8_t ASSETCHAINS_BURN = 0; uint32_t ASSETCHAINS_MINOPRETURNFEE = 0; std::vector Mineropret; diff --git a/src/hush_utils.h b/src/hush_utils.h index f1bb80697..721a65f12 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1853,6 +1853,7 @@ void hush_args(char *argv0) Split(GetArg("-ac_nk",""), sizeof(ASSETCHAINS_NK)/sizeof(*ASSETCHAINS_NK), ASSETCHAINS_NK, 0); ASSETCHAINS_BURN = GetArg("-ac_burn", 0); + ASSETCHAINS_CLEARNET = GetArg("-ac_clearnet", 1); ASSETCHAINS_MINOPRETURNFEE = GetArg("-ac_minopreturnfee", 0); // -ac_ccactivateht=evalcode,height,evalcode,height,evalcode,height.... @@ -2180,7 +2181,7 @@ void hush_args(char *argv0) } } - if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || HUSH_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 || ASSETCHAINS_CBMATURITY != 0 || ASSETCHAINS_ADAPTIVEPOW != 0 || ASSETCHAINS_BURN != 0 || ASSETCHAINS_MINOPRETURNFEE) + if ( ASSETCHAINS_ENDSUBSIDY[0] != 0 || ASSETCHAINS_REWARD[0] != 0 || ASSETCHAINS_HALVING[0] != 0 || ASSETCHAINS_DECAY[0] != 0 || ASSETCHAINS_COMMISSION != 0 || ASSETCHAINS_PUBLIC != 0 || ASSETCHAINS_PRIVATE != 0 || ASSETCHAINS_TXPOW != 0 || ASSETCHAINS_FOUNDERS != 0 || ASSETCHAINS_SCRIPTPUB.size() > 1 || ASSETCHAINS_SELFIMPORT.size() > 0 || ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 || ASSETCHAINS_TIMELOCKGTE != _ASSETCHAINS_TIMELOCKOFF|| ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH || ASSETCHAINS_LWMAPOS != 0 || ASSETCHAINS_LASTERA > 0 || ASSETCHAINS_BEAMPORT != 0 || ASSETCHAINS_CODAPORT != 0 || ASSETCHAINS_MARMARA != 0 || nonz > 0 || ASSETCHAINS_CCLIB.size() > 0 || ASSETCHAINS_FOUNDERS_REWARD != 0 || ASSETCHAINS_NOTARY_PAY[0] != 0 || ASSETCHAINS_BLOCKTIME != 60 || ASSETCHAINS_CBOPRET != 0 || Mineropret.size() != 0 || (ASSETCHAINS_NK[0] != 0 && ASSETCHAINS_NK[1] != 0) || HUSH_SNAPSHOT_INTERVAL != 0 || ASSETCHAINS_EARLYTXIDCONTRACT != 0 || ASSETCHAINS_CBMATURITY != 0 || ASSETCHAINS_ADAPTIVEPOW != 0 || ASSETCHAINS_BURN != 0 || ASSETCHAINS_MINOPRETURNFEE || (ASSETCHAINS_CLEARNET == 0) ) { if(fDebug) fprintf(stderr,"perc %.4f%% ac_pub=[%02x%02x%02x...] acsize.%d\n",dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0],ASSETCHAINS_OVERRIDE_PUBKEY33[1],ASSETCHAINS_OVERRIDE_PUBKEY33[2],(int32_t)ASSETCHAINS_SCRIPTPUB.size()); @@ -2350,6 +2351,11 @@ void hush_args(char *argv0) { extralen += dragon_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_MINOPRETURNFEE),(void *)&ASSETCHAINS_MINOPRETURNFEE); } + + if ( ASSETCHAINS_CLEARNET == 0 ) + { + extralen += dragon_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_CLEARNET),(void *)&ASSETCHAINS_CLEARNET); + } } addn = GetArg("-seednode",""); diff --git a/src/init.cpp b/src/init.cpp index 2877dd288..94bb2d977 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -606,6 +606,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-ac_burn", _("Allow sending funds to the transparent burn address when -ac_private=1")); strUsage += HelpMessageOpt("-ac_minopreturnfee", _("OP_RETURN minimum fee per tx, regardless of tx size, default is 1 coin")); strUsage += HelpMessageOpt("-ac_coda", _("CODA integration")); + strUsage += HelpMessageOpt("-ac_clearnet", _("Enable or disable clearnet connections for the entire blockchain. Setting to 0 will disable clearnet and use sane defaults for Tor/i2p and require all nodes to do the same") + " " + strprintf(_("(default: %u)"), DEFAULT_CLEARNET)); strUsage += HelpMessageOpt("-ac_decay", _("Percentage of block reward decrease at each halving")); strUsage += HelpMessageOpt("-ac_end", _("Block height at which block rewards will end")); strUsage += HelpMessageOpt("-ac_eras", _("Block reward eras")); @@ -1647,8 +1648,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } //fprintf(stderr,"%s tik18\n", __FUNCTION__); - // Disable clearnet peers if -clearnet=0 - if (!GetBoolArg("-clearnet", DEFAULT_CLEARNET)) { + // Disable clearnet peers if -clearnet=0 for this node or -ac_clearnet=0 for this chain + if (ASSETCHAINS_CLEARNET == 0 || !GetBoolArg("-clearnet", DEFAULT_CLEARNET)) { #ifdef ENABLE_MINING // mining to the same taddr links different txs together as from the same owner // and if using -clearnet=0 that can be used to link together different .onions diff --git a/src/main.cpp b/src/main.cpp index ff3c3ea64..87b38ec14 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS+1], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS+1]; extern uint32_t ASSETCHAINS_MAGIC; extern uint64_t ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY; -extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; +extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_CLEARNET; extern int32_t ASSETCHAINS_STAKED; extern uint64_t ASSETCHAINS_CBOPRET; From 03886da0192be15df0a6826ce91b9cbf5944ce64 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 8 Aug 2025 16:17:46 -0400 Subject: [PATCH 22/63] Remove unused code --- src/hush_gateway.h | 629 +-------------------------------------------- 1 file changed, 5 insertions(+), 624 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 3f6a83425..e196da944 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -79,102 +79,15 @@ struct pax_transaction *hush_paxmark(int32_t height,uint256 txid,uint16_t vout,u void hush_paxdelete(struct pax_transaction *pax) { - return; // breaks when out of order - pthread_mutex_lock(&hush_mutex); - HASH_DELETE(hh,PAX,pax); - pthread_mutex_unlock(&hush_mutex); } void hush_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t fiatoshis,uint8_t *rmd160,uint256 txid,uint16_t vout,uint8_t type,int32_t height,int32_t otherheight,char *source,int32_t approved) // assetchain context { - struct pax_transaction *pax; uint8_t buf[35]; int32_t addflag = 0; struct hush_state *sp; char str[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN],*s; - //if ( HUSH_PAX == 0 ) - // return; - //if ( strcmp(symbol,SMART_CHAIN_SYMBOL) != 0 ) - // return; - sp = hush_stateptr(str,dest); - pthread_mutex_lock(&hush_mutex); - pax_keyset(buf,txid,vout,type); - HASH_FIND(hh,PAX,buf,sizeof(buf),pax); - if ( pax == 0 ) - { - pax = (struct pax_transaction *)calloc(1,sizeof(*pax)); - pax->txid = txid; - pax->vout = vout; - pax->type = type; - memcpy(pax->buf,buf,sizeof(pax->buf)); - HASH_ADD_KEYPTR(hh,PAX,pax->buf,sizeof(pax->buf),pax); - addflag = 1; - if ( 0 && SMART_CHAIN_SYMBOL[0] == 0 ) - { - int32_t i; for (i=0; i<32; i++) - printf("%02x",((uint8_t *)&txid)[i]); - printf(" v.%d [%s] kht.%d ht.%d create pax.%p symbol.%s source.%s\n",vout,SMART_CHAIN_SYMBOL,height,otherheight,pax,symbol,source); - } - } - pthread_mutex_unlock(&hush_mutex); - if ( coinaddr != 0 ) - { - strcpy(pax->coinaddr,coinaddr); - if ( value != 0 ) - pax->puposhis = value; - if ( symbol != 0 ) - strcpy(pax->symbol,symbol); - if ( source != 0 ) - strcpy(pax->source,source); - if ( fiatoshis != 0 ) - pax->fiatoshis = fiatoshis; - if ( rmd160 != 0 ) - memcpy(pax->rmd160,rmd160,20); - if ( height != 0 ) - pax->height = height; - if ( otherheight != 0 ) - pax->otherheight = otherheight; - } - else - { - pax->marked = height; - //printf("pax.%p MARK DEPOSIT ht.%d other.%d\n",pax,height,otherheight); - } } int32_t hush_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transaction *pax) { - int32_t i,len = 0; - if ( rwflag == 1 ) - { - for (i=0; i<32; i++) - opretbuf[len++] = ((uint8_t *)&pax->txid)[i]; - opretbuf[len++] = pax->vout & 0xff; - opretbuf[len++] = (pax->vout >> 8) & 0xff; - } - else - { - for (i=0; i<32; i++) - ((uint8_t *)&pax->txid)[i] = opretbuf[len++]; - //for (i=0; i<32; i++) - // printf("%02x",((uint8_t *)&pax->txid)[31-i]); - pax->vout = opretbuf[len++]; - pax->vout += ((uint32_t)opretbuf[len++] << 8); - //printf(" txid v.%d\n",pax->vout); - } - len += dragon_rwnum(rwflag,&opretbuf[len],sizeof(pax->puposhis),&pax->puposhis); - len += dragon_rwnum(rwflag,&opretbuf[len],sizeof(pax->fiatoshis),&pax->fiatoshis); - len += dragon_rwnum(rwflag,&opretbuf[len],sizeof(pax->height),&pax->height); - len += dragon_rwnum(rwflag,&opretbuf[len],sizeof(pax->otherheight),&pax->otherheight); - if ( rwflag != 0 ) - { - memcpy(&opretbuf[len],pax->rmd160,20), len += 20; - for (i=0; i<4; i++) - opretbuf[len++] = pax->source[i]; - } - else - { - memcpy(pax->rmd160,&opretbuf[len],20), len += 20; - for (i=0; i<4; i++) - pax->source[i] = opretbuf[len++]; - } - return(len); + return 0; } int32_t hush_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t *values,int64_t *srcvalues,int32_t *hushheights,int32_t *otherheights,int8_t *baseids,uint8_t *rmd160s,uint8_t *opretbuf,int32_t opretlen,int32_t iskomodo) @@ -184,135 +97,12 @@ int32_t hush_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t * int32_t hush_paxcmp(char *symbol,int32_t hushheight,uint64_t value,uint64_t checkvalue,uint64_t seed) { - int32_t ratio; - if ( seed == 0 && checkvalue != 0 ) - { - ratio = ((value << 6) / checkvalue); - if ( ratio >= 60 && ratio <= 67 ) - return(0); - else - { - if ( SMART_CHAIN_SYMBOL[0] != 0 ) - printf("ht.%d ignore mismatched %s value %lld vs checkvalue %lld -> ratio.%d\n",hushheight,symbol,(long long)value,(long long)checkvalue,ratio); - return(-1); - } - } - else if ( checkvalue != 0 ) - { - ratio = ((value << 10) / checkvalue); - if ( ratio >= 1023 && ratio <= 1025 ) - return(0); - } - return(value != checkvalue); + return 0; } uint64_t hush_paxtotal() { - struct pax_transaction *pax,*pax2,*tmp,*tmp2; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN],*str; int32_t i,ht; int64_t checktoshis; uint64_t seed,total = 0; struct hush_state *basesp; - if ( HUSH_PASSPORT_INITDONE == 0 ) //HUSH_PAX == 0 || - return(0); - if ( hush_isrealtime(&ht) == 0 ) - return(0); - else - { - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->marked != 0 ) - continue; - if ( pax->type == 'A' || pax->type == 'D' || pax->type == 'X' ) - str = pax->symbol; - else str = pax->source; - basesp = hush_stateptrget(str); - if ( basesp != 0 && pax->didstats == 0 ) - { - if ( pax->type == 'I' && (pax2= hush_paxfind(pax->txid,pax->vout,'D')) != 0 ) - { - if ( pax2->fiatoshis != 0 ) - { - pax->puposhis = pax2->puposhis; - pax->fiatoshis = pax2->fiatoshis; - basesp->issued += pax->fiatoshis; - pax->didstats = 1; - if ( strcmp(str,SMART_CHAIN_SYMBOL) == 0 ) - printf("########### %p issued %s += %.8f hushheight.%d %.8f other.%d\n",basesp,str,dstr(pax->fiatoshis),pax->height,dstr(pax->puposhis),pax->otherheight); - pax2->marked = pax->height; - pax->marked = pax->height; - } - } - else if ( pax->type == 'W' ) - { - //bitcoin_address(coinaddr,addrtype,rmd160,20); - if ( (checktoshis= hush_paxprice(&seed,pax->height,pax->source,(char *)"HUSH3",(uint64_t)pax->fiatoshis)) != 0 ) - { - if ( hush_paxcmp(pax->source,pax->height,pax->puposhis,checktoshis,seed) != 0 ) - { - pax->marked = pax->height; - //printf("WITHDRAW.%s mark <- %d %.8f != %.8f\n",pax->source,pax->height,dstr(checktoshis),dstr(pax->puposhis)); - } - else if ( pax->validated == 0 ) - { - pax->validated = pax->puposhis = checktoshis; - //int32_t j; for (j=0; j<32; j++) - // printf("%02x",((uint8_t *)&pax->txid)[j]); - //if ( strcmp(str,SMART_CHAIN_SYMBOL) == 0 ) - // printf(" v%d %p got WITHDRAW.%s HUSH3.%d ht.%d %.8f -> %.8f/%.8f\n",pax->vout,pax,pax->source,pax->height,pax->otherheight,dstr(pax->fiatoshis),dstr(pax->puposhis),dstr(checktoshis)); - } - } - } - } - } - } - hush_stateptr(symbol,dest); - HASH_ITER(hh,PAX,pax,tmp) - { - pax->ready = 0; - if ( 0 && pax->type == 'A' ) - printf("%p pax.%s <- %s marked.%d %.8f -> %.8f validated.%d approved.%d\n",pax,pax->symbol,pax->source,pax->marked,dstr(pax->puposhis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0); - if ( pax->marked != 0 ) - continue; - if ( strcmp(symbol,pax->symbol) == 0 || pax->type == 'A' ) - { - if ( pax->marked == 0 ) - { - if ( hush_is_issuer() != 0 ) - { - if ( pax->validated != 0 && pax->type == 'D' ) - { - total += pax->fiatoshis; - pax->ready = 1; - } - } - else if ( pax->approved != 0 && pax->type == 'A' ) - { - if ( pax->validated != 0 ) - { - total += pax->puposhis; - pax->ready = 1; - } - else - { - seed = 0; - checktoshis = hush_paxprice(&seed,pax->height,pax->source,(char *)"HUSH3",(uint64_t)pax->fiatoshis); - //printf("paxtotal PAX_fiatdest ht.%d price %s %.8f -> HUSH %.8f vs %.8f\n",pax->height,pax->symbol,(double)pax->fiatoshis/COIN,(double)pax->puposhis/COIN,(double)checktoshis/COIN); - //printf(" v%d %.8f k.%d ht.%d\n",pax->vout,dstr(pax->puposhis),pax->height,pax->otherheight); - if ( seed != 0 && checktoshis != 0 ) - { - if ( checktoshis == pax->puposhis ) - { - total += pax->puposhis; - pax->validated = pax->puposhis; - pax->ready = 1; - } else pax->marked = pax->height; - } - } - } - if ( 0 && pax->ready != 0 ) - printf("%p (%c) pax.%s marked.%d %.8f -> %.8f validated.%d approved.%d ready.%d ht.%d\n",pax,pax->type,pax->symbol,pax->marked,dstr(pax->puposhis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0,pax->ready,pax->height); - } - } - } - //printf("paxtotal %.8f\n",dstr(total)); - return(total); + return(0); } static int _paxorder(const void *a,const void *b) @@ -382,150 +172,6 @@ int32_t hush_pending_withdraws(char *opretstr) // todo: enforce deterministic or int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo) { - struct pax_transaction *pax,*tmp; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; uint8_t *script,opcode,opret[16384*4],data[16384*4]; int32_t i,baseid,ht,len=0,opretlen=0,numvouts=1; struct hush_state *sp; uint64_t available,deposited,issued,withdrawn,approved,redeemed,mask,sum = 0; - if ( HUSH_PASSPORT_INITDONE == 0 )//HUSH_PAX == 0 || - return(0); - struct hush_state *hushsp = hush_stateptrget((char *)"HUSH3"); - sp = hush_stateptr(symbol,dest); - strcpy(symbol,base); - if ( SMART_CHAIN_SYMBOL[0] != 0 && hush_baseid(SMART_CHAIN_SYMBOL) < 0 ) - return(0); - PENDING_HUSH_TX = 0; - for (i=0; i<3; i++) - { - if ( hush_isrealtime(&ht) != 0 ) - break; - sleep(1); - } - if ( i == 3 ) - { - if ( tokomodo == 0 ) - printf("%s not realtime ht.%d\n",SMART_CHAIN_SYMBOL,ht); - return(0); - } - if ( tokomodo == 0 ) - { - opcode = 'I'; - } - else - { - opcode = 'X'; - if ( 1 || hush_paxtotal() == 0 ) - return(0); - } - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->type != 'D' && pax->type != 'A' ) - continue; - { -#ifdef HUSH_SMART_CHAINS_WAITNOTARIZE - if ( pax->height > 236000 ) - { - if ( hushsp != 0 && hushsp->NOTARIZED_HEIGHT >= pax->height ) - pax->validated = pax->puposhis; - else if ( hushsp->CURRENT_HEIGHT > pax->height+30 ) - pax->validated = pax->ready = 0; - } - else - { - if ( hushsp != 0 && (hushsp->NOTARIZED_HEIGHT >= pax->height || hushsp->CURRENT_HEIGHT > pax->height+30) ) // assumes same chain as notarize - pax->validated = pax->puposhis; - else pax->validated = pax->ready = 0; - } -#else - pax->validated = pax->puposhis; -#endif - } - if ( SMART_CHAIN_SYMBOL[0] != 0 && (pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,symbol) != 0 || available < pax->fiatoshis) ) - { - //if ( pax->height > 214700 || strcmp(SMART_CHAIN_SYMBOL,symbol) == 0 ) - // printf("miner.[%s]: skip %s %.8f when avail %.8f deposited %.8f, issued %.8f withdrawn %.8f approved %.8f redeemed %.8f\n",SMART_CHAIN_SYMBOL,symbol,dstr(pax->fiatoshis),dstr(available),dstr(deposited),dstr(issued),dstr(withdrawn),dstr(approved),dstr(redeemed)); - continue; - } - /*printf("pax.%s marked.%d %.8f -> %.8f ready.%d validated.%d\n",pax->symbol,pax->marked,dstr(pax->puposhis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0); - if ( pax->marked != 0 || (pax->type != 'D' && pax->type != 'A') || pax->ready == 0 ) - { - printf("reject 2\n"); - continue; - }*/ - if ( SMART_CHAIN_SYMBOL[0] != 0 && (strcmp(pax->symbol,symbol) != 0 || pax->validated == 0 || pax->ready == 0) ) - { - if ( strcmp(pax->symbol,SMART_CHAIN_SYMBOL) == 0 ) - printf("pax->symbol.%s != %s or null pax->validated %.8f ready.%d ht.(%d %d)\n",pax->symbol,symbol,dstr(pax->validated),pax->ready,hushsp->CURRENT_HEIGHT,pax->height); - pax->marked = pax->height; - continue; - } - if ( pax->ready == 0 ) - continue; - if ( pax->type == 'A' && SMART_CHAIN_SYMBOL[0] == 0 ) - { - if ( hushsp != 0 ) - { - if ( (baseid= hush_baseid(pax->symbol)) < 0 || ((1LL << baseid) & sp->RTmask) == 0 ) - { - printf("not RT for (%s) %llx baseid.%d %llx\n",pax->symbol,(long long)sp->RTmask,baseid,(long long)(1LL< %.8f ready.%d validated.%d approved.%d\n",tokomodo,pax->type,pax,pax->symbol,pax->marked,dstr(pax->puposhis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0,pax->approved!=0); - if ( 0 && SMART_CHAIN_SYMBOL[0] != 0 ) - printf("pax.%s marked.%d %.8f -> %.8f\n",SMART_CHAIN_SYMBOL,pax->marked,dstr(pax->puposhis),dstr(pax->fiatoshis)); - if ( opcode == 'I' ) - { - sum += pax->fiatoshis; - if ( sum > available ) - break; - } - txNew->vout.resize(numvouts+1); - txNew->vout[numvouts].nValue = (opcode == 'I') ? pax->fiatoshis : pax->puposhis; - txNew->vout[numvouts].scriptPubKey.resize(25); - script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0]; - *script++ = 0x76; - *script++ = 0xa9; - *script++ = 20; - memcpy(script,pax->rmd160,20), script += 20; - *script++ = 0x88; - *script++ = 0xac; - if ( tokomodo == 0 ) - { - for (i=0; i<32; i++) - data[len++] = ((uint8_t *)&pax->txid)[i]; - data[len++] = pax->vout & 0xff; - data[len++] = (pax->vout >> 8) & 0xff; - PENDING_HUSH_TX += pax->fiatoshis; - } - else - { - len += hush_rwapproval(1,&data[len],pax); - PENDING_HUSH_TX += pax->puposhis; - printf(" len.%d vout.%u DEPOSIT %.8f <- pax.%s pending ht %d %d %.8f | ",len,pax->vout,(double)txNew->vout[numvouts].nValue/COIN,symbol,pax->height,pax->otherheight,dstr(PENDING_HUSH_TX)); - } - if ( numvouts++ >= 64 || sum > COIN ) - break; - } - if ( numvouts > 1 ) - { - if ( tokomodo != 0 ) - strcpy(symbol,(char *)"HUSH3"); - for (i=0; symbol[i]!=0; i++) - data[len++] = symbol[i]; - data[len++] = 0; - for (i=0; ivout.resize(numvouts+1); - txNew->vout[numvouts].nValue = 0; - txNew->vout[numvouts].scriptPubKey.resize(opretlen); - script = (uint8_t *)&txNew->vout[numvouts].scriptPubKey[0]; - memcpy(script,opret,opretlen); - for (i=0; i<8; i++) - printf("%02x",opret[i]); - printf(" <- opret, MINER deposits.%d (%s) vouts.%d %.8f opretlen.%d\n",tokomodo,SMART_CHAIN_SYMBOL,numvouts,dstr(PENDING_HUSH_TX),opretlen); - return(1); - } return(0); } @@ -2142,101 +1788,6 @@ int32_t hush_priceind(const char *symbol) // returns price value which is in a 10% interval for more than 50% points for the preceding 24 hours int64_t hush_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth) { - int32_t i,j,k,n,iter,correlation,maxcorrelation=0; int64_t firstprice,price,sum,den,mult,refprice,lowprice,highprice; - if ( PRICES_DAYWINDOW < 2 || ind >= HUSH_MAXPRICES ) - return(-1); - mult = hush_pricemult(ind); - if ( nonzprices != 0 ) - memset(nonzprices,0,sizeof(*nonzprices)*PRICES_DAYWINDOW); - //for (i=0; i= PRICES_DAYWINDOW ) - i = 0; - if ( (price= rawprices[i*rawskip]) == 0 ) - { - fprintf(stderr,"null rawprice.[%d]\n",i); - return(-1); - } - if ( price >= lowprice && price <= highprice ) - { - //fprintf(stderr,"%.1f ",(double)price/10000); - sum += price; - correlation++; - if ( correlation > (PRICES_DAYWINDOW>>1) ) - { - if ( nonzprices == 0 ) - return(refprice * mult); - //fprintf(stderr,"-> %.4f\n",(double)sum*mult/correlation); - //return(sum*mult/correlation); - n = 0; - i = (iter + seed) % PRICES_DAYWINDOW; - for (k=0; k= PRICES_DAYWINDOW ) - i = 0; - if ( n > (PRICES_DAYWINDOW>>1) ) - nonzprices[i] = 0; - else - { - price = rawprices[i*rawskip]; - if ( price < lowprice || price > highprice ) - nonzprices[i] = 0; - else - { - nonzprices[i] = price; - //fprintf(stderr,"(%d %u) ",i,rawprices[i*rawskip]); - n++; - } - } - } - //fprintf(stderr,"ind.%d iter.%d j.%d i.%d n.%d correlation.%d ref %llu -> %llu\n",ind,iter,j,i,n,correlation,(long long)refprice,(long long)sum/correlation); - if ( n != correlation ) - return(-1); - sum = den = n = 0; - for (i=0; i %.8f\n",(long long)firstprice,((double)(sum*mult) / den) / COIN); - return((sum * mult) / den); - } - } - } - if ( correlation > maxcorrelation ) - maxcorrelation = correlation; - } - fprintf(stderr,"ind.%d iter.%d maxcorrelation.%d ref.%llu high.%llu low.%llu\n",ind,iter,maxcorrelation,(long long)refprice,(long long)highprice,(long long)lowprice); return(0); } @@ -2343,189 +1894,19 @@ static void revsort64(int64_t *l, int32_t llen) int64_t hush_priceave(int64_t *buf,int64_t *correlated,int32_t cskip) { - int32_t i,dir=0; int64_t sum=0,nonzprice,price,halfave,thirdave,fourthave,decayprice; - if ( PRICES_DAYWINDOW < 2 ) - return(0); - for (i=0; i price ) // rising prices - sort64(buf,PRICES_DAYWINDOW); - else revsort64(buf,PRICES_DAYWINDOW); - decayprice = buf[0]; - for (i=0; i %.8f\n",halfave 0 && PRICES[0].fp != 0 && createflag != 0 ) - { - fseek(PRICES[0].fp,(2*PRICES_DAYWINDOW+PRICES_SMOOTHWIDTH) * sizeof(uint32_t) * i,SEEK_SET); - fputc(0,PRICES[0].fp); - fflush(PRICES[0].fp); - } - fprintf(stderr,"pricesinit done i.%d num.%d numprices.%d\n",i,num,(int32_t)(hush_cbopretsize(ASSETCHAINS_CBOPRET)/sizeof(uint32_t))); - if ( i != num || i != hush_cbopretsize(ASSETCHAINS_CBOPRET)/sizeof(uint32_t) ) - { - fprintf(stderr,"fatal error opening prices files, start shutdown\n"); - StartShutdown(); - } return(0); } -pthread_mutex_t pricemutex; - -// PRICES file layouts -// [0] rawprice32 / timestamp -// [1] correlated -// [2] 24hr ave -// [3] to [7] reserved - void hush_pricesupdate(int32_t height,CBlock *pblock) { - static int numprices; static uint32_t *ptr32; static int64_t *ptr64,*tmpbuf; - int32_t ind,offset,width; int64_t correlated,smoothed; uint64_t seed,rngval; uint32_t rawprices[HUSH_MAXPRICES],buf[PRICES_MAXDATAPOINTS*2]; - width = PRICES_DAYWINDOW;//(2*PRICES_DAYWINDOW + PRICES_SMOOTHWIDTH); - if ( numprices == 0 ) - { - pthread_mutex_init(&pricemutex,0); - numprices = (int32_t)(hush_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t)); - ptr32 = (uint32_t *)calloc(sizeof(uint32_t),numprices * width); - ptr64 = (int64_t *)calloc(sizeof(int64_t),PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS); - tmpbuf = (int64_t *)calloc(sizeof(int64_t),2*PRICES_DAYWINDOW); - fprintf(stderr,"prices update: numprices.%d %p %p\n",numprices,ptr32,ptr64); - } - if ( _hush_heightpricebits(&seed,rawprices,pblock) == numprices ) - { - //for (ind=0; ind PRICES_DAYWINDOW ) - { - fseek(PRICES[0].fp,(height-width+1) * numprices * sizeof(uint32_t),SEEK_SET); - if ( fread(ptr32,sizeof(uint32_t),width*numprices,PRICES[0].fp) == width*numprices ) - { - rngval = seed; - for (ind=1; ind 0 ) - { - fseek(PRICES[ind].fp,height * sizeof(int64_t) * PRICES_MAXDATAPOINTS,SEEK_SET); - memset(buf,0,sizeof(buf)); - buf[0] = rawprices[ind]; - buf[1] = rawprices[0]; // timestamp - memcpy(&buf[2],&correlated,sizeof(correlated)); - if ( fwrite(buf,1,sizeof(buf),PRICES[ind].fp) != sizeof(buf) ) - fprintf(stderr,"error fwrite buf for ht.%d ind.%d\n",height,ind); - else if ( height > PRICES_DAYWINDOW*2 ) - { - fseek(PRICES[ind].fp,(height-PRICES_DAYWINDOW+1) * PRICES_MAXDATAPOINTS * sizeof(int64_t),SEEK_SET); - if ( fread(ptr64,sizeof(int64_t),PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS,PRICES[ind].fp) == PRICES_DAYWINDOW*PRICES_MAXDATAPOINTS ) - { - if ( (smoothed= hush_priceave(tmpbuf,&ptr64[(PRICES_DAYWINDOW-1)*PRICES_MAXDATAPOINTS+1],-PRICES_MAXDATAPOINTS)) > 0 ) - { - fseek(PRICES[ind].fp,(height * PRICES_MAXDATAPOINTS + 2) * sizeof(int64_t),SEEK_SET); - if ( fwrite(&smoothed,1,sizeof(smoothed),PRICES[ind].fp) != sizeof(smoothed) ) - fprintf(stderr,"error fwrite smoothed for ht.%d ind.%d\n",height,ind); - else fflush(PRICES[ind].fp); - } else fprintf(stderr,"error price_smoothed ht.%d ind.%d\n",height,ind); - } else fprintf(stderr,"error fread ptr64 for ht.%d ind.%d\n",height,ind); - } - } else fprintf(stderr,"error hush_pricecorrelated for ht.%d ind.%d\n",height,ind); - } - fprintf(stderr,"height.%d\n",height); - } else fprintf(stderr,"error reading rawprices for ht.%d\n",height); - } else fprintf(stderr,"height.%d <= width.%d\n",height,width); - pthread_mutex_unlock(&pricemutex); - } else fprintf(stderr,"null PRICES[0].fp\n"); - } else fprintf(stderr,"numprices mismatch, height.%d\n",height); } int32_t hush_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks) { - FILE *fp; int32_t retval = PRICES_MAXDATAPOINTS; - pthread_mutex_lock(&pricemutex); - if ( ind < HUSH_MAXPRICES && (fp= PRICES[ind].fp) != 0 ) - { - fseek(fp,height * PRICES_MAXDATAPOINTS * sizeof(int64_t),SEEK_SET); - if ( fread(buf64,sizeof(int64_t),numblocks*PRICES_MAXDATAPOINTS,fp) != numblocks*PRICES_MAXDATAPOINTS ) - retval = -1; - } - pthread_mutex_unlock(&pricemutex); - return(retval); + return 0; } - From 701ebf26a7e3391949314d9408d871c918dc8805 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 8 Aug 2025 16:32:27 -0400 Subject: [PATCH 23/63] Remove unused code --- src/hush_gateway.h | 278 --------------------------------------------- 1 file changed, 278 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index e196da944..8e0157a77 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -1365,15 +1365,6 @@ cJSON *send_curl(char *url,char *fname) // get_urljson just returns the JSON returned by the URL using issue_curl - -/* -const char *Techstocks[] = -{ "AAPL","ADBE","ADSK","AKAM","AMD","AMZN","ATVI","BB","CDW","CRM","CSCO","CYBR","DBX","EA","FB","GDDY","GOOG","GRMN","GSAT","HPQ","IBM","INFY","INTC","INTU","JNPR","MSFT","MSI","MU","MXL","NATI","NCR","NFLX","NTAP","NVDA","ORCL","PANW","PYPL","QCOM","RHT","S","SHOP","SNAP","SPOT","SYMC","SYNA","T","TRIP","TWTR","TXN","VMW","VOD","VRSN","VZ","WDC","XRX","YELP","YNDX","ZEN" -}; -const char *Metals[] = { "XAU", "XAG", "XPT", "XPD", }; -const char *Markets[] = { "DJIA", "SPX", "NDX", "VIX" }; -*/ - cJSON *get_urljson(char *url) { char *jsonstr; cJSON *json = 0; @@ -1386,177 +1377,6 @@ cJSON *get_urljson(char *url) return(json); } -int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector symbols) -{ - char url[32768],*symbol,*timestr; cJSON *json,*obj; int32_t i,n=0,retval=-1; uint32_t uprice,timestamp; - sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); - fprintf(stderr,"url.(%s)\n",url); - if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // - { - fprintf(stderr,"stocks.(%s)\n",jprint(json,0)); - if ( (n= cJSON_GetArraySize(json)) > 0 ) - { - retval = n; - for (i=0; i now+60 || timestamp < now-ASSETCHAINS_BLOCKTIME ) - { - fprintf(stderr,"time error.%d (%u vs %u)\n",timestamp-now,timestamp,now); - retval = -1; - }*/ - if ( symbols[i] != symbol ) - { - retval = -1; - fprintf(stderr,"MISMATCH."); - } - fprintf(stderr,"(%s %u) ",symbol,uprice); - } - } - fprintf(stderr,"numstocks.%d\n",n); - } - //https://api.iextrading.com/1.0/tops/last?symbols=AAPL -> [{"symbol":"AAPL","price":198.63,"size":100,"time":1555092606076}] - free_json(json); - } - return(retval); -} - -uint32_t get_dailyfx(uint32_t *prices) -{ - //{"base":"USD","rates":{"BGN":1.74344803,"NZD":1.471652701,"ILS":3.6329113924,"RUB":65.1997682296,"CAD":1.3430201462,"USD":1.0,"PHP":52.8641469068,"CHF":0.9970582992,"AUD":1.4129078267,"JPY":110.6792654662,"TRY":5.6523444464,"HKD":7.8499732573,"MYR":4.0824567659,"HRK":6.6232840078,"CZK":22.9862720628,"IDR":14267.4986628633,"DKK":6.6551078624,"NOK":8.6806917454,"HUF":285.131039401,"GBP":0.7626582278,"MXN":19.4183455161,"THB":31.8702085933,"ISK":122.5708682475,"ZAR":14.7033339276,"BRL":3.9750401141,"SGD":1.3573720806,"PLN":3.8286682118,"INR":69.33187734,"KRW":1139.1602781244,"RON":4.2423783206,"CNY":6.7387234801,"SEK":9.3385630237,"EUR":0.8914244963},"date":"2019-03-28"} - char url[512],*datestr; cJSON *json,*rates; int32_t i; uint32_t datenum=0,price = 0; - sprintf(url,"https://api.openrates.io/latest?base=USD"); - if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"dailyfx")) != 0 ) - { - if ( (rates= jobj(json,(char *)"rates")) != 0 ) - { - for (i=0; i strvec) -{ - int32_t i,errs=0; uint32_t price; char *symbol; - for (i=0; i 333 ) // for debug only! -// ASSETCHAINS_CBOPRET = 7; - size = hush_cbopretsize(ASSETCHAINS_CBOPRET); - if ( Mineropret.size() < size ) - Mineropret.resize(size); - size = PRICES_SIZEBIT0; - if ( (forceflag != 0 || now > lastbtc+120) && get_btcusd(pricebits) == 0 ) - { - if ( flags == 0 ) - hush_PriceCache_shift(); - memcpy(PriceCache[0],pricebits,PRICES_SIZEBIT0); - flags |= 1; - } - if ( (ASSETCHAINS_CBOPRET & 2) != 0 ) - { - if ( now > lasttime+3600*5 || forexprices[0] == 0 ) // cant assume timestamp is valid for forex price as it is a daily weekday changing thing anyway. - { - get_dailyfx(forexprices); - if ( flags == 0 ) - hush_PriceCache_shift(); - flags |= 2; - memcpy(&PriceCache[0][size/sizeof(uint32_t)],forexprices,sizeof(forexprices)); - } - size += (sizeof(Forex)/sizeof(*Forex)) * sizeof(uint32_t); - } - if ( (ASSETCHAINS_CBOPRET & 4) != 0 ) - { - if ( forceflag != 0 || flags != 0 ) - { - get_cryptoprices(pricebuf,Cryptos,(int32_t)(sizeof(Cryptos)/sizeof(*Cryptos)),ASSETCHAINS_PRICES); - if ( flags == 0 ) - hush_PriceCache_shift(); - memcpy(&PriceCache[0][size/sizeof(uint32_t)],pricebuf,(sizeof(Cryptos)/sizeof(*Cryptos)+ASSETCHAINS_PRICES.size()) * sizeof(uint32_t)); - flags |= 4; // very rarely we can see flags == 6 case - } - size += (sizeof(Cryptos)/sizeof(*Cryptos)+ASSETCHAINS_PRICES.size()) * sizeof(uint32_t); - } - now = (uint32_t)time(NULL); - if ( (ASSETCHAINS_CBOPRET & 8) != 0 ) - { - if ( forceflag != 0 || flags != 0 ) - { - if ( get_stockprices(now,pricebuf,ASSETCHAINS_STOCKS) == ASSETCHAINS_STOCKS.size() ) - { - if ( flags == 0 ) - hush_PriceCache_shift(); - memcpy(&PriceCache[0][size/sizeof(uint32_t)],pricebuf,ASSETCHAINS_STOCKS.size() * sizeof(uint32_t)); - flags |= 8; // very rarely we can see flags == 10 case - } - } - size += (ASSETCHAINS_STOCKS.size()) * sizeof(uint32_t); - } - if ( flags != 0 ) - { - if ( (flags & 1) != 0 ) - lastbtc = now; - if ( (flags & 2) != 0 ) - lasttime = now; - memcpy(Mineropret.data(),PriceCache[0],size); - if ( ExtremePrice.dir != 0 && ExtremePrice.ind > 0 && ExtremePrice.ind < size/sizeof(uint32_t) && now < ExtremePrice.timestamp+3600 ) - { - fprintf(stderr,"cmp dir.%d PriceCache[0][ExtremePrice.ind] %u >= %u ExtremePrice.pricebits\n",ExtremePrice.dir,PriceCache[0][ExtremePrice.ind],ExtremePrice.pricebits); - if ( (ExtremePrice.dir > 0 && PriceCache[0][ExtremePrice.ind] >= ExtremePrice.pricebits) || (ExtremePrice.dir < 0 && PriceCache[0][ExtremePrice.ind] <= ExtremePrice.pricebits) ) - { - fprintf(stderr,"future price is close enough to allow approving previously rejected block ind.%d %u vs %u\n",ExtremePrice.ind,PriceCache[0][ExtremePrice.ind],ExtremePrice.pricebits); - if ( (pindex= hush_blockindex(ExtremePrice.blockhash)) != 0 ) - pindex->nStatus &= ~BLOCK_FAILED_MASK; - else fprintf(stderr,"couldnt find block.%s\n",ExtremePrice.blockhash.GetHex().c_str()); - } - } - // high volatility still strands nodes so we need to check new prices to approve a stuck block - // scan list of stuck blocks (one?) and auto reconsiderblock if it changed state - - //int32_t i; for (i=0; i Date: Fri, 8 Aug 2025 17:36:11 -0400 Subject: [PATCH 24/63] Remove unused code --- src/hush_gateway.h | 350 +-------------------------------------------- 1 file changed, 1 insertion(+), 349 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 8e0157a77..707527c24 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -932,12 +932,6 @@ extern std::vector Mineropret; // opreturn data set by the data gatheri #define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0) -const char *Cryptos[] = { "HUSH", "ETH" }; -// "LTC", "BCHABC", "XMR", "IOTA", "ZEC", "WAVES", "LSK", "DCR", "RVN", "DASH", "XEM", "BTS", "ICX", "HOT", "STEEM", "ENJ", "STRAT" -const char *Forex[] = -{ "BGN","NZD","ILS","RUB","CAD","PHP","CHF","AUD","JPY","TRY","HKD","MYR","HRK","CZK","IDR","DKK","NOK","HUF","GBP","MXN","THB","ISK","ZAR","BRL","SGD","PLN","INR","KRW","RON","CNY","SEK","EUR" -}; // must be in ECB list - struct hush_extremeprice { uint256 blockhash; @@ -952,116 +946,35 @@ struct hush_priceinfo char symbol[64]; } PRICES[HUSH_MAXPRICES]; -uint32_t PriceCache[HUSH_LOCALPRICE_CACHESIZE][HUSH_MAXPRICES];//4+sizeof(Cryptos)/sizeof(*Cryptos)+sizeof(Forex)/sizeof(*Forex)]; -int64_t PriceMult[HUSH_MAXPRICES]; int32_t hush_cbopretsize(uint64_t flags); void hush_PriceCache_shift() { - int32_t i; - for (i=HUSH_LOCALPRICE_CACHESIZE-1; i>0; i--) - memcpy(PriceCache[i],PriceCache[i-1],sizeof(PriceCache[i])); - memcpy(PriceCache[0],Mineropret.data(),Mineropret.size()); } int32_t _hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,CBlock *block) { - CTransaction tx; int32_t numvouts; std::vector vopret; - tx = block->vtx[0]; - numvouts = (int32_t)tx.vout.size(); - GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret); - if ( vopret.size() >= PRICES_SIZEBIT0 ) - { - if ( seedp != 0 ) - memcpy(seedp,&block->hashMerkleRoot,sizeof(*seedp)); - memcpy(heightbits,vopret.data(),vopret.size()); - return((int32_t)(vopret.size()/sizeof(uint32_t))); - } return(-1); } // hush_heightpricebits() extracts the price data in the coinbase for nHeight int32_t hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight) { - CBlockIndex *pindex; CBlock block; - if ( seedp != 0 ) - *seedp = 0; - if ( (pindex= hush_chainactive(nHeight)) != 0 ) - { - if ( hush_blockload(block,pindex) == 0 ) - { - return(_hush_heightpricebits(seedp,heightbits,&block)); - } - } - fprintf(stderr,"couldnt get pricebits for %d\n",nHeight); return(-1); } -/* - hush_pricenew() is passed in a reference price, the change tolerance and the proposed price. it needs to return a clipped price if it is too big and also set a flag if it is at or above the limit - */ uint32_t hush_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance) { - uint64_t highprice,lowprice; - if ( refprice < 2 ) - return(0); - highprice = ((uint64_t)refprice * (COIN + tolerance)) / COIN; // calc highest acceptable price - lowprice = ((uint64_t)refprice * (COIN - tolerance)) / COIN; // and lowest - if ( highprice == refprice ) - highprice++; - if ( lowprice == refprice ) - lowprice--; - if ( price >= highprice ) - { - //fprintf(stderr,"high %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); - if ( price > highprice ) // return non-zero only if we violate the tolerance - { - *maxflagp = 2; - return(highprice); - } - *maxflagp = 1; - } - else if ( price <= lowprice ) - { - //fprintf(stderr,"low %u vs h%llu l%llu tolerance.%llu\n",price,(long long)highprice,(long long)lowprice,(long long)tolerance); - if ( price < lowprice ) - { - *maxflagp = -2; - return(lowprice); - } - *maxflagp = -1; - } return(0); } -// hush_pricecmp() returns -1 if any of the prices are beyond the tolerance int32_t hush_pricecmp(int32_t nHeight,int32_t n,char *maxflags,uint32_t *pricebitsA,uint32_t *pricebitsB,int64_t tolerance) { - int32_t i; uint32_t newprice; - for (i=1; i newprice.%u out of tolerance maxflag.%d\n",nHeight,i,n,pricebitsB[i],pricebitsA[i],newprice,maxflags[i]); - return(-1); - } - } return(0); } -// hush_priceclamp() clamps any price that is beyond tolerance int32_t hush_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int64_t tolerance) { - int32_t i; uint32_t newprice; char maxflags[HUSH_MAXPRICES]; - memset(maxflags,0,sizeof(maxflags)); - for (i=1; i %u\n",i,n,refprices[i],pricebits[i],newprice); - pricebits[i] = newprice; - } - } return(0); } @@ -1110,161 +1023,12 @@ CScript hush_mineropret(int32_t nHeight) return(opret); } -/* - hush_opretvalidate() is the entire price validation! - it prints out some useful info for debugging, like the lag from current time and prev block and the prices encoded in the opreturn. - - The only way hush_opretvalidate() doesnt return an error is if maxflag is set or it is within tolerance of both the prior block and the local data. The local data validation only happens if it is a recent block and not a block from the past as the local node is only getting the current price data. - - */ - - void hush_queuelocalprice(int32_t dir,int32_t height,uint32_t timestamp,uint256 blockhash,int32_t ind,uint32_t pricebits) { - fprintf(stderr,"ExtremePrice dir.%d ht.%d ind.%d cmpbits.%u\n",dir,height,ind,pricebits); - ExtremePrice.dir = dir; - ExtremePrice.height = height; - ExtremePrice.blockhash = blockhash; - ExtremePrice.ind = ind; - ExtremePrice.timestamp = timestamp; - ExtremePrice.pricebits = pricebits; } int32_t hush_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int32_t nHeight,CScript scriptPubKey) { - int32_t testchain_exemption = 0; - std::vector vopret; char maxflags[HUSH_MAXPRICES]; uint256 bhash; double btcusd,btcgbp,btceur; uint32_t localbits[HUSH_MAXPRICES],pricebits[HUSH_MAXPRICES],prevbits[HUSH_MAXPRICES],newprice; int32_t i,j,prevtime,maxflag,lag,lag2,lag3,n,errflag,iter; uint32_t now; - now = (uint32_t)time(NULL); - if ( ASSETCHAINS_CBOPRET != 0 && nHeight > 0 ) - { - bhash = block->GetHash(); - GetOpReturnData(scriptPubKey,vopret); - if ( vopret.size() >= PRICES_SIZEBIT0 ) - { - n = (int32_t)(vopret.size() / sizeof(uint32_t)); - memcpy(pricebits,vopret.data(),Mineropret.size()); - memset(maxflags,0,sizeof(maxflags)); - if ( nHeight > 2 ) - { - prevtime = previndex->nTime; - lag = (int32_t)(now - pricebits[0]); - lag2 = (int32_t)(pricebits[0] - prevtime); - lag3 = (int32_t)(block->nTime - pricebits[0]); - if ( lag < -60 ) // avoid data from future - { - fprintf(stderr,"A ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); - return(-1); - } - if ( lag2 < -60 ) //testchain_exemption ) // must be close to last block timestamp - { - fprintf(stderr,"B ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d vs %d cmp.%d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3,ASSETCHAINS_BLOCKTIME,lag2<-ASSETCHAINS_BLOCKTIME); - if ( nHeight > testchain_exemption ) - return(-1); - } - if ( lag3 < -60 || lag3 > ASSETCHAINS_BLOCKTIME ) - { - fprintf(stderr,"C ht.%d now.%u htstamp.%u %u - pricebits[0] %u -> lags.%d %d %d\n",nHeight,now,prevtime,block->nTime,pricebits[0],lag,lag2,lag3); - if ( nHeight > testchain_exemption ) - return(-1); - } - btcusd = (double)pricebits[1]/10000; - btcgbp = (double)pricebits[2]/10000; - btceur = (double)pricebits[3]/10000; - fprintf(stderr,"ht.%d: lag.%d %.4f USD, %.4f GBP, %.4f EUR, GBPUSD %.6f, EURUSD %.6f, EURGBP %.6f [%d]\n",nHeight,lag,btcusd,btcgbp,btceur,btcusd/btcgbp,btcusd/btceur,btcgbp/btceur,lag2); - if ( hush_heightpricebits(0,prevbits,nHeight-1) > 0 ) - { - if ( nHeight < testchain_exemption ) - { - for (i=0; i= PRICES_SIZEBIT0 ) - { - memcpy(localbits,Mineropret.data(),Mineropret.size()); - if ( nHeight < testchain_exemption ) - { - for (i=0; i 0 && localbits[i] < prevbits[i] ) - { - if ( iter == 0 ) - break; - // second iteration checks recent prices to see if within local volatility - for (j=0; j= prevbits[i] ) - { - fprintf(stderr,"i.%d within recent localprices[%d] %u >= %u\n",i,j,PriceCache[j][i],prevbits[i]); - break; - } - if ( j == HUSH_LOCALPRICE_CACHESIZE ) - { - hush_queuelocalprice(1,nHeight,block->nTime,bhash,i,prevbits[i]); - break; - } - } - else if ( maxflag < 0 && localbits[i] > prevbits[i] ) - { - if ( iter == 0 ) - break; - for (j=0; jnTime,bhash,i,prevbits[i]); - break; - } - } - } - } - if ( i != n ) - { - if ( iter == 0 ) - { - fprintf(stderr,"force update prices\n"); - hush_cbopretupdate(1); - memcpy(localbits,Mineropret.data(),Mineropret.size()); - } else return(-1); - } - } - } - } - if ( bhash == ExtremePrice.blockhash ) - { - fprintf(stderr,"approved a previously extreme price based on new data ht.%d vs %u vs %u\n",ExtremePrice.height,ExtremePrice.timestamp,(uint32_t)block->nTime); - memset(&ExtremePrice,0,sizeof(ExtremePrice)); - } - return(0); - } else fprintf(stderr,"wrong size %d vs %d, scriptPubKey size %d [%02x]\n",(int32_t)vopret.size(),(int32_t)Mineropret.size(),(int32_t)scriptPubKey.size(),scriptPubKey[0]); - return(-1); - } return(0); } @@ -1382,18 +1146,7 @@ cJSON *get_urljson(char *url) int32_t hush_cbopretsize(uint64_t flags) { - int32_t size = 0; - if ( (ASSETCHAINS_CBOPRET & 1) != 0 ) - { - size = PRICES_SIZEBIT0; - if ( (ASSETCHAINS_CBOPRET & 2) != 0 ) - size += (sizeof(Forex)/sizeof(*Forex)) * sizeof(uint32_t); - if ( (ASSETCHAINS_CBOPRET & 4) != 0 ) - size += (sizeof(Cryptos)/sizeof(*Cryptos) + ASSETCHAINS_PRICES.size()) * sizeof(uint32_t); - if ( (ASSETCHAINS_CBOPRET & 8) != 0 ) - size += (ASSETCHAINS_STOCKS.size() * sizeof(uint32_t)); - } - return(size); + return 0; } extern uint256 Queued_reconsiderblock; @@ -1404,110 +1157,9 @@ void hush_cbopretupdate(int32_t forceflag) int64_t hush_pricemult(int32_t ind) { - int32_t i,j; - if ( (ASSETCHAINS_CBOPRET & 1) != 0 && ind < HUSH_MAXPRICES ) - { - if ( PriceMult[0] == 0 ) - { - for (i=0; i<4; i++) - PriceMult[i] = 10000; - if ( (ASSETCHAINS_CBOPRET & 2) != 0 ) - { - for (j=0; j Date: Fri, 8 Aug 2025 18:02:25 -0400 Subject: [PATCH 25/63] Remove unused code --- src/hush_gateway.h | 117 +---------------------------------------- src/rpc/blockchain.cpp | 3 -- 2 files changed, 1 insertion(+), 119 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 707527c24..e303de226 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -18,7 +18,6 @@ // paxdeposit equivalent in reverse makes opreturn and HUSH does the same in reverse #include "hush_defs.h" - int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base) { return(-1); @@ -41,39 +40,9 @@ struct pax_transaction *hush_paxfind(uint256 txid,uint16_t vout,uint8_t type) return(pax); } -struct pax_transaction *hush_paxfinds(uint256 txid,uint16_t vout) -{ - struct pax_transaction *pax; int32_t i; uint8_t types[] = { 'I', 'D', 'X', 'A', 'W' }; - for (i=0; itxid = txid; - pax->vout = vout; - pax->type = type; - memcpy(pax->buf,buf,sizeof(pax->buf)); - HASH_ADD_KEYPTR(hh,PAX,pax->buf,sizeof(pax->buf),pax); - //printf("ht.%d create pax.%p mark.%d\n",height,pax,mark); - } - if ( pax != 0 ) - { - pax->marked = mark; - //if ( height > 214700 || pax->height > 214700 ) - // printf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->puposhis),dstr(pax->fiatoshis)); - - } - pthread_mutex_unlock(&hush_mutex); + struct pax_transaction *pax; return(pax); } @@ -105,71 +74,6 @@ uint64_t hush_paxtotal() return(0); } -static int _paxorder(const void *a,const void *b) -{ -#define pax_a (*(struct pax_transaction **)a) -#define pax_b (*(struct pax_transaction **)b) - uint64_t aval,bval; - aval = pax_a->fiatoshis + pax_a->puposhis + pax_a->height; - bval = pax_b->fiatoshis + pax_b->puposhis + pax_b->height; - if ( bval > aval ) - return(-1); - else if ( bval < aval ) - return(1); - return(0); -#undef pax_a -#undef pax_b -} - -int32_t hush_pending_withdraws(char *opretstr) // todo: enforce deterministic order -{ - struct pax_transaction *pax,*pax2,*tmp,*paxes[64]; uint8_t opretbuf[16384*4]; int32_t i,n,ht,len=0; uint64_t total = 0; - if ( HUSH_PAX == 0 || HUSH_PASSPORT_INITDONE == 0 ) - return(0); - if ( hush_isrealtime(&ht) == 0 || SMART_CHAIN_SYMBOL[0] != 0 ) - return(0); - n = 0; - HASH_ITER(hh,PAX,pax,tmp) - { - if ( pax->type == 'W' ) - { - if ( (pax2= hush_paxfind(pax->txid,pax->vout,'A')) != 0 ) - { - if ( pax2->approved != 0 ) - pax->approved = pax2->approved; - } - else if ( (pax2= hush_paxfind(pax->txid,pax->vout,'X')) != 0 ) - pax->approved = pax->height; - //printf("pending_withdraw: pax %s marked.%u approved.%u validated.%llu\n",pax->symbol,pax->marked,pax->approved,(long long)pax->validated); - if ( pax->marked == 0 && pax->approved == 0 && pax->validated != 0 ) - { - if ( n < sizeof(paxes)/sizeof(*paxes) ) - { - paxes[n++] = pax; - //int32_t j; for (j=0; j<32; j++) - // printf("%02x",((uint8_t *)&pax->txid)[j]); - //printf(" %s.(ht.%d ht.%d marked.%u approved.%d validated %.8f) %.8f\n",pax->source,pax->height,pax->otherheight,pax->marked,pax->approved,dstr(pax->validated),dstr(pax->puposhis)); - } - } - } - } - opretstr[0] = 0; - if ( n > 0 ) - { - opretbuf[len++] = 'A'; - qsort(paxes,n,sizeof(*paxes),_paxorder); - for (i=0; i>3)*7 ) - len += hush_rwapproval(1,&opretbuf[len],paxes[i]); - } - if ( len > 0 ) - init_hexbytes_noT(opretstr,opretbuf,len); - } - //fprintf(stderr,"hush_pending_withdraws len.%d PAXTOTAL %.8f\n",len,dstr(hush_paxtotal())); - return(len); -} - int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo) { return(0); @@ -932,26 +836,8 @@ extern std::vector Mineropret; // opreturn data set by the data gatheri #define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0) -struct hush_extremeprice -{ - uint256 blockhash; - uint32_t pricebits,timestamp; - int32_t height; - int16_t dir,ind; -} ExtremePrice; - -struct hush_priceinfo -{ - FILE *fp; - char symbol[64]; -} PRICES[HUSH_MAXPRICES]; - int32_t hush_cbopretsize(uint64_t flags); -void hush_PriceCache_shift() -{ -} - int32_t _hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,CBlock *block) { return(-1); @@ -1128,7 +1014,6 @@ cJSON *send_curl(char *url,char *fname) } // get_urljson just returns the JSON returned by the URL using issue_curl - cJSON *get_urljson(char *url) { char *jsonstr; cJSON *json = 0; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d0029b73e..abcc49c45 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1055,9 +1055,6 @@ UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) return ret; } -int32_t hush_pending_withdraws(char *opretstr); -extern char CURRENCIES[][8]; - UniValue gettxout(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() < 2 || params.size() > 3) From fc8c641cfffa751f4e2ef065082ead59f766136d Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 8 Aug 2025 21:58:39 -0400 Subject: [PATCH 26/63] Remove unused code --- src/hush_defs.h | 10 ---- src/hush_gateway.h | 140 --------------------------------------------- 2 files changed, 150 deletions(-) diff --git a/src/hush_defs.h b/src/hush_defs.h index f60aad8df..37e496fae 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -556,12 +556,6 @@ static const char *notaries_list[NUM_HUSH_SEASONS][NUM_HUSH_NOTARIES][2] = #define HUSH_BIT63SET(x) ((x) & ((uint64_t)1 << 63)) #define HUSH_VALUETOOBIG(x) ((x) > (uint64_t)10000000001*COIN) -//#ifndef TESTMODE -#define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) -//#else -//#define PRICES_DAYWINDOW (7) -//#endif - extern uint8_t ASSETCHAINS_CLEARNET; extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; extern int8_t ASSETCHAINS_ADAPTIVEPOW; @@ -623,12 +617,8 @@ int32_t hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeigh char *hush_pricename(char *name,int32_t ind); int32_t hush_priceind(const char *symbol); int32_t hush_pricesinit(); -int64_t hush_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); -int64_t hush_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); int32_t hush_nextheight(); uint32_t hush_heightstamp(int32_t height); -int64_t hush_pricemult(int32_t ind); -int32_t hush_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); int32_t hush_currentheight(); int32_t hush_notarized_bracket(struct notarized_checkpoint *nps[2],int32_t height); arith_uint256 hush_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime); diff --git a/src/hush_gateway.h b/src/hush_gateway.h index e303de226..a27b99927 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -18,11 +18,6 @@ // paxdeposit equivalent in reverse makes opreturn and HUSH does the same in reverse #include "hush_defs.h" -int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base) -{ - return(-1); -} - void pax_keyset(uint8_t *buf,uint256 txid,uint16_t vout,uint8_t type) { memcpy(buf,&txid,32); @@ -79,15 +74,6 @@ int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t toko return(0); } -int32_t hush_checkvout(int32_t vout,int32_t k,int32_t indallvouts) -{ - if ( k < indallvouts ) - return(vout == 1); - else if ( k == indallvouts || k == indallvouts+1 ) - return(1); - else return(vout == 0); -} - void hush_passport_iteration(); const char *hush_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_t opretlen,uint256 txid,uint16_t vout,char *source) @@ -1026,136 +1012,15 @@ cJSON *get_urljson(char *url) return(json); } -// hush_cbopretupdate() obtains the external price data and encodes it into Mineropret, which will then be used by the miner and validation -// save history, use new data to approve past rejection, where is the auto-reconsiderblock? - int32_t hush_cbopretsize(uint64_t flags) { return 0; } -extern uint256 Queued_reconsiderblock; - void hush_cbopretupdate(int32_t forceflag) { } -int64_t hush_pricemult(int32_t ind) -{ - return(0); -} - -int64_t hush_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth) -{ - return(0); -} - -int64_t _pairave64(int64_t valA,int64_t valB) -{ - if ( valA != 0 && valB != 0 ) - return((valA + valB) / 2); - else if ( valA != 0 ) return(valA); - else return(valB); -} - -int64_t _pairdiff64(register int64_t valA,register int64_t valB) -{ - if ( valA != 0 && valB != 0 ) - return(valA - valB); - else return(0); -} - -int64_t balanced_ave64(int64_t buf[],int32_t i,int32_t width) -{ - register int32_t nonz,j; register int64_t sum,price; - nonz = 0; - sum = 0; - for (j=-width; j<=width; j++) - { - price = buf[i + j]; - if ( price != 0 ) - { - sum += price; - nonz++; - } - } - if ( nonz != 0 ) - sum /= nonz; - return(sum); -} - -void buf_trioave64(int64_t dest[],int64_t src[],int32_t n) -{ - register int32_t i,j,width = 3; - for (i=0; i<128; i++) - src[i] = 0; - //for (i=n-width-1; i>width; i--) - // dest[i] = balanced_ave(src,i,width); - //for (i=width; i>0; i--) - // dest[i] = balanced_ave(src,i,i); - for (i=1; i *(int64_t *)b) return 1; - else if ( (uint64_t)a < (uint64_t)b ) // jl777 prevent nondeterminism - return(-1); - else return(1); -} - -static void sort64(int64_t *l, int32_t llen) -{ - qsort(l,llen,sizeof(uint64_t),cmp_llu); -} - -static int revcmp_llu(const void *a, const void*b) -{ - if(*(int64_t *)a < *(int64_t *)b) return 1; - else if(*(int64_t *)a > *(int64_t *)b) return -1; - else if ( (uint64_t)a < (uint64_t)b ) // jl777 prevent nondeterminism - return(-1); - else return(1); -} - -static void revsort64(int64_t *l, int32_t llen) -{ - qsort(l,llen,sizeof(uint64_t),revcmp_llu); -} - -int64_t hush_priceave(int64_t *buf,int64_t *correlated,int32_t cskip) -{ - return 0; -} - int32_t hush_pricesinit() { return(0); @@ -1164,8 +1029,3 @@ int32_t hush_pricesinit() void hush_pricesupdate(int32_t height,CBlock *pblock) { } - -int32_t hush_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks) -{ - return 0; -} From bd52fc5ee61d1490e36a0aa98f2ebaf48b25908a Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 11 Aug 2025 09:36:45 -0400 Subject: [PATCH 27/63] Try harder to avoid selecting locked notes to spend --- src/wallet/asyncrpcoperation_sendmany.cpp | 28 ++++++++++++++++++----- src/wallet/wallet.cpp | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index f97795ab6..a6d708e53 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -129,8 +129,9 @@ void AsyncRPCOperation_sendmany::main() { // clean up locks if we are cancelled if (isCancelled()) { - unlock_utxos(); + // We are more likely to be spending notes, so unlock them first unlock_notes(); + unlock_utxos(); return; } @@ -192,9 +193,9 @@ void AsyncRPCOperation_sendmany::main() { } LogPrintf("%s",s); - unlock_utxos(); // clean up unlock_notes(); // clean up - LogPrint("zrpc", "%s: z_sendmany input notes unlocked\n", getId()); + unlock_utxos(); // clean up + LogPrint("zrpc", "%s: z_sendmany input notes+utxos unlocked\n", getId()); } // Notes: @@ -411,7 +412,14 @@ bool AsyncRPCOperation_sendmany::main_impl() { // saplingNoteInputs_ is a list of notes we will actually spend // and need to lock. It is a subset of z_sapling_inputs_ for (const auto t : z_sapling_inputs_) { - // keep track of notes to lock later on in lock_notes() + // locked status of these inputs may have changed, check again + const bool isLocked = pwalletMain->IsLockedNote(t.op); + if (isLocked) { + LogPrintf("%s: skipping locked note %s\n", __func__, t.op.hash.ToString().substr(0,10).c_str()); + continue; + } + + // keep track of currently unlocked notes to lock later on in lock_notes() saplingNoteInputs_.emplace_back(t.op, t.note, t.note.value() ); ops.push_back(t.op); @@ -658,7 +666,7 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { return t_inputs_.size() > 0; } - +// find unspent notes which are also unlocked bool AsyncRPCOperation_sendmany::find_unspent_notes() { if(fZdebug) LogPrintf("%s: For address %s depth=%d\n", __FUNCTION__, fromaddress_.c_str(), mindepth_); @@ -666,11 +674,19 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { std::vector saplingEntries; { LOCK2(cs_main, pwalletMain->cs_wallet); + // GetFilteredNotes ignores locked notes by default pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_); } - for (auto entry : saplingEntries) { + // locked status of note may have changed since GetFilteredNotes() + // returned data, so we check again + const bool isLocked = pwalletMain->IsLockedNote(entry.op); + if (isLocked) { + LogPrintf("%s: skipping locked note %s:%d\n", __func__, entry.op.hash.ToString().substr(0,10).c_str(), entry.op.n); + continue; + } + z_sapling_inputs_.push_back(entry); std::string data(entry.memo.begin(), entry.memo.end()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cceef53e2..75445e8e1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4942,8 +4942,8 @@ void CWallet::GetFilteredNotes( } // skip locked notes - // TODO: Add locking for Sapling notes -> done if (ignoreLocked && IsLockedNote(op)) { + LogPrintf("%s: skipping locked note %s\n", __func__, op.hash.ToString().substr(0,10).c_str()); continue; } From 0cd2bafa3a7c2a221ceb4079da0bffc24224a347 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 13:37:44 -0400 Subject: [PATCH 28/63] Remove unused CLI options and update debian example config --- contrib/debian/examples/HUSH3.conf | 71 +++++++++++++++++++++++++----- src/hush_defs.h | 3 +- src/hush_globals.h | 4 +- src/hush_utils.h | 2 - src/wallet/wallet.cpp | 1 - 5 files changed, 64 insertions(+), 17 deletions(-) diff --git a/contrib/debian/examples/HUSH3.conf b/contrib/debian/examples/HUSH3.conf index f11e309c1..3d19720e4 100644 --- a/contrib/debian/examples/HUSH3.conf +++ b/contrib/debian/examples/HUSH3.conf @@ -4,6 +4,11 @@ # Run a regression test network #regtest=0 +# Run a test node (which means you can mine with no peers) +#testnode=1 + +# Rescan from block height +#rescan=123 # Connect via a SOCKS5 proxy #proxy=127.0.0.1:9050 @@ -63,8 +68,9 @@ #rpcbind= # You must set rpcuser and rpcpassword to secure the JSON-RPC api -#rpcuser=Ulysses -#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593 +# These will automatically be created for you +#rpcuser=user +#rpcpassword=supersecretpassword # How many seconds node will wait for a complete RPC HTTP request. # after the HTTP connection is established. @@ -83,7 +89,7 @@ #rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96 # Listen for RPC connections on this TCP port: -#rpcport=8232 +#rpcport=1234 # You can use hushd to send commands to hushd # running on another host using this option: @@ -100,8 +106,8 @@ # Miscellaneous options -# Enable attempt to mine HUSH -#gen=0 +# Enable mining at startup +#gen=1 # Set the number of threads to be used for mining (-1 = all cores). #genproclimit=1 @@ -121,7 +127,7 @@ #paytxfee=0.00 #Rewind the chain to specific block height. This is useful for creating snapshots at a given block height. -#rewind=777777 +#rewind=555 #Stop the chain a specific block height. This is useful for creating snapshots at a given block height. #stopat=1000000 @@ -129,9 +135,54 @@ #Set an address to use as change address for all transactions. This value must be set to a 33 byte pubkey. All mined coins will also be sent to this address. #pubkey=027dc7b5cfb5efca96674b45e9fda18df069d040b9fd9ff32c35df56005e330392 -#Forfeit all user rewards to miners. Set this to explicitly not claim user rewards. -#exchange=1 +# Disable clearnet (ipv4 and ipv6) connections to this node +#clearnet=0 -#Donate all user rewards to a a specific address. This value must be set to a 33 byte pubkey. -#donation=027dc7b5cfb5efca96674b45e9fda18df069d040b9fd9ff32c35df56005e330392 +# Disable ipv4 +#disableipv4=1 +# Disable ipv6 +#disableipv6=1 +# Enable transaction index +#txindex=1 +# Enable address index +#addressindex=1 +# Enable spent index +#spentindex=1 + +# Enable shielded stats index +#zindex=1 + +# Attempt to salvage a corrupt wallet +# salvagewallet=1 + +# Mine all blocks to this address (not good for your privacy and not recommended!) +# Disallowed if clearnet=0 +# mineraddress=XXX + +# Disable wallet +#disablewallet=1 + +# Allow mining to an address that is not in the current wallet +#minetolocalwallet=0 + +# Delete all wallet transactions +#zapwallettxes=1 + +# Enable sapling consolidation +# consolidation=1 + +# Enable stratum server +# stratum=1 + +# Run a command each time a new block is seen +# %s in command is replaced by block hash +#blocknotify=/my/awesome/script.sh %s + +# Run a command when wallet gets a new tx +# %s in command is replaced with txid +#walletnotify=/my/cool/script.sh %s + +# Run a command when tx expires +# %s in command is replaced with txid +#txexpirynotify=/my/elite/script.sh %s diff --git a/src/hush_defs.h b/src/hush_defs.h index 37e496fae..510a6309a 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -577,13 +577,12 @@ extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTP extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_MARMARA; extern std::vector ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS; extern uint256 HUSH_EARLYTXID; -extern int32_t HUSH_CONNECTING,HUSH_CCACTIVATE,HUSH_DEALERNODE; +extern int32_t HUSH_CONNECTING,HUSH_CCACTIVATE; extern uint32_t ASSETCHAINS_CC; extern std::string CCerror,ASSETCHAINS_CCLIB; extern uint8_t ASSETCHAINS_CCDISABLES[256]; extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY,NOTARY_ADDRESS; -extern std::string DONATION_PUBKEY; extern uint8_t ASSETCHAINS_PRIVATE; extern int32_t USE_EXTERNAL_PUBKEY; extern char NOTARYADDRS[64][64]; diff --git a/src/hush_globals.h b/src/hush_globals.h index 4079f5cca..f7bbeb860 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -45,9 +45,9 @@ int COINBASE_MATURITY = _COINBASE_MATURITY;//100; unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10; uint256 HUSH_EARLYTXID; -int32_t HUSH_MININGTHREADS = -1,IS_HUSH_NOTARY,USE_EXTERNAL_PUBKEY,HUSH_CHOSEN_ONE,ASSETCHAINS_SEED,HUSH_ON_DEMAND,HUSH_EXTERNAL_NOTARIES,HUSH_PASSPORT_INITDONE,HUSH_PAX,HUSH_EXCHANGEWALLET,HUSH_REWIND,HUSH_CONNECTING = -1,HUSH_DEALERNODE,HUSH_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,HUSH_NSPV; +int32_t HUSH_MININGTHREADS = -1,IS_HUSH_NOTARY,USE_EXTERNAL_PUBKEY,HUSH_CHOSEN_ONE,ASSETCHAINS_SEED,HUSH_ON_DEMAND,HUSH_EXTERNAL_NOTARIES,HUSH_PASSPORT_INITDONE,HUSH_PAX,HUSH_EXCHANGEWALLET,HUSH_REWIND,HUSH_CONNECTING = -1,HUSH_EXTRASATOSHI,ASSETCHAINS_FOUNDERS,ASSETCHAINS_CBMATURITY,HUSH_NSPV; int32_t HUSH_INSYNC,HUSH_LASTMINED,prevHUSH_LASTMINED,HUSH_CCACTIVATE; -std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB; +std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,ASSETCHAINS_SCRIPTPUB,NOTARY_ADDRESS,ASSETCHAINS_SELFIMPORT,ASSETCHAINS_CCLIB; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEYHASH[20],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE,ASSETCHAINS_TXPOW,ASSETCHAINS_MARMARA; int8_t ASSETCHAINS_ADAPTIVEPOW; uint8_t ASSETCHAINS_CLEARNET = 1; diff --git a/src/hush_utils.h b/src/hush_utils.h index 721a65f12..39ffd3e97 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1763,9 +1763,7 @@ void hush_args(char *argv0) { HUSH_MININGTHREADS = GetArg("-genproclimit",-1); } - DONATION_PUBKEY = GetArg("-donation", ""); NOTARY_PUBKEY = GetArg("-pubkey", ""); - HUSH_DEALERNODE = GetArg("-dealer",0); HUSH_TESTNODE = GetArg("-testnode",0); if ( strlen(NOTARY_PUBKEY.c_str()) == 66 ) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1017bb3df..df7377321 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -66,7 +66,6 @@ bool fPayAtLeastCustomFee = true; #include "hush_defs.h" CBlockIndex *hush_chainactive(int32_t height); -extern std::string DONATION_PUBKEY; extern int32_t HUSH_LOADINGBLOCKS; int32_t hush_dpowconfs(int32_t height,int32_t numconfs); int tx_height( const uint256 &hash ); From 37fe953ea40c8e9b35bd7211464cc36153003de6 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 13:49:27 -0400 Subject: [PATCH 29/63] Add more to debian example config --- contrib/debian/examples/HUSH3.conf | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/contrib/debian/examples/HUSH3.conf b/contrib/debian/examples/HUSH3.conf index 3d19720e4..0d6abda58 100644 --- a/contrib/debian/examples/HUSH3.conf +++ b/contrib/debian/examples/HUSH3.conf @@ -7,12 +7,27 @@ # Run a test node (which means you can mine with no peers) #testnode=1 +#set a custom client name/user agent +#clientName=GoldenSandtrout + # Rescan from block height #rescan=123 # Connect via a SOCKS5 proxy #proxy=127.0.0.1:9050 +# Automatically create Tor hidden service +#listenonion=1 + +#Use separate SOCKS5 proxy to reach peers via Tor hidden services +#onion=1.2.3.4:9050 + +# Only connect to nodes in network (ipv4, ipv6, onion or i2p)")); +#onlynet= + +#Tor control port to use if onion listening enabled +#torcontrol=127.0.0.1:9051 + # Bind to given address and always listen on it. Use [host]:port notation for IPv6 #bind= @@ -147,6 +162,8 @@ #txindex=1 # Enable address index #addressindex=1 +# Enable timestamp index +#timestampindex=1 # Enable spent index #spentindex=1 @@ -186,3 +203,7 @@ # Run a command when tx expires # %s in command is replaced with txid #txexpirynotify=/my/elite/script.sh %s + +# Execute this commend to send a tx +# %s is replaced with tx hex +#txsend=/send/it.sh %s From fb062d2849ebe1b5718f85dbeac1f74fff15efd2 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 17:19:04 -0400 Subject: [PATCH 30/63] Work towards getting RPC tests working again So much has changed since I originally got the RPC tests working many years ago, most notably modern Linux distros don't even have a way to install python2 via packages, you have to install from source. Continuing with python2 does not seem like a good idea, so we begin migrating thigns to Python 3. Currently running ./test.sh will successfully spin up a test chain but then the test suite crashes when attempting to send an RPC request, which looks to be caused by the test suite internals still expecting python2. --- qa/rpc-tests/ac_private.py | 11 +++----- qa/rpc-tests/test_framework/authproxy.py | 1 + qa/rpc-tests/test_framework/test_framework.py | 2 +- qa/rpc-tests/test_framework/util.py | 26 +++++++++---------- test.sh | 3 +++ 5 files changed, 22 insertions(+), 21 deletions(-) create mode 100755 test.sh diff --git a/qa/rpc-tests/ac_private.py b/qa/rpc-tests/ac_private.py index bab8f618c..edef4e207 100755 --- a/qa/rpc-tests/ac_private.py +++ b/qa/rpc-tests/ac_private.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Copyright (c) 2016-2024 The Hush developers # Copyright (c) 2018 SuperNET developers # Distributed under the GPLv3 software license, see the accompanying @@ -39,13 +39,10 @@ class AssetChainPrivateTest (BitcoinTestFramework): self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ # always give -ac_name as first extra_arg and port as third - '-ac_name=REGTEST', - '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-ac_name=ZZZ', + '-conf='+self.options.tmpdir+'/node0/ZZZ.conf', '-port=64367', '-rpcport=64368', - '-regtest', - '-addressindex=1', - '-spentindex=1', '-ac_supply=0', '-ac_reward=25600000000', '-ac_private=1', @@ -78,7 +75,7 @@ class AssetChainPrivateTest (BitcoinTestFramework): rpc.getwalletinfo() taddr = rpc.getnewaddress() - print "Sending to " + taddr + print("Sending to " + taddr) # sending to arbitrary non-notary transparent address is not allowed assert_raises(JSONRPCException, rpc.sendtoaddress, taddr,1) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 366140aab..483944836 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -142,6 +142,7 @@ class AuthServiceProxy(object): 'method': self.__service_name, 'params': args, 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) + print("self.__url.path=" + self.__url.path) response = self._request('POST', self.__url.path, postdata) if response['error'] is not None: raise JSONRPCException(response['error']) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 273d9c6bf..7376fb542 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -169,7 +169,7 @@ class ComparisonTestFramework(BitcoinTestFramework): help="bitcoind binary to use for reference nodes (if any)") def setup_chain(self): - print "Initializing test directory "+self.options.tmpdir + print("Initializing test directory "+self.options.tmpdir) initialize_chain_clean(self.options.tmpdir, self.num_nodes) def setup_network(self): diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 3280be573..7936fcf0a 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -107,7 +107,7 @@ def initialize_datadir(dirname, n): f.write("port="+str(p2p_port(n))+"\n"); rpcport = str(rpc_port(n)) f.write("rpcport="+rpcport+"\n"); - print "RPC port=" + rpcport + print("RPC port=" + rpcport) f.write("listenonion=0\n"); # TODO: maybe make these optional, via arg to initialize_datadir, defaulted to on for now f.write("addressindex=1\n"); @@ -136,14 +136,14 @@ def initialize_chain(test_dir): cmd = os.getenv("BITCOINCLI", "hush-cli") cmd_args = cmd + " -datadir="+datadir + " -rpcwait getblockcount" if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: hushd started, calling: " + cmd_args + print("initialize_chain: hushd started, calling: " + cmd_args) strcmd = cmd + " " + "-datadir="+datadir + " -rpcwait getblockcount" print("Running " + strcmd) subprocess.check_call(strcmd, shell=True); #subprocess.check_call([ cmd, "-rpcwait", "getblockcount"], stdout=devnull) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: hush-cli -rpcwait getblockcount completed" + print("initialize_chain: hush-cli -rpcwait getblockcount completed") devnull.close() rpcs = [] for i in range(4): @@ -175,7 +175,7 @@ def initialize_chain(test_dir): stop_nodes(rpcs) wait_bitcoinds() for i in range(4): - print "Cleaning up cache dir files" + print("Cleaning up cache dir files") os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "db.log")) os.remove(log_filename("cache", i, "peers.dat")) @@ -221,13 +221,12 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= """ Start a hushd and return RPC connection to it """ - print("Starting node " + str(i)) + print("Starting node " + str(i) + "in dir " + dirname) datadir = os.path.join(dirname, "node"+str(i)) # creating special config in case of cryptocondition asset chain test - if len(extra_args) > 0 and extra_args[0] == '-ac_name=REGTEST': - configpath = datadir + "/REGTEST.conf" + if len(extra_args) > 0 and extra_args[0] == '-ac_name=ZZZ': + configpath = datadir + "/ZZZ.conf" with open(configpath, "w+") as config: - config.write("regtest=1\n") config.write("rpcuser=rt\n") config.write("rpcpassword=rt\n") port = extra_args[3] @@ -239,18 +238,18 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= config.write("bind=127.0.0.1\n") config.write("rpcbind=127.0.0.1") if binary is None: - binary = os.getenv("BITCOIND", "hushd") + binary = os.getenv("BITCOIND", "src/hushd") args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] if extra_args is not None: args.extend(extra_args) #print("args=" + ' '.join(args)) bitcoind_processes[i] = subprocess.Popen(args) devnull = open("/dev/null", "w+") - cmd = os.getenv("BITCOINCLI", "hush-cli") + cmd = os.getenv("BITCOINCLI", "src/hush-cli") print("cmd=" + cmd) cmd_args = ' '.join(extra_args) + " -rpcwait getblockcount " if os.getenv("PYTHON_DEBUG", ""): - print "start_node: hushd started, calling : " + cmd + " " + cmd_args + print("start_node: hushd started, calling : " + cmd + " " + cmd_args) strcmd = cmd + " " + cmd_args print("Running " + strcmd) @@ -261,13 +260,14 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= # _rpchost_to_args(rpchost) + # ["-rpcwait", "-rpcport=6438", "getblockcount"], stdout=devnull) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: calling hush-cli -rpcwait getblockcount returned" + print("start_node: calling hush-cli -rpcwait getblockcount returned") devnull.close() #port = extra_args[3] port = rpc_port(i) + print("port=%s" % port) username = rpc_username() password = rpc_password() - url = "http://%s:%s@%s:%d" % (username, password, rpchost or '127.0.0.1', int(port[9:])) + url = "http://%s:%s@%s:%s" % (username, password, rpchost or '127.0.0.1', port) print("connecting to " + url) if timewait is not None: proxy = AuthServiceProxy(url, timeout=timewait) diff --git a/test.sh b/test.sh new file mode 100755 index 000000000..93bbb470c --- /dev/null +++ b/test.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +PYTHONPATH=./qa/rpc-tests/test_framework/ ./qa/rpc-tests/ac_private.py From c8e1b598bc5eccca38506e22b5048420691b08ae Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 17:23:46 -0400 Subject: [PATCH 31/63] Update authproxy.py to python3 version from upstream --- qa/rpc-tests/test_framework/authproxy.py | 76 +++++++++++------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index 483944836..e55570636 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -1,8 +1,3 @@ -#!/usr/bin/env python2 -# Copyright (c) 2016-2024 The Hush developers -# Distributed under the GPLv3 software license, see the accompanying -# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - """ Copyright 2011 Jeff Garzik @@ -38,45 +33,37 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -try: - import http.client as httplib -except ImportError: - import httplib import base64 import decimal import json import logging -try: - import urllib.parse as urlparse -except ImportError: - import urlparse +from http.client import HTTPConnection, HTTPSConnection, BadStatusLine +from urllib.parse import urlparse + +USER_AGENT = "AuthServiceProxy/0.1" -USER_AGENT = "FUCKjl777LULZ" HTTP_TIMEOUT = 600 + log = logging.getLogger("BitcoinRPC") class JSONRPCException(Exception): def __init__(self, rpc_error): - Exception.__init__(self) + Exception.__init__(self, rpc_error.get("message")) self.error = rpc_error - def EncodeDecimal(o): if isinstance(o, decimal.Decimal): - return round(o, 8) + return str(o) raise TypeError(repr(o) + " is not JSON serializable") -class AuthServiceProxy(object): + +class AuthServiceProxy(): __id_count = 0 def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): self.__service_url = service_url - self.__service_name = service_name - self.__url = urlparse.urlparse(service_url) - if self.__url.port is None: - port = 80 - else: - port = self.__url.port + self._service_name = service_name + self.__url = urlparse(service_url) (user, passwd) = (self.__url.username, self.__url.password) try: user = user.encode('utf8') @@ -89,23 +76,25 @@ class AuthServiceProxy(object): authpair = user + b':' + passwd self.__auth_header = b'Basic ' + base64.b64encode(authpair) - if connection: - # Callables re-use the connection of the original proxy - self.__conn = connection - elif self.__url.scheme == 'https': - self.__conn = httplib.HTTPSConnection(self.__url.hostname, port, - None, None, False, - timeout) - else: - self.__conn = httplib.HTTPConnection(self.__url.hostname, port, - False, timeout) + self.timeout = timeout + self._set_conn(connection) + def _set_conn(self, connection=None): + port = 80 if self.__url.port is None else self.__url.port + if connection: + self.__conn = connection + self.timeout = connection.timeout + elif self.__url.scheme == 'https': + self.__conn = HTTPSConnection(self.__url.hostname, port, timeout=self.timeout) + else: + self.__conn = HTTPConnection(self.__url.hostname, port, timeout=self.timeout) + def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): # Python internal stuff raise AttributeError - if self.__service_name is not None: - name = "%s.%s" % (self.__service_name, name) + if self._service_name is not None: + name = "%s.%s" % (self._service_name, name) return AuthServiceProxy(self.__service_url, name, connection=self.__conn) def _request(self, method, path, postdata): @@ -124,8 +113,9 @@ class AuthServiceProxy(object): # If connection was closed, try again. # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. # ConnectionResetError happens on FreeBSD with Python 3.4. - # These classes don't exist in Python 2.x, so we can't refer to them directly. - if ((isinstance(e, httplib.BadStatusLine) and e.line == "''") + # This can be simplified now that we depend on Python 3 (previously, we could not + # refer to BrokenPipeError or ConnectionResetError which did not exist on Python 2) + if ((isinstance(e, BadStatusLine) and e.line == "''") or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): self.__conn.close() self.__conn.request(method, path, postdata, headers) @@ -136,13 +126,12 @@ class AuthServiceProxy(object): def __call__(self, *args): AuthServiceProxy.__id_count += 1 - log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self.__service_name, + log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name, json.dumps(args, default=EncodeDecimal))) postdata = json.dumps({'version': '1.1', - 'method': self.__service_name, + 'method': self._service_name, 'params': args, 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) - print("self.__url.path=" + self.__url.path) response = self._request('POST', self.__url.path, postdata) if response['error'] is not None: raise JSONRPCException(response['error']) @@ -162,6 +151,11 @@ class AuthServiceProxy(object): if http_response is None: raise JSONRPCException({ 'code': -342, 'message': 'missing HTTP response from server'}) + + content_type = http_response.getheader('Content-Type') + if content_type != 'application/json': + raise JSONRPCException({ + 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) responsedata = http_response.read().decode('utf8') response = json.loads(responsedata, parse_float=decimal.Decimal) From 465fe58e6a3357ed1b4eda02b400ee4423f6bd5d Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 22:17:18 -0400 Subject: [PATCH 32/63] ./test.sh now runs successfully and we can now write RPC tests --- qa/rpc-tests/ac_private.py | 46 +++++++++---------- qa/rpc-tests/test_framework/test_framework.py | 4 +- qa/rpc-tests/test_framework/util.py | 44 +++++++++++------- test.sh | 1 + 4 files changed, 51 insertions(+), 44 deletions(-) diff --git a/qa/rpc-tests/ac_private.py b/qa/rpc-tests/ac_private.py index edef4e207..5db08a0f1 100755 --- a/qa/rpc-tests/ac_private.py +++ b/qa/rpc-tests/ac_private.py @@ -8,7 +8,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, assert_greater_than, \ initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ - stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises, assert_true import time from decimal import Decimal @@ -21,16 +21,11 @@ def assert_success(result): def assert_error(result): assert_equal(result['result'], 'error') -def generate_random_string(length): - random_string = ''.join(choice(ascii_uppercase) for i in range(length)) - return random_string - - -class AssetChainPrivateTest (BitcoinTestFramework): - +class PrivateTest (BitcoinTestFramework): def setup_chain(self): print("Initializing ac_private test directory "+self.options.tmpdir) self.num_nodes = 1 + self.options.nocleanup = 1 # do not delete datadir after test run initialize_chain_clean(self.options.tmpdir, self.num_nodes) def setup_network(self, split = False): @@ -40,17 +35,18 @@ class AssetChainPrivateTest (BitcoinTestFramework): extra_args=[[ # always give -ac_name as first extra_arg and port as third '-ac_name=ZZZ', - '-conf='+self.options.tmpdir+'/node0/ZZZ.conf', + '-conf='+self.options.tmpdir+'/node0/regtest/ZZZ.conf', '-port=64367', '-rpcport=64368', - '-ac_supply=0', + '-ac_supply=10', '-ac_reward=25600000000', '-ac_private=1', '-allowlist=127.0.0.1', - '-debug', + #'-debug', + '-regtest', '--daemon', - '-rpcuser=rt', - '-rpcpassword=rt' + '-rpcuser=hush', + '-rpcpassword=puppy' ]] ) self.is_network_split = split @@ -68,23 +64,23 @@ class AssetChainPrivateTest (BitcoinTestFramework): def run_test (self): print("Mining blocks...") rpc = self.nodes[0] - # utxos from block 1 become mature in block 101 - rpc.generate(101) + rpc.generate(1) self.sync_all() rpc.getinfo() rpc.getwalletinfo() taddr = rpc.getnewaddress() - print("Sending to " + taddr) - # sending to arbitrary non-notary transparent address is not allowed - assert_raises(JSONRPCException, rpc.sendtoaddress, taddr,1) - # this is a current notary address - # TODO: keep in sync when notaries change - #dev1_jl777 = "RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc" - # taddr vout is only allowed if it is a notary address - #txid = rpc.sendtoaddress(dev1_jl777, 7) - #assert txid, 'got txid' + # sending to arbitrary non-notary transparent address is not allowed + print("Sending to " + taddr) + try: + rpc.sendtoaddress(taddr, 1) + except: + assert_true(1) + + # this should work but don't + #assert_raises(JSONRPCException, rpc.sendtoaddress, taddr,1) + if __name__ == '__main__': - AssetChainPrivateTest ().main() + PrivateTest ().main() diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 7376fb542..d04bd8b95 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -134,10 +134,10 @@ class BitcoinTestFramework(object): stop_nodes(self.nodes) wait_bitcoinds() else: - print("Note: hushds were not stopped and may still be running") + print("Note: nodes were not stopped and may still be running") if not self.options.nocleanup and not self.options.noshutdown: - print("Cleaning up") + print("Deleting %s" % self.options.tmpdir) shutil.rmtree(self.options.tmpdir) if success: diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 7936fcf0a..018f6722d 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -57,7 +57,9 @@ def sync_blocks(rpc_connections, wait=1): break time.sleep(wait) - # Now that the block counts are in sync, wait for the internal + return + + # Now that the block counts are in sync, wait for the internal # notifications to finish while True: notified = [ x.getblockchaininfo()['fullyNotified'] for x in rpc_connections ] @@ -80,6 +82,7 @@ def sync_mempools(rpc_connections, wait=1): break time.sleep(wait) + return # Now that the mempools are in sync, wait for the internal # notifications to finish while True: @@ -91,13 +94,14 @@ def sync_mempools(rpc_connections, wait=1): bitcoind_processes = {} def initialize_datadir(dirname, n): - datadir = os.path.join(dirname, "node"+str(n)) - datadir = os.path.join(datadir,"HUSH3") + datadir = os.path.join(dirname, "node"+str(n), "regtest") + #datadir = os.path.join(datadir,"ZZZ") if not os.path.isdir(datadir): + print("Creating dirs %s" % datadir) os.makedirs(datadir) - print("Writing to " + os.path.join(datadir,"HUSH3.conf")) - with open(os.path.join(datadir, "HUSH3.conf"), 'w') as f: + print("Writing to " + os.path.join(datadir,"ZZZ.conf")) + with open(os.path.join(datadir, "ZZZ.conf"), 'w') as f: f.write("regtest=1\n"); f.write("txindex=1\n"); f.write("server=1\n"); @@ -113,7 +117,9 @@ def initialize_datadir(dirname, n): f.write("addressindex=1\n"); f.write("spentindex=1\n"); f.write("timestampindex=1\n"); - f.write("zindex=1\n"); + #f.write("zindex=1\n"); + print("Done writing to %s" % os.path.join(datadir,"ZZZ.conf") ) + return datadir def initialize_chain(test_dir): @@ -221,14 +227,14 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= """ Start a hushd and return RPC connection to it """ - print("Starting node " + str(i) + "in dir " + dirname) - datadir = os.path.join(dirname, "node"+str(i)) - # creating special config in case of cryptocondition asset chain test + print("Starting node " + str(i) + " in dir " + dirname) + datadir = os.path.join(dirname, "node"+str(i), "regtest") + # creating special config if len(extra_args) > 0 and extra_args[0] == '-ac_name=ZZZ': configpath = datadir + "/ZZZ.conf" with open(configpath, "w+") as config: - config.write("rpcuser=rt\n") - config.write("rpcpassword=rt\n") + config.write("rpcuser=hush\n") + config.write("rpcpassword=puppy\n") port = extra_args[3] config.write("rpcport=" + (port[9:]) + "\n") config.write("server=1\n") @@ -236,18 +242,22 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= config.write("rpcworkqueue=256\n") config.write("rpcallowip=127.0.0.1\n") config.write("bind=127.0.0.1\n") - config.write("rpcbind=127.0.0.1") + config.write("rpcbind=127.0.0.1\n") + + print("Done writing to %s" % configpath) + if binary is None: binary = os.getenv("BITCOIND", "src/hushd") args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] if extra_args is not None: args.extend(extra_args) - #print("args=" + ' '.join(args)) + print("args=" + ' '.join(args)) bitcoind_processes[i] = subprocess.Popen(args) devnull = open("/dev/null", "w+") cmd = os.getenv("BITCOINCLI", "src/hush-cli") print("cmd=" + cmd) - cmd_args = ' '.join(extra_args) + " -rpcwait getblockcount " + args = [ extra_args[0], "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] + cmd_args = ' '.join(args) + " -rpcwait getblockcount " if os.getenv("PYTHON_DEBUG", ""): print("start_node: hushd started, calling : " + cmd + " " + cmd_args) strcmd = cmd + " " + cmd_args @@ -262,12 +272,12 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= if os.getenv("PYTHON_DEBUG", ""): print("start_node: calling hush-cli -rpcwait getblockcount returned") devnull.close() - #port = extra_args[3] - port = rpc_port(i) + port = extra_args[3] + #port = rpc_port(i) print("port=%s" % port) username = rpc_username() password = rpc_password() - url = "http://%s:%s@%s:%s" % (username, password, rpchost or '127.0.0.1', port) + url = "http://%s:%s@%s:%s" % (username, password, rpchost or '127.0.0.1', port[9:]) print("connecting to " + url) if timewait is not None: proxy = AuthServiceProxy(url, timeout=timewait) diff --git a/test.sh b/test.sh index 93bbb470c..b9d12c6ae 100755 --- a/test.sh +++ b/test.sh @@ -1,3 +1,4 @@ #!/usr/bin/env bash +#export PYTHON_DEBUG=1 PYTHONPATH=./qa/rpc-tests/test_framework/ ./qa/rpc-tests/ac_private.py From 0f1894663013a5851b00673d2b295d1dd990eac5 Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 23:30:06 -0400 Subject: [PATCH 33/63] Add lockzins test --- qa/rpc-tests/lockzins.py | 78 +++++++++++++++++++++++++++++ qa/rpc-tests/test_framework/util.py | 7 +-- test.sh | 5 +- 3 files changed, 86 insertions(+), 4 deletions(-) create mode 100755 qa/rpc-tests/lockzins.py diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py new file mode 100755 index 000000000..6fe6cf4bd --- /dev/null +++ b/qa/rpc-tests/lockzins.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2025 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises, assert_true + +import time +from decimal import Decimal +from random import choice +from string import ascii_uppercase + +def assert_success(result): + assert_equal(result['result'], 'success') + +def assert_error(result): + assert_equal(result['result'], 'error') + +class LockZinsTest (BitcoinTestFramework): + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + self.num_nodes = 1 + self.options.nocleanup = 1 # do not delete datadir after test run + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=ZZZ', + #'-ac_algo=randomx', + #'-testnode=1', # why does this make the test node hang before run_test() ? + '-conf='+self.options.tmpdir+'/node0/regtest/ZZZ.conf', + '-port=64367', + '-rpcport=64368', + '-ac_supply=10', + '-ac_reward=25600000000', + '-ac_private=1', + '-allowlist=127.0.0.1', + '-debug', + '-regtest', + '--daemon', + #'-rpcuser=hush', + #'-rpcpassword=puppy' + ]] + ) + self.is_network_split = False + self.rpc = self.nodes[0] + self.sync_all() + print("Done setting up network") + + def run_test (self): + print("Mining blocks...") + rpc = self.nodes[0] + # mine the initial ac_supply + rpc.generate(5) + self.sync_all() + + zaddr = rpc.z_getnewaddress() + print("Created zaddr %s" % zaddr) + + rpc.getinfo() + time.sleep(1) + rpc.getinfo() + + rpc.z_shieldcoinbase('*', zaddr) + rpc.generate(1) + + self.sync_all() + print(rpc.z_getbalances()) + +if __name__ == '__main__': + LockZinsTest ().main() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 018f6722d..9e71a28f0 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -82,7 +82,6 @@ def sync_mempools(rpc_connections, wait=1): break time.sleep(wait) - return # Now that the mempools are in sync, wait for the internal # notifications to finish while True: @@ -238,13 +237,15 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= port = extra_args[3] config.write("rpcport=" + (port[9:]) + "\n") config.write("server=1\n") + #config.write("testnode=1\n") config.write("txindex=1\n") config.write("rpcworkqueue=256\n") config.write("rpcallowip=127.0.0.1\n") config.write("bind=127.0.0.1\n") + #config.write("listenonion=0\n") + #config.write("torcontrol=127.0.0.1:9999\n") config.write("rpcbind=127.0.0.1\n") - - print("Done writing to %s" % configpath) + print("Done writing to %s" % configpath) if binary is None: binary = os.getenv("BITCOIND", "src/hushd") diff --git a/test.sh b/test.sh index b9d12c6ae..5d81d4850 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash #export PYTHON_DEBUG=1 -PYTHONPATH=./qa/rpc-tests/test_framework/ ./qa/rpc-tests/ac_private.py +export PYTHONPATH=./qa/rpc-tests/test_framework/ + +#./qa/rpc-tests/ac_private.py +./qa/rpc-tests/lockzins.py --tracerpc From 45f2e6b134635d8f5703a8abe83fb1dbd2f75acf Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 23:39:26 -0400 Subject: [PATCH 34/63] Remove unused code --- src/wallet/rpcwallet.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e86bcdd59..908333809 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -82,8 +82,6 @@ char *uint256_str(char *dest,uint256 txid); // Private method: UniValue z_getoperationstatus_IMPL(const UniValue&, bool); -#define PLAN_NAME_MAX 8 -#define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) #define THROW_IF_SYNCING(INSYNC) if (HUSH_TESTNODE == 0 && INSYNC == 0) { throw runtime_error(strprintf("%s: Extreme Privacy! Chain still syncing at height %d, aborting to prevent linkability analysis. Please wait until FULLY SYNCED and try again.",__FUNCTION__,chainActive.Tip()->GetHeight())); } int tx_height( const uint256 &hash ); From 5d31a77036e0a78f448cdc5281b943f0496f7fdf Mon Sep 17 00:00:00 2001 From: Duke Date: Tue, 12 Aug 2025 23:57:21 -0400 Subject: [PATCH 35/63] Do not throw exception during syncing on regtest --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 908333809..c12394cfa 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -82,7 +82,7 @@ char *uint256_str(char *dest,uint256 txid); // Private method: UniValue z_getoperationstatus_IMPL(const UniValue&, bool); -#define THROW_IF_SYNCING(INSYNC) if (HUSH_TESTNODE == 0 && INSYNC == 0) { throw runtime_error(strprintf("%s: Extreme Privacy! Chain still syncing at height %d, aborting to prevent linkability analysis. Please wait until FULLY SYNCED and try again.",__FUNCTION__,chainActive.Tip()->GetHeight())); } +#define THROW_IF_SYNCING(INSYNC) if (Params().NetworkIDString() != "regtest" && HUSH_TESTNODE == 0 && INSYNC == 0) { throw runtime_error(strprintf("%s: Extreme Privacy! Chain still syncing at height %d, aborting to prevent linkability analysis. Please wait until FULLY SYNCED and try again.",__FUNCTION__,chainActive.Tip()->GetHeight())); } int tx_height( const uint256 &hash ); From bd9dc4d19017fc4e726aba0d7ddab2947d41d037 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 13 Aug 2025 01:13:10 -0400 Subject: [PATCH 36/63] A test for lockzins branch which currently fails on dev branch --- qa/rpc-tests/lockzins.py | 62 ++++++++++++++++++++--------- qa/rpc-tests/test_framework/util.py | 3 +- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index 6fe6cf4bd..232667ab5 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -7,7 +7,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, assert_greater_than, \ initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ - stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises, assert_true + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises, assert_true, \ + wait_and_assert_operationid_status import time from decimal import Decimal @@ -38,11 +39,11 @@ class LockZinsTest (BitcoinTestFramework): '-conf='+self.options.tmpdir+'/node0/regtest/ZZZ.conf', '-port=64367', '-rpcport=64368', - '-ac_supply=10', - '-ac_reward=25600000000', + '-ac_supply=1', + '-ac_reward=100000000', '-ac_private=1', '-allowlist=127.0.0.1', - '-debug', + #'-debug', '-regtest', '--daemon', #'-rpcuser=hush', @@ -57,22 +58,47 @@ class LockZinsTest (BitcoinTestFramework): def run_test (self): print("Mining blocks...") rpc = self.nodes[0] - # mine the initial ac_supply - rpc.generate(5) - self.sync_all() - - zaddr = rpc.z_getnewaddress() - print("Created zaddr %s" % zaddr) - - rpc.getinfo() - time.sleep(1) - rpc.getinfo() - - rpc.z_shieldcoinbase('*', zaddr) + # mine initial ac_supply rpc.generate(1) - self.sync_all() - print(rpc.z_getbalances()) + + zaddr1 = rpc.z_getnewaddress() + zaddr2 = rpc.z_getnewaddress() + + x = 0 + while x < 15: + rpc.generate(1) + self.sync_all() + time.sleep(1) + rpc.z_shieldcoinbase('*', zaddr1, 0, 1) + x = x+1 + + rpc.generate(11) + self.sync_all() + rpc.z_listunspent() + rpc.z_getbalances() + + recipients = [] + recipients.append({"address": zaddr2, "amount": Decimal('3')}) + + # queue 4 ztxs, which will try to spend the same funds multiple times + # without correct locking of zins + opid1 = rpc.z_sendmany(zaddr1,recipients,1,0) + opid2 = rpc.z_sendmany(zaddr1,recipients,1,0) + opid3 = rpc.z_sendmany(zaddr1,recipients,1,0) + opid4 = rpc.z_sendmany(zaddr1,recipients,1,0) + + rpc.generate(1) + self.sync_all() + wait_and_assert_operationid_status(self.nodes[0], opid1) + wait_and_assert_operationid_status(self.nodes[0], opid2) + wait_and_assert_operationid_status(self.nodes[0], opid3) + wait_and_assert_operationid_status(self.nodes[0], opid4) + + # give time for all z_sendmany's to run + #time.sleep(10) + + rpc.z_getoperationstatus() if __name__ == '__main__': LockZinsTest ().main() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 9e71a28f0..ff1115b88 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -103,6 +103,7 @@ def initialize_datadir(dirname, n): with open(os.path.join(datadir, "ZZZ.conf"), 'w') as f: f.write("regtest=1\n"); f.write("txindex=1\n"); + #f.write("testnode=1\n"); f.write("server=1\n"); f.write("showmetrics=0\n"); f.write("rpcuser=hush\n"); @@ -481,7 +482,7 @@ def assert_raises(exc, fun, *args, **kwds): def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None, timeout=300): print('waiting for async operation {}'.format(myopid)) result = None - for _ in xrange(1, timeout): + for _ in range(1, timeout): results = node.z_getoperationresult([myopid]) if len(results) > 0: result = results[0] From 8f01fbf4ab6b8ae9a3186122e03befd74862fd38 Mon Sep 17 00:00:00 2001 From: fekt Date: Mon, 18 Aug 2025 08:19:03 -0400 Subject: [PATCH 37/63] DragonX checkpoints In 3.10.4 release, Hush checkpoints were added as DragonX checkpoints, causing nodes to not sync and ban seeds and other nodes that updated. These are DragonX checkpoints from a synced node but need to be verified with others that have synced nodes. --- src/chainparams.cpp | 1459 ++++++++++++++++++++++++------------------- 1 file changed, 818 insertions(+), 641 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 106ce8c1d..828f0c47f 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -4153,647 +4153,824 @@ void *chainparams_commandline() { (1602000, uint256S("0x0000a8ca712ed653cf5cdf141382b02b552e21f4dc687a89ca946d7a236fca29")) (1603000, uint256S("0x000009762ffa6eefefcd29703f41cf9bbe5e44b4a757968f107ad9e20679c373")) // Generated at 1750959556 via hush3 util/checkpoints.pl by Duke Leto - (1604000, uint256S("0x000000047ec28daa1ebd35d272006bb99be1bfc432e64fa9ba7558669a0beebc")) - (1605000, uint256S("0x00000002829e77226633eecc400ad22f7c0051e9acea26285ffb12cad1fd3461")) - (1606000, uint256S("0x00000005c2cb7675138e10f36971d9620254bc4781d07f0785c0567068e39ef5")) - (1607000, uint256S("0x00000005703e6b60f7004a502a54615df241f38e1b4f30856a21db2ab8e2a162")) - (1608000, uint256S("0x00000000397c7d1a709c8156ef2d3da4f63b06cef6e16656510e9fb07e398d94")) - (1609000, uint256S("0x000000031accfc8544bde0cf3d160e9c46186d1330bfbc2f075bda9e63e71058")) - (1610000, uint256S("0x00000000318ea4aea52e334b9b3f8bf91e63fe485468936bba68485ae1095a46")) - (1611000, uint256S("0x0000000197b39d70fb42cd31ddc99cc3993f8fcf143f4f13138908bad9be1dfb")) - (1612000, uint256S("0x000000032441e4bbf21affe0c75a11c2aa6e8527be12effc017cb0601dd0d88a")) - (1613000, uint256S("0x00000002ff16ad0bafee22be75b953357ac958b64aa74761017cf27ef349093f")) - (1614000, uint256S("0x00000003a313b96708612dd8223e7d1bf0384b6edc56320a9932f64d1d638db6")) - (1615000, uint256S("0x00000000d192d0150f90daa6b4e2e6f7236cd641314fdced99fce65fe30d48be")) - (1616000, uint256S("0x000000036a26bb9a2481f666975bd98a478b52eb98cc0719fea84bac424a7ba8")) - (1617000, uint256S("0x000000015b35b9e2df778aac51af83403d9f361c582ff8a91a3dc4fdfadf7018")) - (1618000, uint256S("0x0000000638029048e3dff9fba19fcf06b88543ecfe45980cfdb1282670095d85")) - (1619000, uint256S("0x000000025fcd19b079405d3037588012a9cdc138ee633dd5ab5cdef92a8de23d")) - (1620000, uint256S("0x000000048c6667a8724512cbd999bc491ec8522b1f3817001c7ba485dec46d10")) - (1621000, uint256S("0x00000005d981cd3473f8815d18965c0e0035993117390e9659fe8d3b9562c8dc")) - (1622000, uint256S("0x0000000371a1663973c7b19a0b4dd8673f1ddb14a0438c89de3908712437f688")) - (1623000, uint256S("0x000000038ed359f4cdcfb54a0ba36a8ac89e4f697836920c28dd038d643064d1")) - (1624000, uint256S("0x00000000ca915eb30164ac2aad328ae5d9d4531bf8ef30c7bdf3c18c0abcdae4")) - (1625000, uint256S("0x0000000303957deb36dc6a3b6597984ca9585172a198342eb102a9d3b9455596")) - (1626000, uint256S("0x00000001485e2bf5e67162c35b4dddb9ea709e639bfdf79c8b9d1e0fd9abcf00")) - (1627000, uint256S("0x000000000cb8f8b60fa1e57622a7a5bb2daa07899d1eb39f817f8c424a52a3e5")) - (1628000, uint256S("0x00000000eab91143aa66330d27d57f77bb7feb904d17e9a3ec20c7836c701f35")) - (1629000, uint256S("0x00000002ed48f715858c998e5133c0d6748b820ce3380e2759db5558209a167a")) - (1630000, uint256S("0x000000032c724b40a4fb6d3e613aed9f294f22b76fc30b6caaa3bfe7ce3b01ad")) - (1631000, uint256S("0x000000008b0eb942b318fe821ccbf977d24a34cb9138555cc02130ecc655af81")) - (1632000, uint256S("0x0000000061c1e1eef48730e29b494681c2a3aab036219bbea140e0e4f51e0d6e")) - (1633000, uint256S("0x00000003b3d9950c5ddb598a474edc15fcc323dd59b44c32534354a043014707")) - (1634000, uint256S("0x00000001e6b8b9a471537f3b006c75428405c0f877e638e417ee9be9d2ff43b1")) - (1635000, uint256S("0x000000030073be68be4e7d68bcdb151ecf5af613bdfb9e93e7d1f7b0752f7aa5")) - (1636000, uint256S("0x00000000fd1b3853a2d59705d5b36e76491c58e0fbb81d2b35d7a7e3add3b4e1")) - (1637000, uint256S("0x000000023620ab021fb58eee94b3fbcff4b7d502807d028bdb2f32708150aae4")) - (1638000, uint256S("0x000000043c2e172e6ca4248a65ba64bdbe445f5f81844752f988a107845f349a")) - (1639000, uint256S("0x00000002fcbf7f7b4e04fa895012776248ce5020ec4bded612537a58c9dd87ea")) - (1640000, uint256S("0x00000000d6605a8a213fa134a2bf74cc901a42d0706718090788d6915c7ebbfd")) - (1641000, uint256S("0x00000001716416197b1802314a0d0f1679ab789e258ed3c930ac3456dba9bed4")) - (1642000, uint256S("0x000000044a7353133354febf9a2549d6033cabff8b3e9cb8c4335ca809d9d048")) - (1643000, uint256S("0x00000004b7eaa979bcbd468e4f9f0e4c1c9a7dde3eedd1ea53a5ce2bef562b09")) - (1644000, uint256S("0x000000027430ab7a59514ba994b3f114e5c28ea36f714515ed3cf70caeb8d227")) - (1645000, uint256S("0x00000000d4de211a3a25d4243278e0fc498058a9bae5860ae35963bcf155ba4f")) - (1646000, uint256S("0x00000004d8e662533da408b1427c4840c477bb176f5d6cc16e989a57646ecba5")) - (1647000, uint256S("0x0000000213f087be9c672b98a13d76dfb77bf276dee00e14a708c3b864427331")) - (1648000, uint256S("0x0000000129f391dd5e18ce5efbfff76edbdbd87914b7b07a68a6bbee01b4efa1")) - (1649000, uint256S("0x00000003c84f48d9074fe0dd3132843feebc204b7832fcf58265ed2b0fc91e9f")) - (1650000, uint256S("0x00000000922fca1c2ab235f6592387433c0622665408caf1a689d588acd7ef4a")) - (1651000, uint256S("0x0000000235c9ddae6fcee3486886406cdfacf06729a6a7e2abbd1a12d5b65367")) - (1652000, uint256S("0x00000001122a37089bc208bf027091c41aeed037a011aebfd1beb1388aa6e3ea")) - (1653000, uint256S("0x000000013177553290193311f8cffaa71c3648cd54039bd700685f626b7f61c3")) - (1654000, uint256S("0x00000003fadb924a1ff4dc97591004198afc9711dbbd404099f671ad93a372f5")) - (1655000, uint256S("0x0000000155ca47f18a7bc8dd51e68140cdb9a8e9d3b774276ba1dbebb1755857")) - (1656000, uint256S("0x00000003899e96ab824d812f38ac7de0c68edd5092fdbed2bc2c25ff98d64a23")) - (1657000, uint256S("0x0000000382b6257c88191f59c00b494a70a9748fa6e15edfa3a7861961836125")) - (1658000, uint256S("0x000000015f51ec2a910d81081f3458e384fa6fd3687b6b6081da5d908c21fed4")) - (1659000, uint256S("0x000000002613a74bdcb2a4321f2bf8b17dfd247cfe139ea569c0912ded3c7d2d")) - (1660000, uint256S("0x000000049e13deb195724e2a64bf4d7a476b44d67d9779a321cdc32f2363c691")) - (1661000, uint256S("0x0000000188e1647808e786af316efa45a9faba7241a24ea44a7b3b1487db382d")) - (1662000, uint256S("0x00000001edfb091e9ea392c20a197002d7de65656f41b97fdd2b175dc92860ca")) - (1663000, uint256S("0x000000029800198e2b567a2b256bc5089e6d3a57379e22ff966126151acad77b")) - (1664000, uint256S("0x0000000215402fce1b5853158fc0210b3cd3d8ad125af4692562ed8f9c399075")) - (1665000, uint256S("0x00000003164d40c0bb82317df59c0e325601b268d2c579d8f81e593c1e85adda")) - (1666000, uint256S("0x00000004a4bb0d82d09a6cfdea1493de1e960adf9bf58ecf12fcc65d8c076db6")) - (1667000, uint256S("0x00000000677a80fc06a62957146bdcfc83c637504683265fb09ca655b14a1ad8")) - (1668000, uint256S("0x00000002d16c791f19fbfb53f6b8b061af5276a756b632a59627889291caade0")) - (1669000, uint256S("0x0000000063226419faac0536ce13765bcf210fb02f4b32aa34dc68e36edc62ff")) - (1670000, uint256S("0x00000001d70644f12e0ed97832baea5d8d52b4109c3eb6d13628ca61c6983af6")) - (1671000, uint256S("0x00000001cf40d5ab42932e082e3c8f0bb769d46e759776113a40e864d9aa4aad")) - (1672000, uint256S("0x00000002070b8a20b0c1491cb30554beaa4070ca92c043a436de279794e9f24c")) - (1673000, uint256S("0x00000002619389bf5e4e12e728a4879f0ae9e09e59721313efaf00c293dbb3fd")) - (1674000, uint256S("0x000000032517420588e7b8fa7892ebe9c04fa247dc04a77cf7ff8cd96dcdfaf1")) - (1675000, uint256S("0x00000002e056c3b3501346a044723757bdf22448957ed61f580482cead17db2b")) - (1676000, uint256S("0x000000021956ce039b89a4dc4f57bbd948852fb8e60cbee97e47914476a00af7")) - (1677000, uint256S("0x00000000dcd83c42b2bd5a062c0e46237232166a3fd11fe0909908675d4b2960")) - (1678000, uint256S("0x00000002be3d780622e1c8d12dfb9ce8e00d1a6a0774edac2ec7cacd0d47968c")) - (1679000, uint256S("0x000000021acce8c8f368551df6373c7a87d884847a4837abfdeca3a412b50cdb")) - (1680000, uint256S("0x00000005910f9f52c1b2c386a051811f11d3eaa4c737dcce58ab3cc37fcd62fb")) - (1681000, uint256S("0x000000049ffd7d05bb3c1b49874baceea1bc7b6b900e31100c2ca3bcc28a25a2")) - (1682000, uint256S("0x00000001b230ac60a34ebd20a60b32c881c6d720e61eb8ff353426579d9a38b4")) - (1683000, uint256S("0x0000000427e6838977f26189ff5e1d56ebc6ecd7a9eb06d0ad1cae3ef773519e")) - (1684000, uint256S("0x000000022f04d5082852031d455546c7ca4a25e964008f8ea69d29946f28e1e6")) - (1685000, uint256S("0x0000000475bec2831d736ed0a14462c023bbd80ae03d0ec2e5c4633339332456")) - (1686000, uint256S("0x000000047a42b4eabe3ffab8d95e3cb1a2d923afcbda4e335374e728777fc474")) - (1687000, uint256S("0x00000003eda47c88b7d313cc525f0511934dacc364d045057eefc2148934cfbb")) - (1688000, uint256S("0x000000040d7bda41689357c29aedb77b016f3cd2ce2bc3ba04c4bdd95d455286")) - (1689000, uint256S("0x0000000128027ca8f7b2dccb44d26946b9df6533f05e63da9d475867c4b251fa")) - (1690000, uint256S("0x00000002dbbef67d168a562e36ba850e15acfad1172d1134df4f1f4288c9d865")) - (1691000, uint256S("0x000000048ad7645fb07ec103dadabfb66c2b544c69bd920692a834a8844be93d")) - (1692000, uint256S("0x000000010ddd71bc79e292a7c6e3c70565ba211f918eb1751e905301acbcd517")) - (1693000, uint256S("0x000000010dc70ae11c82e34000cd7d1a344bbf9fcf6344b3ac04f3173d1703d0")) - (1694000, uint256S("0x000000027e5cb8c5bfd613100811708f7d180b994650d3ca6900a81683d50fa0")) - (1695000, uint256S("0x000000014325867b388dc34843b695536eb9185c6782707f1c86edf0b5b89e9d")) - (1696000, uint256S("0x000000046385ad70b5c3de53eb6634836758eea4f7ee7b81a889f7201e27337d")) - (1697000, uint256S("0x00000004bbef43e1ad19298dea05462d23e7de9482dfda72c8643cc5a73e3356")) - (1698000, uint256S("0x00000000c7fa58a2b8420904097a9e02bc0b7aa9bc9e427ae1eed1908a150b0c")) - (1699000, uint256S("0x000000020ddfe5a4caddee1261f1b30faebfa220184e7e8fafee520d1bdc2452")) - (1700000, uint256S("0x00000001c8a7698cd8594605fed3594a8a576535d94f3440ba69b2ec01706e2f")) - (1701000, uint256S("0x00000002e9daa2a596858bd331b6320b4aaa34124ace3dbabbd50502b58eaf6b")) - (1702000, uint256S("0x000000015cfe670509475a9e7f693b5169e02d54bf459342f511b39ae05d8ce5")) - (1703000, uint256S("0x0000000045def8972d1adc0828618f4186f89b2d550a03f099ea4a72a78161ec")) - (1704000, uint256S("0x00000001a4a313c141aa9f20bb8011d00315bcfab4784a711d1529851ca6f218")) - (1705000, uint256S("0x00000000fc4bbd9320b7b0f3329c52e604655d872caa8ef9a64eb34e44b42795")) - (1706000, uint256S("0x0000000614e676936e086495ec9b3b1688a7d6030d032c3da7c241a417e6dbe7")) - (1707000, uint256S("0x000000005ebf5e6aa923dd2a4367d7747126343356710659b4b105b5557b26be")) - (1708000, uint256S("0x00000002dbfbbfa81aba34a934a69c7d6db57ace02eb20b7f1be183d8bc67b49")) - (1709000, uint256S("0x0000000481ece1648cf7bc906f3f912d7900170d6adda615c6e9402e7aae7a71")) - (1710000, uint256S("0x00000003b17400949f2f3c82142eca4c6590e863f657b64a3dbe7f79fccf38d0")) - (1711000, uint256S("0x00000004f87d08b7c4d366db9cdcef3f427842525b6e61c42338474821a22e03")) - (1712000, uint256S("0x000000049b7af8b5b5f9eb3f29d37e312abde898ad5b4891cd7d0ca1a7ee6c9d")) - (1713000, uint256S("0x00000002fe801673cf970df547fc14c4028b7c77abc185cb733b1726d8bcbce1")) - (1714000, uint256S("0x00000004a088e6e02bdc2cd157915dc13f4ff56eaaa0e7e79b796b5b3c72a89b")) - (1715000, uint256S("0x00000002e2d5aab4a2e23b05498896ff1e8c509e66ea5018c5a48135d65f54cf")) - (1716000, uint256S("0x0000000050ffc3dc91d5a8514d461b81515ebd67e22e2e3588436a8a10d7b768")) - (1717000, uint256S("0x000000017bfd0ce4a25cb8d4bae41b7e8d007854c1a66ea2fc015259b1e76174")) - (1718000, uint256S("0x00000000c8746b2e580c8e50800000d65fe893b974c2b0825521d916a87f6bbc")) - (1719000, uint256S("0x00000004647c20d62c9d15237d1f7d7996fd09c3e3a22f85439d1437eba50ca3")) - (1720000, uint256S("0x0000000087327d6b4e0644f9160915ad6f9e61497569d6223f079f7e9745674e")) - (1721000, uint256S("0x0000000201320ec96d6595875bcea2e431521b5035a766b072152af196004dbf")) - (1722000, uint256S("0x00000003d96adf0598c8a738e69fab7e578be011a49725b7dc77ebec29641dfd")) - (1723000, uint256S("0x0000000539537247a56af803ea95566ed5460664b0ba7958304f8f12ddbd657d")) - (1724000, uint256S("0x00000000e00f083cf90a695e5d6027a64e6cf3d42597a56871d17f310d7d3136")) - (1725000, uint256S("0x00000000888dbc0aa88e5d36cea342943d0271d5bfb15feebf637a838088aad3")) - (1726000, uint256S("0x000000059b3c06996b53335953a921cbd3edd0987b95a6be1987517afa58fd6c")) - (1727000, uint256S("0x000000048b539eaf18dfb0a9ce0b69a089fb4bdc80f4248dfd3e0270a2de6ce2")) - (1728000, uint256S("0x00000001055b9a98fd452d8b15f32990319ee5cb55fcd2463f382f1c9ba3ef4a")) - (1729000, uint256S("0x00000004237a1b7205a35ff9d2ed13198899f6995a0c9080ea1e0fce6b119d6c")) - (1730000, uint256S("0x00000002db2eb82e6309c174228bd0ef365f39ae75774123ff97ac729ce2ed42")) - (1731000, uint256S("0x000000066d71c51b95c32540d10fb0a7dcd8057ed812fb3bad4e084926b6cfe4")) - (1732000, uint256S("0x0000000285bd425dd245cc5456f6e0df4d1fc35531019297f3ba4a39e1c0f20e")) - (1733000, uint256S("0x000000020aad80909c26fc60918260f1096897a67d8d0e8e712b5374c04df5f4")) - (1734000, uint256S("0x0000000454b30f370832f4f09dcb3cc25347185fe78e6a20f53bc929c1f4f046")) - (1735000, uint256S("0x000000031c20ff6b27992f7df1c7852100844745d06eb081f1d7a14f8945a15d")) - (1736000, uint256S("0x00000002e8bb07f38fea576318d0daf090360d1c80f22d2c4d5acb18167985d3")) - (1737000, uint256S("0x000000029a2c942f291b050a17474b6fc0302911cbe28200133e6da35e282e7d")) - (1738000, uint256S("0x00000000ff3a12e66d4ea8356848f5fd4ee9a08793d182c91e805a0783dbb0ad")) - (1739000, uint256S("0x0000000141c88040bb76f4a44c42df8bab23b7d8cc582cdd76e7ce76ef56cb1d")) - (1740000, uint256S("0x00000001b8e797ff118fa4c0275efc75d8a1c57753b60939bd3365b29f801b7e")) - (1741000, uint256S("0x00000003f9d0ab66675f262a3bdcc1a31dcc31726ee7765ab29378d543329e49")) - (1742000, uint256S("0x000000002d3600b5c69588493b3129d847bb6e2576c0bc3ff9f6460efd2581f5")) - (1743000, uint256S("0x0000000282cadbec2f99e0c8e944b9260f13f7133cc56416870fe38e4848bfff")) - (1744000, uint256S("0x000000038e69af50667adef2cb0e9aeee8bccd52bea7e46227294f6a5e0c0438")) - (1745000, uint256S("0x000000057c5b7c69c1c10a2d11caecfbe17eb62e9be08bcf70334e25709d85b2")) - (1746000, uint256S("0x000000005590217461b08cffd1058091affebbed9715322a924057cbe697e94f")) - (1747000, uint256S("0x00000001f6a7c6dcb1984728e353cf24a3bea2e68c73754a916aefcdfb0cf29c")) - (1748000, uint256S("0x000000050efca03a20ac1d081f7b237e0187003765c302826c1c5ebb6eb251a2")) - (1749000, uint256S("0x000000029dc342a556a0f39de61340bf1913a001f2bedffb2d2fc75e9b2306bd")) - (1750000, uint256S("0x000000014c90d5bd41f3bb9cc83e966d17245989901adea24e9fb803a3af796f")) - (1751000, uint256S("0x00000002a3ace1b4b93e182cc8ab48c2d5f21d098435e08d6ffa006e66bde526")) - (1752000, uint256S("0x000000014717eb5f4d01bfe4a62a0a3cf5767ac1fe61d20782767b9ad38551a4")) - (1753000, uint256S("0x0000000165c3cd794a3ad5f5f7cf858228dd7bafea465d89d9ea6bb9d50c9a8b")) - (1754000, uint256S("0x0000000425309c3ac83b8f59e0987213c44f9d1a70af1b2df67acef706e37da6")) - (1755000, uint256S("0x00000003d788414e454fdf516d768165cd6efd59da056ad9275a2818bbf29dd0")) - (1756000, uint256S("0x0000000665956fc396e2c1b42c3932580e37f478ec7c15e28f35a76195a986d5")) - (1757000, uint256S("0x00000000dc5ace43a116ccc9358a1a6a1f21b99a4d4b38b939b5dc732578e340")) - (1758000, uint256S("0x00000000e2a0b7e090507f4f13e21aa73024fb5f8eb946975c8e18d3fbe5425c")) - (1759000, uint256S("0x000000037def7a52163a882e40c5f693d718ee3c9a3ff72765c91e5b6f9af913")) - (1760000, uint256S("0x000000045769ff47e8e3f1cb51a9b6ff1378899a231161da2a3b3caa8413b94a")) - (1761000, uint256S("0x000000052ffed0ce57ccfad266b64d9a949ad2784af80a066902dca2b2d417c8")) - (1762000, uint256S("0x000000010bef4889898cf3e2c3d0cb0ad0cc15a7aa394b6db6949aac4414e9d7")) - (1763000, uint256S("0x000000052b4397f24c7be192df7c617a3ec05eea73a9f0a71d294749c0555521")) - (1764000, uint256S("0x000000024051d111a516bd779d7a854c658439a0f82664ae7742fb76f2d87a86")) - (1765000, uint256S("0x000000054ae9cfdc5678a79671544817cfb5c45c865ce489388c6f4aab2216ee")) - (1766000, uint256S("0x00000004221eb0fac5a1340dec575372ca0ea842ac3f13eaeb41e848a9b3d605")) - (1767000, uint256S("0x0000000365cfe174006b52e5699397e641be7aaac2e4dd954bdc417dc2077004")) - (1768000, uint256S("0x00000003fdc4b4eda17fb6af8ae1551a13fc0d655a6b9559f61f39dc08ba0087")) - (1769000, uint256S("0x000000037d29ae542edf0e8fe09b2cf95d36f90d827152d4693244915b3ee456")) - (1770000, uint256S("0x00000004c918f544097141d0d6086567f483f707e948b6b9a9de762ed5281205")) - (1771000, uint256S("0x0000000436ac22a224104b08bff31869c7ac3102b9e35ae3cc23190809008abb")) - (1772000, uint256S("0x00000002385ec38d63ba954913958bc0c973698667f0cf37fe840faf362add07")) - (1773000, uint256S("0x00000004b1bd7d5616aaccf2eb556dfcd704c82c60c0b4eebc29f8f640903168")) - (1774000, uint256S("0x000000036415ef1337b9120373ccc66e851cf33e77579832eb65983bafeecbec")) - (1775000, uint256S("0x00000004c4bab47e83343b2bfce06d1542ebdefe1fddb286ed8f91a6c84769c7")) - (1776000, uint256S("0x000000016a5765722d608457aa92632a328ae581a5de599504c0935ca6092e82")) - (1777000, uint256S("0x0000000701c4bab1ce3c92668ed4949496b0830cf1d771670bb5631df8c7f643")) - (1778000, uint256S("0x000000013d0ff9925033ce0b3162926f200f867ee43efac2a7bdf6a95a56c351")) - (1779000, uint256S("0x000000003b272c6520cb8893f29db1e667aacbf40ff6da4da3ac325516c16e57")) - (1780000, uint256S("0x000000013df5ab5ff720342b732febd98fa9320bc64ea34714dbf7b4fbcd53aa")) - (1781000, uint256S("0x0000000b64be023cbcfcec386c79d708467e466782b835d1e67b486f2e5c2d74")) - (1782000, uint256S("0x000000021b2a9cd3cbbba257a3ce503f6fa1e39c6d1804100a14c13744b24363")) - (1783000, uint256S("0x00000007cde6f7ef2a41c581b122b24877e4203b3445baf0034d73ed14204ed2")) - (1784000, uint256S("0x000000004b37bb794f24abca1c311145c97550199373b17d2c7c07df5ebb9538")) - (1785000, uint256S("0x000000047edc917325ce9578a4c94f00a1183cd753c76b12c195e0e820d556f3")) - (1786000, uint256S("0x000000025c0177811a33925ddb7c245e56b941a6fbbabad67f300489e98817cf")) - (1787000, uint256S("0x0000000459dc750d8d9310ea28c7f88bdc2c2816b185ec45919bffd62153a57d")) - (1788000, uint256S("0x000000034ca7412ad71c48d3772d97dc99bbe3418b1c3cdd538b9700936fb199")) - (1789000, uint256S("0x000000076f64250f26cd16523a1785b7add386b594ebd457acbff0b7a6aa89cd")) - (1790000, uint256S("0x000000060d72c59bb12a1633dce31071cc6a132c626ab16caec774c1c7eb4d35")) - (1791000, uint256S("0x00000001515c3d79e4e28cdeaaa4a5b95b94e3a20e54c788bd66c7d79b312a5c")) - (1792000, uint256S("0x000000030f57e0c948e41863bda05f6c144ac8c9e0811e3c1844cc417e2ac8f9")) - (1793000, uint256S("0x00000005dcbfb0ea2a75b3babdf61fdaa8bc4bb24f08f2aadce4d431a681ad3d")) - (1794000, uint256S("0x00000005471c52605a54456a45e70e78f212988a21dbfc2b44329595c9d61dcd")) - (1795000, uint256S("0x000000041746a3ea05c2e383917554b8687bedce1c79c59e4d48a9dad86245af")) - (1796000, uint256S("0x00000002381f362803c3c533767dfbcb32f9756ae6bf9b7bfbf717751959be15")) - (1797000, uint256S("0x000000010a66bfc8280389b9358b7d32df17368c8d207385827ce5dcc26d8928")) - (1798000, uint256S("0x00000003170e34e98d6f7465c2aca3ac03fd6838770c639ffaaffdf47b2b5a5e")) - (1799000, uint256S("0x0000000d1f702ffae124c4d2ec4094b453f6a730f7d137638e517f377b2699f0")) - (1800000, uint256S("0x00000003119096a306aeb83dc7c3fa2c1baecaed090d88fac9751b85c02d5392")) - (1801000, uint256S("0x00000005583508df3d48ca3ea7aa8b1790a12b9d68a1537316d3ba83041acb70")) - (1802000, uint256S("0x000000060084882a0c69971fa6b1f5b219fe582b715864791c24fbdf779e30ef")) - (1803000, uint256S("0x0000000362f4bdac37f39bc886b56518b27ddca7df34c93170b316dc861997b0")) - (1804000, uint256S("0x000000052ac5a611ef3aded2989cc41fe7ef76ee95235ddc8904035ea6b41220")) - (1805000, uint256S("0x000000053f82b8a019469735d361dfe98b0ede3b7eeb1ea98bd266e4957c2009")) - (1806000, uint256S("0x00000002a73fd89ea6c9cc235a70d6d5de89870669b89a96a917f8bf96b9f799")) - (1807000, uint256S("0x000000045c45f117de62f01bc283f6170fda3ccc403aef07ad8d1b30eaf11031")) - (1808000, uint256S("0x00000004a6be7713af8533717d906be3d0b3df6b845be498591e775b27b570a5")) - (1809000, uint256S("0x000000030e95b1540d64d3cc1f596b3b84e21b7211595210d51807f12f784d29")) - (1810000, uint256S("0x00000000b00c53c576fc4938e55c3e091eebc59b67007a819d7ac77ab56fd296")) - (1811000, uint256S("0x000000008dffebe6bdf334c49df095ac5cfbcd6c81b2737e57f3ae706ee1355d")) - (1812000, uint256S("0x00000004870a62faf53b5bc60093537140a2ed830773294dac7fbe7caceac315")) - (1813000, uint256S("0x00000001cfa729a10b2978412336e3b8e5e776b79ebae946c23027fd54acae47")) - (1814000, uint256S("0x000000041aaaaa85cec731049de070fdc2b307b452cc305e8c75664efe5041bc")) - (1815000, uint256S("0x00000002ae8ca8bf637db8f46524c969fb60ec976dee9337c85e12acda1b800a")) - (1816000, uint256S("0x000000025cc83efcfa5b31b0a4b547cf5923b2f28344079f50ff09310b4e3149")) - (1817000, uint256S("0x000000038d0d1c7c923615fb07937822e313804269fccf884e38e613db802db8")) - (1818000, uint256S("0x00000005cdaec2266a5c21932dd2289a0171931aa4bdc39bcdc381d6194f3733")) - (1819000, uint256S("0x0000001f9bdedeacacc6602bf223dab9e25944637920fc6799738795c3c7efde")) - (1820000, uint256S("0x00000003a5a16120bde4b1a6a784ace30b616be37b8429e4f43eee44ceee0598")) - (1821000, uint256S("0x00000001f3c39cbe6a2bc81b0a6e6aa257de0bf13452d9adcaeeb71cc23ad029")) - (1822000, uint256S("0x00000004e0bbde4a8783d01581c7a1ba255506e9f967d8c096bc6c9034f70222")) - (1823000, uint256S("0x00000004a6d66ca53dbf714c238022cc0a42126540dff2f9cff7c59395a5752a")) - (1824000, uint256S("0x000000014b2b5044d0150acb34d993faa9ef0120a0842455e112d78632659c4f")) - (1825000, uint256S("0x0000000263a08ebf63abf6bd81764d1215a5a90aaded13d11bd04e2eb5107a05")) - (1826000, uint256S("0x000000065c08ecd03aa691178834c112fa5e728ecd82a8927f0e4f49664d5af8")) - (1827000, uint256S("0x000000058d8e8b4a7d38afa75d99f5e91b440fc209572ff26a98b1aabbbdbdcd")) - (1828000, uint256S("0x00000004480b9a3c0f9c87307804c6278dcb49c3fc362370a9fc424f27bac805")) - (1829000, uint256S("0x00000000f0b3cb7e289f48c72af19d62075c3390cd2991447216be87f9d372ae")) - (1830000, uint256S("0x000000008cd6ca08f95df6d9fab3faf3ab1ea74570d953fc05dea018f7ab0d95")) - (1831000, uint256S("0x0000000434184bdedea630dcdfeb3ff92aa48c46623f9237ee4b965150557c5a")) - (1832000, uint256S("0x00000003bf13197e2553f80bb4f1f41a27aafff87829e921fbddbdfa58718c78")) - (1833000, uint256S("0x000000037027ca30d184228e7ff663a9c0dde0f8f26f99bd587e0b8a309389fc")) - (1834000, uint256S("0x00000002827b9efc26f29c80eb728cb8ecd6cfc1a968b03c3f0e8fdd81625d88")) - (1835000, uint256S("0x000000049a0d5128db2dfa0961db2058bf7d153ebf0f4cc6d5054f561736f90c")) - (1836000, uint256S("0x00000003f67c56ff4281d35dfa78392f7ca0fe10cca06015e60b4c6ebfa2da7c")) - (1837000, uint256S("0x00000007ab31a2d80026cb363b965ed0b43a122b3e03e53b6f6614ed5ad835e6")) - (1838000, uint256S("0x00000009024dd6c35f41ebd7b759f8b108fb990c337fb2b764abcf571c731098")) - (1839000, uint256S("0x00000004a77cdd4e5130cee8c0ac9ecde7c22b0e342463596275db8b249d235e")) - (1840000, uint256S("0x0000000194db82e2be83455d477ba908718dc3c0b1092a4ef62459ad9b75b864")) - (1841000, uint256S("0x000000039654d65ddca898e2e13af01982516a542d3ede41163bb5e57c62cfcd")) - (1842000, uint256S("0x000000026c7a39b765fd8fab1cbd39bb4acb76e65de4d84996e90b6bc5cbbb8e")) - (1843000, uint256S("0x00000004ce2314f45bfeb207e27324783207dccc9a032f4f7560d5b63073d7bc")) - (1844000, uint256S("0x0000000830425ecc1282b45f0d9d2496eda51e7d29ffba7900441132c7a49d59")) - (1845000, uint256S("0x0000000a2f8f3e74c416dcd911fb06985baafa789066a7d98535fc7ccaf01299")) - (1846000, uint256S("0x00000002ac3047bbaf9a6fb3158e1245022251c40ad29c7b7d9e0dc117bae112")) - (1847000, uint256S("0x000000048c49382f8e79ae130453614ed621975037119573a8442e0c5674b7d2")) - (1848000, uint256S("0x00000007a618116d10d5cd2d61f3a542d44780a951f18b217ae394a95a51f946")) - (1849000, uint256S("0x000000053b6032fcd14396e27f966ce552450219e4f77a4bcfc7759362975d2f")) - (1850000, uint256S("0x0000000a68b3397504659a4e8eea87fc7c8788b8ce6616148c02addf46fb5a38")) - (1851000, uint256S("0x000000095bfe4bbdf20dafff20a5ba564b879595eb543394b789337e5493e766")) - (1852000, uint256S("0x000000027befad10df24147b92fc6b0b1310311fbcea57cb0ecb0f20cac43c60")) - (1853000, uint256S("0x00000000eb95b25125c7b58b9685242b4e29c4bce0f952b96475971d2b4bac51")) - (1854000, uint256S("0x000000035427daf79fdbba6152e558cb835c87817952e16dc83694d74f577dd9")) - (1855000, uint256S("0x00000000e86cebd49029f1348ecf3fec3d042fe3ad054040cf809975d676ccab")) - (1856000, uint256S("0x00000006d804ca22bbc006e2204ed721e35ca88675a66817f56a5daf3d34aaf3")) - (1857000, uint256S("0x000000069547a70ca10c149dc211c92c986800b9a4f74a44a0892f187ddf5042")) - (1858000, uint256S("0x00000002ca6303d0b280024eac8b07405dc2cfc86d54f3668074f60180bff21c")) - (1859000, uint256S("0x00000009736485bdfbcc7fef9068d2c50690e1331c0063381bb96940ce6740c7")) - (1860000, uint256S("0x00000003a9ec571fce90048e4c46586dd0a764a332b9aad36783ebe6ef225ef6")) - (1861000, uint256S("0x00000002fba6f836e098c87c71e6fc2fc811ef2c3e4014b8f66ca241c9538370")) - (1862000, uint256S("0x0000000458bcae098b9aed006b5f5b71cdfb5f7b73b0217a809d4ab5db2be96b")) - (1863000, uint256S("0x00000001e71c2b9725fd5afbb8586d6312200eada7971fdfab2d9c888daaf350")) - (1864000, uint256S("0x00000000971b82db5d846116c8bce305134f155730fc61a0f3b1e3fdc75828eb")) - (1865000, uint256S("0x00000000e999b3f061a706af846bc212e4e2ce41151a9c5d9ca6504ee7dc9675")) - (1866000, uint256S("0x000000003919b6575c4d446f14b00a57c326f282ed2e00cf75f72006d67680e3")) - (1867000, uint256S("0x00000001008c08cbae80cbf264f8c4aba686928fd72459df2298f2a6042d074c")) - (1868000, uint256S("0x000000000b8c1a48392a319214fefaf0a1aa0ff9c3ec57437fcce5068f2c4789")) - (1869000, uint256S("0x0000000758b5ff8f3edf6cf1f3b8c31778595eacc6e9139c3cd7485abf6ac8ac")) - (1870000, uint256S("0x00000006c0e18a5966014b683fc2ad66e67233857f870d1dfc3e4ba24c8d8c80")) - (1871000, uint256S("0x0000000aca708fa0f28d3c6dd195bce536428919684852372cca706440ce6470")) - (1872000, uint256S("0x00000009f1e7e2ee40d6436009ef884d25171058221068e6b561649164b921a3")) - (1873000, uint256S("0x000000041205df49ec40c992d36f19bb697f0dd25fd9474a613cdd4aea8cdf9e")) - (1874000, uint256S("0x0000000578b693fff37a8603939098aea30340b7c805a98317ced77cc9a9d738")) - (1875000, uint256S("0x000000038b9acc3c108412fe3a61bd7f77c4e709e7923fce6730173edc851ff3")) - (1876000, uint256S("0x00000002500162bbfcabe7018c43756da89dd5f5dd86b7a59d81b0aab222a4b1")) - (1877000, uint256S("0x00000001653423619a040072d21407c8f3e481c5d2da428a8c3aec4ff044ca3a")) - (1878000, uint256S("0x00000007c40a0e9e986333cbdabc6d81e100eaa1eea7a983b8bbb78317d05072")) - (1879000, uint256S("0x00000000742d5d64baebfca3b564937726ea4d4928f5b14bc5a5e70fd9c72e99")) - (1880000, uint256S("0x000000024d22fa0bdfeec3156b14a6ec455e0dccb913d006d701087a962bf692")) - (1881000, uint256S("0x000000077867103cbb1befdf33a24850470f1e26d8942a8c694b0cfd736cc8a6")) - (1882000, uint256S("0x00000003e31aad71429d93282c80b73903df35d6a762eae880ce7f746e39acb7")) - (1883000, uint256S("0x00000007df770a4a295aaed19a510535217663471284c37e62171a0b8b69070e")) - (1884000, uint256S("0x00000004f813d155265f3f09d6e0512bd0111e81708bd6c4b5857fa4c85bbf02")) - (1885000, uint256S("0x00000006236adc55d27b875af36649c7482b16a33842546bf4e8212805174e76")) - (1886000, uint256S("0x000000075757edd65122294031731b6038daefeb2d18e9adacda4b85da530fc0")) - (1887000, uint256S("0x000000021f9eaf50778462b2b58aa21b047200697c6c41880b014a14d9883c33")) - (1888000, uint256S("0x00000043c363d1126947ebea3156d801ef0922ecc57f2130793526801f11772b")) - (1889000, uint256S("0x0000000353d262ed384f346d50d7fa64ac7e513c155f4322386a0f1e33d626d1")) - (1890000, uint256S("0x000000029f50b0065af5c1eec4de04b140d847535d5422215dd0e26eed008d35")) - (1891000, uint256S("0x00000001f5b6af002a9524a8991426ee891a268f885139001ed6fdef2e1b0cb0")) - (1892000, uint256S("0x00000003c7318412f7ebd0a1da5e2809abf6293b2cf6ec519ed91a44a9b5acff")) - (1893000, uint256S("0x0000000c0efaacf06f7d9f5ce1a5211671201c24bbbe4fcbd759d17daf07d3f9")) - (1894000, uint256S("0x0000000095e2ba9e15c007baca9a01ea50ec64d87bf84f32fa9749d6f3c69f4a")) - (1895000, uint256S("0x00000002909536ceb779f4fb3bff8bf68aabcf26d953a6ccf9eac2b012c348fe")) - (1896000, uint256S("0x000000099876579cb3995e07b004c5b25304db77604b049c36473bb3be195159")) - (1897000, uint256S("0x00000009a267875f480399b16c0aa89f915d7d0a4ae15cf3bef66f9a104219d7")) - (1898000, uint256S("0x00000004321a0d47a384e405e4d3d585c7b5e064559b394d9b8517d409b81647")) - (1899000, uint256S("0x000000083025e8364786b286eb3d65cc39fa9cad4720ffef5a22da2618c4ddce")) - (1900000, uint256S("0x00000003df9302cdceced304405e46e3fe5950e191173e2afc810527d4a45472")) - (1901000, uint256S("0x00000001634453c1ad96fc6bae21a1e58c6b48af72ba9633b95fd313f4bf68da")) - (1902000, uint256S("0x0000000bc5de5e55f8d89dd1e26125b69767df8b410163d4903cfdc69687c2d7")) - (1903000, uint256S("0x0000000425dbba65f46a66a3255fe4c3e446c460970ecc066270abc0ef53ddf4")) - (1904000, uint256S("0x00000005cfedd11ec3f788d8c3e6a126c47c6bfffe0d34b821a0a1ebbd2bd0ed")) - (1905000, uint256S("0x00000004c602ef20f36b9dcfefe1970f3e008157ffcc8ddde3eb5f304f566618")) - (1906000, uint256S("0x00000004051959adaef5d9e0dc2b142351c5a5afc9a01b5c9b333a8f72844902")) - (1907000, uint256S("0x000000095bc01b7e1fdefcdc2fdfa5e9a9be8a896fae2d2b0907a5c6fc741fd2")) - (1908000, uint256S("0x00000007258940eebc238e5aabd9403c3ad97e88a90e0596a15a50f979c3b7a4")) - (1909000, uint256S("0x0000000623a348b65f08632fa073d3226831f677299eaa98afc249c6b7dea056")) - (1910000, uint256S("0x00000011f5e9f50fd2aa37b4c1bcb42a3607f4837687300be7cfc0acfe4db976")) - (1911000, uint256S("0x00000004bfc1a263d309938f5604f5c8cbc54d7b580c0b2300f6d96a2e6ac4e5")) - (1912000, uint256S("0x0000000137671d01cfcefa184b3a3365bce9caa2b8db024101f5c996b9cb2dcf")) - (1913000, uint256S("0x00000008b7007ec04ad61ce451f94a3c6fb2adb7426fc6071b2a5ea48c4f9fd8")) - (1914000, uint256S("0x0000000243fe84ebc7f9e6464ea68e938c3095e51561d168cac11e02da7dfffc")) - (1915000, uint256S("0x0000000463ee472250bc95ddf1403ac7ce518cb52b4570c5bf53c7c055f718e0")) - (1916000, uint256S("0x00000007450182fd8b6e17ab04c95182aa33ab281399e590538f3c6a5daff7cc")) - (1917000, uint256S("0x0000000a3e34f534cb787befc6520577404e39ddfb8331e587912e3c35f8eee3")) - (1918000, uint256S("0x0000000a8377c632f26108c153d2fd1d42e13e7bbfb8e62642d5e80546e2ed62")) - (1919000, uint256S("0x000000016e1b54a1aea7c531c47a3cd6aa5e0722d294c8fc0b718a9aa4574792")) - (1920000, uint256S("0x00000003e6d1d949658d5852b9319dbe0e75a4c171d2282a091a97aadc301da0")) - (1921000, uint256S("0x00000003d37c4d24c50bc32f815a8c089862d2a33f5e5010c0c36cf51f23d430")) - (1922000, uint256S("0x00000001de45a81a83b52246f6bdfd8ce4ab49ff209377f348040a2f7a08f540")) - (1923000, uint256S("0x00000006ec45bdf0764f20744447b67227cc91330bded5797881616372aa0400")) - (1924000, uint256S("0x00000003f57657a30f1fc6107611dc86dff2ea88a58d46a37339a1bc199c8f96")) - (1925000, uint256S("0x000000012f56b581239965f384ee45d91f58818781616b24e37b1a0f9ff3d21d")) - (1926000, uint256S("0x00000001fac2e82d4b4e4dc95f62625d259c29a16527dcd2ee8f1a5005944269")) - (1927000, uint256S("0x00000003ab28525c560ac0f8ba5a5ab32975b87ba1d423bdd1d1a9a675d668c6")) - (1928000, uint256S("0x0000001fc650e767800d6e022e173a9d1608ef821c296dfaabc8ac1e4f60f10c")) - (1929000, uint256S("0x00000000a297246c427d1d21d43110f0e4561e42ab940c1269d5cca17f0904e1")) - (1930000, uint256S("0x00000012f367afa4b2981c51d39b2d5181b076d93f85220a2e6c373be5c3ba13")) - (1931000, uint256S("0x0000000195f51b18da7a447e64c29086d9b9239f344592fdc31dd4793f6fb4dc")) - (1932000, uint256S("0x0000000a72a3f81eecf15b2b06b37e5d0e5c8be26945be29f7b80242dd8d866d")) - (1933000, uint256S("0x0000000602cec0393e21864f1f9de0e9a31c9eaf96d406d976b2932cb076f945")) - (1934000, uint256S("0x000000026ae0bfcedd170c1a7ec3c282806d522c714337105a5b9e3c9f75f51f")) - (1935000, uint256S("0x000000096c05eb37e98c0ac1e5da953f75c416b1939d05c3a7f38b443075274f")) - (1936000, uint256S("0x00000000b366ca6e89b40632b26fe80c14fb549c70484adede899f4b9550594b")) - (1937000, uint256S("0x00000002407697e167d3a957bf6e89a3f6ef12448ec37dc077c36541c08d9d9c")) - (1938000, uint256S("0x000000010e122ecf450e3f7af854c5d5af48ff297dc9f7b49ee60d7bb26b8744")) - (1939000, uint256S("0x00000004ace5ced8a4f052dd1260cccb305f4ec05207d3882b9ef40d11a5fe6b")) - (1940000, uint256S("0x00000001e668c7e4bcdee1a9b291e5ecfcad3eeb84ec4cff80eab05ce23109cd")) - (1941000, uint256S("0x0000000913631ecaeefb24c9d168a9a0c05df2012f3e988030eed645687a6ec3")) - (1942000, uint256S("0x0000000315b6039d0a0c14820f396dc960ad507783847f599b7d5154f88f94e0")) - (1943000, uint256S("0x00000005b7bc0112d299c2f0caed3b0cfa6c1bb730c9004e4d6ef2ceeec9efe0")) - (1944000, uint256S("0x00000007c64f0a932a8edfebb2d494665e524afc5ab755e2cefec84ce77d259a")) - (1945000, uint256S("0x00000006c6a9fe8c05283f310c0dff22a2d92304b605b593fe1c1fdfc1085bb3")) - (1946000, uint256S("0x000000054b5c0409f082be6f0b4deac5ef5106fc44173f3422885fb23bd73f7d")) - (1947000, uint256S("0x000000069a8e31d32df50f35ef63029bdd3a56d042d34cf6d02f6efc637c8dd1")) - (1948000, uint256S("0x0000000885fd68fb764457590ddee9aef3e4256f2ef067388a9c72714fa775b7")) - (1949000, uint256S("0x000000064285b903e667a64cb598f7aee2cbcf8a513a681334adef89f58b58c5")) - (1950000, uint256S("0x0000000a706ce153f138e155a21da714642ccf0997f9f9229dded6335a59ba07")) - (1951000, uint256S("0x00000005a15015e01043f708b242ae79f71694be8546098085f6604c007c40c3")) - (1952000, uint256S("0x0000000acf2ac942089d2f1dee9428c42ca89857b4cd412daedc8c68f1ca4b0b")) - (1953000, uint256S("0x00000001b11437b9668a1ba11d70af25a2c9c1635604e689d7e846d154af7503")) - (1954000, uint256S("0x0000000217414e96a2db88062abb846422f94a5329f9b89545c5c85848b3050f")) - (1955000, uint256S("0x0000000007a180128bd24de08bcda9a1f14985facc7836f4e0807c8f35b6f390")) - (1956000, uint256S("0x0000000e2a5b0ea6c830770e16614a39704d94224b317a3c82361e5c833e5480")) - (1957000, uint256S("0x00000004e224492b153481750f677db156a960d80e046c0a99fd05e3841f7a2d")) - (1958000, uint256S("0x000000038b6f492cfe2bbdef289854fb1b095c240dd4166a8f235e9eb8156258")) - (1959000, uint256S("0x00000001e59f4c934ef2f778612da7e8574649cce4638a7b4a9d9833ad32b6cc")) - (1960000, uint256S("0x0000000dad02b04d06cf33f129c4001eee6a1633281ad1966089287542dbf0d4")) - (1961000, uint256S("0x00000003bbbb92d446e92a6ca1c2026ca5acff6ef342ad7f98220e4a9f8e7ea4")) - (1962000, uint256S("0x0000000c344d3c9c22450b075f54711dda6d6f31bd4131cd8ace9197bbc79d11")) - (1963000, uint256S("0x00000007f00366ec50f4b795574ab91f426e130cd9b03999fb06a72fb4398f65")) - (1964000, uint256S("0x00000000bc0ccb4e73a3b1da4c8b9898176658fd67e0be6268e4e6a7d15a910b")) - (1965000, uint256S("0x000000037ef51b844eeddc16da9879defc6a3445142281ae34024447c3c8d9c5")) - (1966000, uint256S("0x00000001874485237ab2d0f395532fa16907e2cb0f25e5651312be730a2edcb0")) - (1967000, uint256S("0x000000054de0e7518f1263b6d0235f1e2430f7dd23cc1620122357a68731eab9")) - (1968000, uint256S("0x00000000a63a04fda160827bf347d6a6cd72ba97ae1608a76716cd97926ea88b")) - (1969000, uint256S("0x000000063f5c075dc64a67c603d21416c75ec633c1dcd0e7a93fc03bc21c6979")) - (1970000, uint256S("0x00000007790e2edf51dbaced8ac240a960dd133cbab4c0c642b93614987aedb5")) - (1971000, uint256S("0x00000007158c4e8d7ad061228c7386179ab5bececfc8e9719dc3129c6c441acc")) - (1972000, uint256S("0x0000000c1827bbab90381298cb73f55a2e146bbf235dfa57d6bc08632448acd0")) - (1973000, uint256S("0x00000005da023a70008ab851ec50b8b900332376f17f99588c91504c26b5b125")) - (1974000, uint256S("0x00000002114d8ecee02f6b3be44335ab85df887a86d78992af6a3ce9ba669c56")) - (1975000, uint256S("0x0000000a397eb6d899727ca5db6db81c6ad676c58020a0ffb3f391ff6888f3e3")) - (1976000, uint256S("0x00000009bbbf4aab09bb73cc6ed628211b1977ae5a3265fc778dcc06391c4c3e")) - (1977000, uint256S("0x0000000b7fb944df8a5b894a38b96c17eda331b3d8c406c5921f470d4adeda22")) - (1978000, uint256S("0x00000004008b94214bded7d7f14981a445055997d76b92a920dc4d55681066b0")) - (1979000, uint256S("0x000000074afc0070f2fe5643ae73e82f9e2a00c2bd10b65c4009f1fa8b9bb447")) - (1980000, uint256S("0x000000104f63e7a22c822a5185dfcf3daea94d1dc4eb72cdd1c0d5819b284b2a")) - (1981000, uint256S("0x000000056829646eb2ec3e513ae9bce58e55cc76ff9a8cca9ef9ba1665a39010")) - (1982000, uint256S("0x00000001519cc29c8c85f9f4aa37226b7d3a8a65f922f0406a9c5d92175c3c3a")) - (1983000, uint256S("0x00000017dc2451bb004694edbc90d12fc16aa45b25ac6b7b3d0179527e1c45ab")) - (1984000, uint256S("0x000000020d0f451448959d98abbdc7c9d890b8d52257323b551497376a558a1d")) - (1985000, uint256S("0x00000002577dcc6f4fe27913c036fb90161d35ce4ad9eec7fc311eaaef60e94a")) - (1986000, uint256S("0x0000000202b6fcf0b41f9214f65d5c2180815004d39ec2de27cacd3a92576607")) - (1987000, uint256S("0x000000055865f161ff5e3c9761b37505064dc7583ce5e5e592b6721ee6cb5347")) - (1988000, uint256S("0x000000080f858e3d234d701da31ef2aa1254fda3150e3ac368cb51e2115e3200")) - (1989000, uint256S("0x0000000cfa4d1e2bbdcbb234fe2f082850dcdfa858a32bef37cf89d00c89f396")) - (1990000, uint256S("0x0000000a4c621c54b6e3b4a75e9fa4f018960a1200f074de82324f68b294f04d")) - (1991000, uint256S("0x00000000cc0f49d2b2448b362e28daf3e57e1bafdb634ba2c85a51bbbec57afb")) - (1992000, uint256S("0x00000002ebd4290f45632a9573abcf4d6fc1639b34aa990eef34b6b0935cf14d")) - (1993000, uint256S("0x0000000b6d0c384a04f998e996f453058e006cd0d2bc3abdd518804eb3263fab")) - (1994000, uint256S("0x00000002c0fcac020a83d330d6e56255c82d0b47b048270dc33d6ce05b18048d")) - (1995000, uint256S("0x00000001d0cd3b61e536c43dac7d4f072769ae8e3b9abdd7f934059e5692c6ef")) - (1996000, uint256S("0x0000000ac753c7ed5450d7b05b0bd98a29df7059769c8bc07e04a2ca609c346e")) - (1997000, uint256S("0x00000004f457ce81972f0eff5cac5a63832b0d043e0ca9fc5ecac6dbdce65240")) - (1998000, uint256S("0x0000000b572087155a59cc67ba355d3a3ffaccfd685570ec56778329b27fb9ce")) - (1999000, uint256S("0x00000006e4773706c3a83ed448da34fc4e3e737d47df623254e059fd76643a52")) - (2000000, uint256S("0x00000006104d9702e1e5347418c213ba31fc3c14e009ab2d802de64f75f5ef8b")) - (2001000, uint256S("0x00000003e0ca20ef98823c384607d34fbadd3425f54b75b92a2f7b898386afff")) - (2002000, uint256S("0x0000000486c9388c8932401756df96c043e39bdfb52d8d0a147a5b97922b428e")) - (2003000, uint256S("0x00000001e639068d2aada8551e23effbea6e281bc8b10a74e8f9fd757a9d7f26")) - (2004000, uint256S("0x00000004e6f8077d8cb9adb4b0c4f08e88deb784c57b461167000763c9f7e22c")) - (2005000, uint256S("0x0000000381e818c7c3598ce66fceeb3f76538b851a33672b6fb7f63b0ee1376c")) - (2006000, uint256S("0x00000005956353cc542e589709ef1d1859c0466ae6590459ac3299513431e935")) - (2007000, uint256S("0x00000000efc171f4a2eab03c8ce32dadade866aee3a9c70b430daf051715f900")) - (2008000, uint256S("0x0000000120aad6d1c226a6ec15887cbc96135d2237f37c8c076dd20c81122cad")) - (2009000, uint256S("0x000000048d5381588a5be440fd9ad45747f76f6f5ce6e0b679ef549e0ab33979")) - (2010000, uint256S("0x000000086d9b6cfc665cd910e9d3832cde002278ae7342b1d660141390e81ed9")) - (2011000, uint256S("0x000000070b22fa037c6d290ba7811448bea1cf00c8f22aaf70b992a0456aaca0")) - (2012000, uint256S("0x00000003b32bf142b85b39c398205f42b3e10fa967fd78db41cec936347fa545")) - (2013000, uint256S("0x00000003b5bd355c58956838c927059b221c87af7e8282a5e0027e8c552d082f")) - (2014000, uint256S("0x00000001c5f2d5cccc99b43f7a9c1b9e3315eb4feef4bf611c680d6d55a1c395")) - (2015000, uint256S("0x00000006f94f71772329e7ebab13a932297c37faef047b4777f276281a6412e6")) - (2016000, uint256S("0x0000000421b342cf93513b1d098fc1a50904a1583f11a67b2d1286b4311270aa")) - (2017000, uint256S("0x000000035cfdd315adf7eb39f24b1114c316559b7266e28e369bd335332ed26e")) - (2018000, uint256S("0x00000004178109bc2e463872fed909113bb4a047722e7d4131f9f5e75e3b5d07")) - (2019000, uint256S("0x000000040bee044c9437828ac4569799f69d14527918015b94c6ef9f0ec771a2")) - (2020000, uint256S("0x00000002b5a7669c48ab1e6405688bf645062c2098ffaa8784bb6b9e952f32c3")) - (2021000, uint256S("0x00000003e7f2248ec7063391c0b8f650f6f02abcea8146025685cce41f1967db")) - (2022000, uint256S("0x00000002a3057653ae6c75eecd9f4688f0440b4e44f81af95cfa2072e01cf366")) - (2023000, uint256S("0x000000043d0b453924262edf2f2b07419cb1c79a22d2aeb9d0352727b8b95770")) - (2024000, uint256S("0x0000000857efe8be5bee7d4949b4a46924a6b16a773267faa47924db46755adc")) - (2025000, uint256S("0x00000007e197ec851d99abb18e9bda39af5acd4ebdf1cb284cf24becaa621936")) - (2026000, uint256S("0x00000008e7576b9fd21454ee1c241ad5ff86de27b90a2038b17c05174af6aa2b")) - (2027000, uint256S("0x00000007852b9d9c07bb4fb396bfcf1651fed5afacf91ac051e6232cc79eaf43")) - (2028000, uint256S("0x00000002134827686fa7399d930d28e1379d806c5da307ee8b6420e43e587c95")) - (2029000, uint256S("0x000000064d359b9d5968be2e7f2629363f16f14f2e2c23f9f113bb8074219eeb")) - (2030000, uint256S("0x0000000b62411c2027634d87f0fe56311f891a2471c2dc59f881e909fa62e21d")) - (2031000, uint256S("0x0000000b69aa3c2e0a408071337b0b8e500d7168ae58866008278bd876711b8e")) - (2032000, uint256S("0x00000004ce57ce1b210ec68c6d78d3e61b1bb61b15b42829f59adc144243396c")) - (2033000, uint256S("0x00000004024fdc3d1fac61b6713ad6013a2f36738d63cc8da836baf294bee671")) - (2034000, uint256S("0x000000057861c7bc5314e0da1aec9f1ebc1ffb4faf6955e0b75a892601edff73")) - (2035000, uint256S("0x00000010c8a56a05dad2b598c2912c8ea541b4a26f1547d96a653f6a4201bd22")) - (2036000, uint256S("0x000000041e11ed9bd926c40d810330fac5a7d68e6eaa363e0bb5c61af322ea65")) - (2037000, uint256S("0x0000000a7e65071ac725747967d8fa4c05cf1c3cf707bf32ea3af64b5be1b708")) - (2038000, uint256S("0x0000000f2bf661c814dd4c29018d5990125f5b944f8ff32d1dab74c4df96bb22")) - (2039000, uint256S("0x00000011646bb384a33b2176522d0b1890c4252e004f6e39a8a24ef23de7d4c6")) - (2040000, uint256S("0x000000049927621327cb34f68b8fa4a7a27a8f348284fbbe19a31dfb05796028")) - (2041000, uint256S("0x00000012aa50fdd25fa7bec01b4b23bf185028ee9b391ee01f448e3466dde830")) - (2042000, uint256S("0x0000001448dbbce0a941d62af80a4802b4125dbb703b8d6afc562f6f6a71c2ce")) - (2043000, uint256S("0x00000008425d39caac093da2d3bca16eb6341a5a5c6a0c9c3b29e59b613f19d5")) - (2044000, uint256S("0x00000003646c87e167ccec6a46c532299ff95ad0e09d763c77dea1b1f77fa41d")) - (2045000, uint256S("0x00000008a305f798f921a659779f2faa0c9b6061654f128bc0288e5ffba5617b")) - (2046000, uint256S("0x00000005f13275b498964e0b1b2175e9269c6e72f8d3d4a6c8800866648cc139")) - (2047000, uint256S("0x00000001faff2ed7233ac268b0dea48ca095c4221531fd5cb0a717be44fa57f2")) - (2048000, uint256S("0x000000096067600fb16cf37ff22348b0f66e81e70b9db5594ec96e55ea2aed3e")) - (2049000, uint256S("0x00000004a5c77487e8b9ce874907d1d87a5cc9a233b8200dc29424fc4d05c4ad")) - (2050000, uint256S("0x00000000f9e4a246d317efc0058c117518058b90e354fd0832a8aa3f2817ad98")) - (2051000, uint256S("0x00000004c25718021a1640d581520087f4b1ca550f60624e4f0165c42811f591")) - (2052000, uint256S("0x00000001f1cc162af35f2b78d57ce24699ddade07e9e28a72024eed4ae6d88da")) - (2053000, uint256S("0x0000000675cd8c85204a982290cbcee1ce7744883f50e49b42ec19bc3f26a6cd")) - (2054000, uint256S("0x000000073ae301de16e3a8ddfc31461abaaa6d0f68dce219e021e60786a87e33")) - (2055000, uint256S("0x0000000c3c1403f65d6d949bf47ac6c20ddf1a72a4746d489ac0373d0019ef36")) - (2056000, uint256S("0x00000000bbd938ba5199353f4464da3e0548a161b659d4158022c494e5964c53")) - (2057000, uint256S("0x00000002ef9613e873ab3e696bc67a854ca0fbd5d2c80ca2813790c7e68f7ca0")) - (2058000, uint256S("0x0000000aa352bf7be4811a434ed81b599c8bb75b51c9180ed950ed93025896bc")) - (2059000, uint256S("0x00000008758359b387368898cb7a1ab2637e8afcc25be27639c92044b6d38481")) - (2060000, uint256S("0x00000007e482f4d5931a4900fea1fe60e9b5272340930740d1daf0ddcb60fba6")) - (2061000, uint256S("0x00000002a4cc006f2a4a8dfe6031a8224f13a1653d2d7cb759f6424e973b21bc")) - (2062000, uint256S("0x00000002a89e57d8aa5073bbf9b47d3a1406b880d5a10cd04bf4db15b8d52f9f")) - (2063000, uint256S("0x00000001c2c88d5d2afd8e5d3ac0a58f75f1233278bad1f509c04bf2de8a0cd7")) - (2064000, uint256S("0x00000001e96c132713c76b3b660176376eee4d01aca688ccbd1f052c7e02eab9")) - (2065000, uint256S("0x00000009be2a5ecaa562da4b4a89974c63e41fff0d45e67aaef52cd5628832a7")) - (2066000, uint256S("0x00000002b9e96ca7a4702ff76b0e8985bd5b8165a844b0ff524118cb73b81b91")) - (2067000, uint256S("0x0000000b08dc59f10fbf0be04059d20d0fe8dffa0775a27deddeea31f1aa9c08")) - (2068000, uint256S("0x00000004f4bad2cf91e2ca928674dc26219b9fd5d51089b71ffa3a0e40c1a8cb")) - (2069000, uint256S("0x000000020ef61abb460f3bf1805208c67ef076169cc3d93feea93a44549e6b01")) - (2070000, uint256S("0x0000001933ccfe24b7f15e44ffcd6c70eb07ddd1e5153572c587c71604e037de")) - (2071000, uint256S("0x00000000b837126d714857fbefa49ba9b57a5c8e4131bc58a57a8cb72e0db9a7")) - (2072000, uint256S("0x00000009fe7c493b1bedea4cbe111dc917f36a5daa7c515efc1b152b5a4f898b")) - (2073000, uint256S("0x000000017b1dcba194020efecba83e73dc5c79d61a67909ba9697be7a096fa21")) - (2074000, uint256S("0x0000000523d291de6295dccc955ce5ad336f16f7758be2fe806828c577aceb10")) - (2075000, uint256S("0x000000000797b81b51747b233de0f2af1996321a91f3e4202b6ec009c084fa40")) - (2076000, uint256S("0x00000001e24e43918b04c68bdb3d6f344fa45161d6a83214d33182c266106942")) - (2077000, uint256S("0x0000000cd024f9475ad27396e68f77d14f261db3168510b7d5fd985e15317fe7")) - (2078000, uint256S("0x0000000098a181b61158deab23686d5fd27124e333c9db07b23144d490e94e21")) - (2079000, uint256S("0x00000008530c9cf4c78823bb23f1c12bf06fba66b757e5c0289c49a695d0f0de")) - (2080000, uint256S("0x00000006d0cfee04fb90dcbc7a3e97928228f9d49311f0c03ba36ebd91714c0e")) - (2081000, uint256S("0x000000061584569c356147479c7b59896050f266971b3ba39f2afd863c9d5da7")) - (2082000, uint256S("0x000000038a92b82d08c169edac37a1b6686d32c9b62efb79a1e0120a2e5b980c")) - (2083000, uint256S("0x0000000ed590f12cc3b91f450e5d30a317fb745dfd0559640bbd1822be0892cf")) - (2084000, uint256S("0x000000033451b003a9784bf72fb2fdf45a39b324efc6b58c5428ce4d06ae9383")) - (2085000, uint256S("0x00000006d0106b85a660e384bcf50003fbb3ebf4dc8ea4666745d18aad0ce706")) - (2086000, uint256S("0x000000046acf8da7d34ea59dee43aed38d8b174b8d3945223fd302fd43d1da30")) - (2087000, uint256S("0x00000005ced9d8c38416be2bf222b4e6bd0c116b8f3f7eb64b6a8979c4d42496")) - (2088000, uint256S("0x000000056abb81bb40ce200afa9431ec809a0b32614bc0a222d8f5363457cb1d")) - (2089000, uint256S("0x00000007510588a1f76e1bfd1d71302c734296e56654b973633cdd09715ac1b1")) - (2090000, uint256S("0x0000000419b70e2eee4092d5a7a6567d4f0f44bd25bb2e0c9c93640c147c8ad7")) - (2091000, uint256S("0x00000005a64ce43194676a276f61bc316b122526487eb6446900ecc3128d2b59")) - (2092000, uint256S("0x00000008a604ff11b8c78d309b067636a08881d6b67a262c33a35b7103228a8d")) - (2093000, uint256S("0x00000005cd8ad1d36831cb219e751d6fdea3c1ef5984106d4267181574abbb7a")) - (2094000, uint256S("0x000000084ecece471b2a7c20058821bc00507948c4e2ddda440fbbff20e8f9d0")) - (2095000, uint256S("0x00000004febb4db9b9a83945d1e876e6a1df57e9d4b7c7be522c313ca14b0684")) - (2096000, uint256S("0x00000000c6b4ad716b1ecdf2941ac5951566349430f4f65ab30a19d4683e06fe")) - (2097000, uint256S("0x0000000a69188059da26fcda56fda6616b6a7b910d81fbac0bed9cd2788fe11d")) - (2098000, uint256S("0x000000000964c0376b72fd3475fe3e20ebc0f43269d7c7be0c1b3e1ae3b084a2")) - (2099000, uint256S("0x000000075489657e7019ba875720ba133610cccbd69873b2409d293973878de6")) - (2100000, uint256S("0x000000048bce0d172dc7f21cfdd89cebc1dc8fda33b53ccd483fa77465601469")) - (2101000, uint256S("0x0000000d17a5f6802150f5f317617439d1406c1a6c9905360d5b8936f1235bf1")) - (2102000, uint256S("0x0000000a2e1dab28ba0b9d381c2a1dfc503dfc3ece2e7382efeef7fc0a9114ee")) - (2103000, uint256S("0x0000000af3728cb8cfd44ebba3ad4371affc1b77dded8c1016f6aa1e7533620f")) - (2104000, uint256S("0x00000004d3121b000e5fdfb36181921f290f9b0e88bca5e7db73edfe39ad4389")) - (2105000, uint256S("0x0000001578e4d7efa6c5071cce3bcb6c313dc20024605fc68ec52373940e2503")) - (2106000, uint256S("0x000000091602e3e0e6f2696b637f278878aa9df54b5da697623d3ff15758f530")) - (2107000, uint256S("0x0000000b40c4b2d15563ea4a4526618bc7456ae7af75b43564ef0cec35ad938f")) - (2108000, uint256S("0x0000000682e77053c4d4bcd7b6c2104e4e3c194154ef857cd05115f02681d81f")) - (2109000, uint256S("0x000000035a9bbeba87ba109903ffee9c71fd62a0a6395f1696490ea674e5a658")) - (2110000, uint256S("0x0000000547f13c557983f66c18ab0db1a64c9a8892dd84127e04025b5335a816")) - (2111000, uint256S("0x00000011342622886386272683f28994966657f559c5a39dbef9aef6c14314f3")) - (2112000, uint256S("0x0000000446d090e0f478bcb7d90cbb15142eb585c31229a433f8fb1470252be2")) - (2113000, uint256S("0x0000000db1383e1c4ca8e5f29136deb3f65ff989acbca44c94cdd4d431d6e40d")) - (2114000, uint256S("0x00000001574baeb58d2999e2ce95b0049ba0d680cc68caf2ee644abe05d17c58")) - (2115000, uint256S("0x0000000b784255ee9900040a759883da9cb04d29fd96f2b2bc8fa777377666e3")) - (2116000, uint256S("0x00000002598ad558cd93fbc11106615d187c227d80f4b9e30ba480c264bd2345")) - (2117000, uint256S("0x00000009d3b9dbbd63b11aa254b53421d55c864578617c5a57addb7b2b058f51")) - (2118000, uint256S("0x0000001083f791fdb1d314ac096a510e829d849c51ecfd07b05a97beca0fdc9f")) - (2119000, uint256S("0x0000000ef2775f3449c5f473744e92018681e9de74c59695457d4aa6fdd6d74c")) - (2120000, uint256S("0x000000044205e969e5d5ce1f297de9fa11fa23e0407dd28b852d48ab5e45f1da")) - (2121000, uint256S("0x00000010b04548479daf16dfa9c8e3c0e5b4e5b29876cb8a307d2e407aa3e5ab")) - (2122000, uint256S("0x000000052cd0199a56b4f840e6cd06afc7bae1fe5c6b060ad56b25e60037acbb")) - (2123000, uint256S("0x000000059972a7dde8caf40947c0e6fad1e85558e6da1e444be6c246589ed617")) - (2124000, uint256S("0x00000009eb2cbc8df55758e60fe06d9b38e57e1408caa4e03724519cf2639e7e")) - (2125000, uint256S("0x0000000118e98419f9b56c890c77e53298fa478bf0adaa1cd4e9617f575d442c")) - (2126000, uint256S("0x0000001168a734074aaeaa042800ebfd7a1283e0fea5ec8a688beed2822983e4")) - (2127000, uint256S("0x00000006dc5056e1e4ecd42ab4247ad9aeeb78313d5b00c14038a91c4c18b6dd")) - (2128000, uint256S("0x00000000310924a85b39bbd14bcb151d11e450bd69af772276509e007d93bf7e")) - (2129000, uint256S("0x00000014a0d1ad70f7e8b9444143cea92f0bbbba8f3490a502ccb26169acc3c3")) - (2130000, uint256S("0x000000077bafacdc4d2276cbd5e97b7f303c98570932991935d947c2bdcf6d0e")) - (2131000, uint256S("0x0000000af47253f4aea86c4af51be4b34f5aba1c454aa41098c41d84793cfb5f")) - (2132000, uint256S("0x0000000d8b0fd244174731a7f03a399597be4b27ea30f82711c5ce5a7b4cb778")) - (2133000, uint256S("0x000000096f73526a734ef98d58ceaf9839095180f96b27aa0b68f8e9bc395cc1")) - (2134000, uint256S("0x000000135654421fab135971b1654a79dddb59195ccc060a5b19ba80beef5955")) - (2135000, uint256S("0x0000000a93e5abb450f1f1aded4f38b808dfd038fd72e4c20b697aa98fa9cfdc")) - (2136000, uint256S("0x0000000408c0887a70fe0fa4a43c477426589ce4f552db7d176eb140a9a30fcc")) - (2137000, uint256S("0x0000000464a46aa2d5f22f3f4a39803aad1084a22dccd1fcb83f08e29d3e28b2")) - (2138000, uint256S("0x000000064a011e9ecef25946fe33f9c18371e051eb246cd3621090f8139ced91")) - (2139000, uint256S("0x000000082fa6fc9c1a92ebf29a0ba2eadccd20508a1db83619357894062a5aff")) - (2140000, uint256S("0x0000000460f855e76c4d739a4023d17fe1ac6376614a1764141770edb1d687c8")) - (2141000, uint256S("0x0000000481247aaabde662576ee0178a48a4f25ddf188eebc95db4ce2c578bb2")) - (2142000, uint256S("0x00000011b7aa00475cf8620ccb296970536e0a7e3cd928d5ed05020f95923ff7")) - (2143000, uint256S("0x00000004a48dfe4fdf0eec5f130563783c60e56115226c5febfa0a5201ba7b25")) - (2144000, uint256S("0x00000013dad0ea792083834d4e02a711a738ccc4f51955fca5852b151e469f05")) - (2145000, uint256S("0x000000054ce9776cbf4d7d957865c0b3aed4a6f466459b5f2f395d2b2a2da6f2")) - (2146000, uint256S("0x00000001e0aafae6d61db4d7fb1441e1ce8381a3243e8904ff453857d0b3456c")) - (2147000, uint256S("0x000000084f0c9ba9b8490ed271747910a4053bc09ec4ec74f399fe7262e822dd")) - (2148000, uint256S("0x00000003f7b29fb734195f4ea924862811300096a17367c0334bf74e2f483fdd")) - (2149000, uint256S("0x00000002586cd17b50a802cf1a37cbf0ae8c4f165a8b4bb1dbbf0f434832e44f")) - (2150000, uint256S("0x0000000234336fc37adb386d4d3ba166106b1888f6b15210b476778e1cdba617")) - (2151000, uint256S("0x0000000abd4237926addc45f8aa8e2e8e3dcecc8f9a065538a0d8add0a41adcd")) - (2152000, uint256S("0x00000004063fbe8f4cb1c212ebe3c4655744728091e92e219b245fcd5a0c572a")) - (2153000, uint256S("0x000000015299ea3f0bbac8c1e87774255918e60405de053e01f468605169721a")) - (2154000, uint256S("0x000000009f685faddbdded0d7aa0360e5fd0434672ec0bd7a496ef14f300d9c6")) - (2155000, uint256S("0x00000004e2bab8860d90b57285c78d521d0a67826c6b59ee53907a97ebc3e98b")) - (2156000, uint256S("0x0000000365fc20fedaf53e4eb761e8b3efa219d6bb5eee72b569d49302b098f6")) - (2157000, uint256S("0x0000000ee0631ed6e44c0ad4e2ab99732088a92b17b946afd6782faf8c1039be")) - (2158000, uint256S("0x0000000f64d288fff1628defcbfc0ca5c41a45cdffad7ac8b425eb688645090c")) - (2159000, uint256S("0x0000000b4b3609b61df88081218a64157546e78be3125f02e0fb9a2ad7dc6fe0")) - (2160000, uint256S("0x0000000c658223e9d6a2b966022dfadc8e6b4a54e04710d2ebcded687cead660")) - (2161000, uint256S("0x0000001159a41488ff78d7bedca36a0fd79b841dab0e8ab3904d82860baa8b8a")) - (2162000, uint256S("0x00000011fecb4f33f5707ebb37badaf7ff933f117e892f58782b4a9a5f3baa63")) - (2163000, uint256S("0x0000000f5797242276a9a7a8cd70d8efbc6c225fcec4cb733ddec3c763ca42e4")) - (2164000, uint256S("0x0000000886bfacf5c79a53fbd9533b7af09f22e1a340284f9cff2644fe0b4b6b")) - (2165000, uint256S("0x0000000ba2f63317611c67307a58afc3f536568cc8a26c3e1a7c96bfeae50d04")) - (2166000, uint256S("0x0000000e2cf36af435818846e670e89b01c4204520108b24fd8b7138da9a80fc")) - (2167000, uint256S("0x000000015fcddcda4bf66d26410b003fe1f117701d72a85a2ec308db6a88cacc")) - (2168000, uint256S("0x000000129c923c361fd4caeee0bfabef70c5358489ca3a64ccb2c0fb74c2d759")) - (2169000, uint256S("0x0000000246c65f7233c3319283c4600600ba6bec6ecf33113552762f8bcc82ee")) - (2170000, uint256S("0x0000000ac527711a96daa55c309ac6090e0c5e47f4dc43720fffaf3167d9385a")) - (2171000, uint256S("0x000000065376b6bdc5dc0bc108400a4749afddde1c1757c17f11476c1d612220")) - (2172000, uint256S("0x00000006ca134d446c4e8cbbd1f8c3fa0276a12dfd5419ac83797e01e87a7836")) - (2173000, uint256S("0x00000009009d3bb8f190afc32b77661e0081d2c3f5d7e5e3377b4bb53d5c1a9b")) - (2174000, uint256S("0x00000010feb7099c8e0a2f0582c653d131123ca678c11965886b7f283438d5b4")) - (2175000, uint256S("0x00000011dbb4610eadd4991bd7a29360d2e73e98ac053445639fa63d87df9364")) - (2176000, uint256S("0x000000085561ce48c0eac05bc168bf5eb4eec888795be1ce26ad10e9543b9f66")) - (2177000, uint256S("0x000000095e48492726b15e24aa78ada0ec58a06f3d8c6588e9d732f377748596")) - (2178000, uint256S("0x0000001219fe5ea9287939ddd0e6e5e2f8ad4d6556a52002ad5074de9f53227d")) - (2179000, uint256S("0x00000010e3820efc9a0adc4ef3871f03f2f4722c982a77b30f757b3ef9975cb2")) - (2180000, uint256S("0x000000081877c0925c42cb866f4100f49eeb17af7ce3527744e10d519a35dc90")) - (2181000, uint256S("0x0000000cea4a29dcf89dc3d699ffc9e04aef2e923f4b75ba9af5c89ebffdb9d7")) - (2182000, uint256S("0x000000018920865bb9ea4a7458fec9e3b0e9f28c9bef25488ce444f08c58a062")) - (2183000, uint256S("0x0000001353c7fdf1416a0d361dcbe669de666166fe645188a26eea4c78ddf03a")) - (2184000, uint256S("0x00000007dbbe33596b119695ebd530869646c32e322b5fcd377d48bc31fd8c2b")) - (2185000, uint256S("0x000000198ffa20fcd5fcc98d5242f43ed1fad39015885cafd817870237420ee2")) - (2186000, uint256S("0x0000000914848d7c0720bf947010055b0a99b1854e305ca5146658181493d4bc")) - (2187000, uint256S("0x00000005b671f40e14f57ae18eb2aef37c233be1f6958a8deb25897b0755d88b")) - (2188000, uint256S("0x00000010ff6edb5e128fb6c729fdca152931cdd2c85161770833ed0a4021556f")) - (2189000, uint256S("0x0000001790079fc71b5cf4c9e28e8c4f7c2ed68db86618fdab844ed92f49869a")) - (2190000, uint256S("0x0000001ac858c2579fe6804e17c9a4ffac6f87ad218a42e0023d4f4a937d256a")) - (2191000, uint256S("0x0000000657e488ff574b139465409d783d5e7b12275b9a904adc4bdcbec555a6")) - (2192000, uint256S("0x0000000f5d7531d2be768b6b077cc1981f3da77065ddac9019c376abd771d2bf")) - (2193000, uint256S("0x0000002bf66b350408816e2dcc6166a7438786d28b5dc96eb2be8251c9edd915")) - (2194000, uint256S("0x00000006bf224770c8ed65aba45a66e04a484d4e11718586ca367e76d23570c1")) - (2195000, uint256S("0x0000000d1a303359ca7cfff975ea261045650efae95a58ec942ae6b65418760d")) - (2196000, uint256S("0x0000000c10de971b747e2d8dcf0b435ad911c5c4e650c22c2926317f9737f958")) - (2197000, uint256S("0x000000147f6a742c2a6177e3d265a0ebda14d8b065ccb31979e5a98d886136eb")) - (2198000, uint256S("0x000000104a69691ae8661a505be930491f1f8e778b66f236fd82238f1ecc55b5")) - (2199000, uint256S("0x0000001d15e004f42cb05c998b9bc4dc523be01d38b05b70d6247b7b273b3b1a")) - (2200000, uint256S("0x00000008cfb7b2ee0a5efbcaf54fb9343fd45aa0fc15fdf9f793a9ec84b1b3d8")) - (2201000, uint256S("0x00000014ffb9bacf3a7cce9172c18acaefb7e37be1622c058239c3903a41b1fb")) - (2202000, uint256S("0x000000199098587a246d8326b2bcd3edb13f9a5929164973f3dba9aafc7e2db1")) - (2203000, uint256S("0x000000003bbc88abdde6242b28a8f7ad7c80a0a4b2b02f7c13f1e851a87c0531")) - (2204000, uint256S("0x0000000b9454d46cdc35e507b9aa0b98f8c6c98bc7473281a5925efa25e7d9f7")) - (2205000, uint256S("0x00000003c6742a5eb51b71732d4ad13bddabe1a22a0f9bb1879c726853db4ea0")) - (2206000, uint256S("0x00000010ee207e0218f281066a8cb3a208540766a34818d001859a4ff21a9442")) - (2207000, uint256S("0x00000011fdbf6ed34b05e960036e4d1bd5087cb10a3fb37edad1847403d0a5fc")) - (2208000, uint256S("0x00000017fd1de616ff467b5a6ec399703f232dd5e20021f0325df4cd5066047e")) - (2209000, uint256S("0x0000001b0d85a780bc6c1fcf95d775ddf7d11930b8a7d0f30c76e17fe5b91f08")) - (2210000, uint256S("0x000000320ac1d0412b54f38d926afd63830f91fcbcc06869b9970f53804c8b05")) - (2211000, uint256S("0x0000000e89eb1167ff72252d64de56463e8bb89a546a318100bc1e09b40c75ed")) - (2212000, uint256S("0x0000000929563985b806ac74a296d19869e5e74942e73a8769da3380b0be3769")) - (2213000, uint256S("0x0000000268c366b226e82917d23c89eebfab13d226388362220b0052cefeda9d")) - (2214000, uint256S("0x0000000667ffb02f6dfceba778614abdbf5ae11b73ce4d8e5524d3e77b6d1bf0")) - (2215000, uint256S("0x00000009c0432726c9666371c3834e5b500b38caf41080b68869cfbb12af6dc2")) - (2216000, uint256S("0x0000000b4a5c376d4fc524ad456c90147206bbd445509be5a191ad9979c51f67")) - (2217000, uint256S("0x0000000563e32e4235ab5694177fc53923b9b742d0cb8b6dd654a1b45b5b9e9f")) - (2218000, uint256S("0x00000002e16de2a52496ac6caff3454fcc8dda9291b042607ab5b8cb4eb06149")) - (2219000, uint256S("0x00000003f615c3a50807128b9eb71dd357782edc581b923f0d97ecb169f00744")) - (2220000, uint256S("0x00000005a5d40c3f2239ceab163c6b0065b5c8eb98608a67943c42a7d0efdf06")) - (2221000, uint256S("0x000000052f90cdbad630bfc9639680fa20fd40af4448d6222b832b1496f9d611")) - (2222000, uint256S("0x0000000a114845b86115b2b7e83999f8745d795b3e712481dd8fcad6b017ad6c")) - (2223000, uint256S("0x0000000671f202549cf64821f6a7f9a722cf79054fd415af2c38477ed11f4509")) - (2224000, uint256S("0x00000006f8d21a9b3ffca12033f5e27d7a4b45c6254cd3bcfa0a6a7e252ffbdc")) - (2225000, uint256S("0x0000000e97a31cd82ec650d23de1d6a505ebc6f752b1bedb9f9295be69840212")) - (2226000, uint256S("0x0000000a77b14d5e8aa98dc37bab028d11c999478a344dc2d9eb4db350a8fffb")) - (2227000, uint256S("0x0000000886cde6f06d72666d7ed1d85866f8bea788102932c973fe39af80a74a")) - (2228000, uint256S("0x00000009af43eb0ed51d153a3462b65d09b4730c277d528016852980e4168752")) - (2229000, uint256S("0x00000003f464599aa6386056de225d1cbef006b8da9c0d27cc6fa779089868ca")) - (2230000, uint256S("0x0000000c0bd50433b89655bf283daf43856db8d822e996f614397c8b1c393e38")) - (2231000, uint256S("0x00000003254820b91ccca295afaa3c9562ec15032953d5ad0782c95f7d4da9fb")) - (2232000, uint256S("0x0000000349afb4e98ae708f7dff039c54b1446da2664ad0dddd5f5b94755cbfc")) - (2233000, uint256S("0x0000000297526918a57fb1a21b70cd8ed1265547d4a61ecd57302c29d16aba1c")) - (2234000, uint256S("0x00000003288ea064a3f6ddc603de61bdb4c0ccfee2a70b621a7fe95f9ad35a8c")) - (2235000, uint256S("0x0000000b8a88cee5ac71e4b61ace898cafe7c895c9bf0b5db00b9d71fda173d7")) - (2236000, uint256S("0x000000056051307f0119d828d8d621b34ef6f60a06694c569c669ead97b9a00d")) - (2237000, uint256S("0x000000001f5aa9e9dbb3be2b01a4ab0b108b85fd375f23a0452930126a00c21c")) - (2238000, uint256S("0x00000002daa24ab7db17601826843cef57562ccc1aa80a692daf45435d816cca")) - (2239000, uint256S("0x0000000a9a4283412f076a0e1d36e1e02571468ff12d06c0d075e1dfa569af8c")) - (2240000, uint256S("0x00000008b78c49c1d514ce9cc583ec04c36023911ed7772d1cf0c50b5ce1f8c8")) - (2241000, uint256S("0x0000000cbb3151b62023e1cafa4476d7bf2cf34c13229f3ba510053182133ef2")) - ,(int64_t) 1750938666, // time of last checkpointed block - (int64_t) 3149424, // total txs - (double) 1254 // txs in the last day before block 2241283 + (1604000, uint256S("0x000053478e368ce750b05823a9e447a301b710f27706147d0d332a4cb36a22b5")) + (1605000, uint256S("0x000049065fd13cb57dd726073c7c853ed782c51e628710d1d24734aa137fe59b")) + (1606000, uint256S("0x00000357ae034d1f09c8811cb6ea67e215328aa356cb4d994e2b8a5c06135ba1")) + (1607000, uint256S("0x0000029d9591e7419b690a06e53b8fae256f2f2ee6c08f1d8f884e2178d38c58")) + (1608000, uint256S("0x00007d9b1a09454155a6a16fc8059c58663062467edaa2186e076d66614d61ba")) + (1609000, uint256S("0x000024edd89c1fb75ccb09efcfe784076424f10560665703756d6dddd92c63ca")) + (1610000, uint256S("0x000011718a84324cf4835a0c8542d104f15c1be0163a62964a2c5aee9d74b009")) + (1611000, uint256S("0x00002b51e1267724fc9ff41bf9baf7d4dc782ff3937fd06a8af1830fd9a0a2b7")) + (1612000, uint256S("0x000054122352b8d9291610ca615490545c8f4f0a70c433dd7c38971550410efd")) + (1613000, uint256S("0x00000c203ebc51c3245f63db8cc547ece178f7e66bc93ebb5e316283fbb142ff")) + (1614000, uint256S("0x00004d3bea1a9021dce6d1d40a2c06339378bdea72e7bcaa3e6f60d4aeb0c25c")) + (1615000, uint256S("0x000038e054ef9bafa02611a955d078821922c7db275d9a76d19380677739f23b")) + (1616000, uint256S("0x000058453b3b20f1cfb4cbe352a62e9cdb15a4e71b14201cb636051fe1bc4a19")) + (1617000, uint256S("0x00000f411b588d5c4da025c8acda1b9f59d30d1545391990bc92af770f08d256")) + (1618000, uint256S("0x0000290a91f0102503e4680f84545c56f2f70b07473a33f4c827cfd6bee1dd57")) + (1619000, uint256S("0x00004ec7af19002d933b97772c5c509ce1212998eae5e446a3bd85853a295565")) + (1620000, uint256S("0x000064999f826e0d9f30f02b043b9a4201c1e131780a3ff66d942cd77382f5ea")) + (1621000, uint256S("0x000091494301816024fe6487025f50412a11c3f674edad153e1d8ca6d718bf4e")) + (1622000, uint256S("0x0000848c9ac925405c44bab21acf2da2d7477365d471a4ae4087d618e41f86cd")) + (1623000, uint256S("0x00007d79d44347a8686801860167ff1ada44d79ee5a5f4d8cb5e4dfa4807bf64")) + (1624000, uint256S("0x00000e2c7c8b97b52d4dc46632b59a8b451ab7e825a663a5677287b7c7688f8e")) + (1625000, uint256S("0x0000744f002cde97defe6c309b5cb36f7445115c3a5df4a3b94652ae8fe11623")) + (1626000, uint256S("0x00008d7ea54cef69b5682e55e6e42a0a90eafac8bf66b1ffb9611c97673fc661")) + (1627000, uint256S("0x0000526f00c213475f6a2e6a6ecd82acebb0b6670cbd5925d57fb5f6920f4c16")) + (1628000, uint256S("0x000033512e220eb168f502b8c33b9e2e3f18282f7f368a1f3f304fb07676754a")) + (1629000, uint256S("0x000032f8b34f1a321b6cdda71a549c110a24767b186588ac9df0f50485b2b62c")) + (1630000, uint256S("0x00004965b5928360a6dc4e6915f09aa1b649cfca8bc86bd34852fa7db5ceaba7")) + (1631000, uint256S("0x0000903bed2cade92b0a2c264d67b5177a24222233bde20d2331554193a9d5a7")) + (1632000, uint256S("0x000054449bac4e93c8c702d96a6c13766ddd2be9f829a0433cd8a4cdaad2f6dd")) + (1633000, uint256S("0x00003d332ca6431bc517c6ecb55500dbf5f1f8af0668bbe9f60f6f8c6f47f039")) + (1634000, uint256S("0x00004fbf63652158368a413d0388bc44f48d076706ddd837e71b1a908a4e4ce2")) + (1635000, uint256S("0x00002119ef08cf1f283aa1a48f3f80387f92ad9e17ace20cb8372e7bd77461fc")) + (1636000, uint256S("0x00004162bffa0ec2ce6884bb6f4d39e660d831e816f8a2a176c5f5a5682e41b1")) + (1637000, uint256S("0x00001e7ae09c43dd8eaf5a9976fc7cc09d3520662f9ce0701137faa342ea29ea")) + (1638000, uint256S("0x0000671c52671f27d04f9ed4fbec3eb3f18de24b5aae94702b0bc571c265fe92")) + (1639000, uint256S("0x000060c64c5b820509a66de9ea7ad16e5006d70f94945a81a8f7f9e6bb728aef")) + (1640000, uint256S("0x00003b7b3cc716f0273150d2f6a8ba1616290975d847df91929dee69f730d5ad")) + (1641000, uint256S("0x000081ba05c922763c54bcc835b787d55568833380a87ce67d63296e5e5a67ef")) + (1642000, uint256S("0x00002dc1b0be12afdd54c292ebae66ad16975ae9bbd498e76ed2f896ed6ba5c4")) + (1643000, uint256S("0x000053232583a54ddf9037d5a1f42239677a8f0d2f2eb3749eed80278679a0d4")) + (1644000, uint256S("0x00005a66a9ad7ccecf90c03a0faedfaa7d70788eca1d84bb8b6077034e0ddbc4")) + (1645000, uint256S("0x00002d669f1bb99c5f6e73b649303895cfe90df2b4a64cc5698902be1232ddea")) + (1646000, uint256S("0x00008d105cae918f2564c056812867498d11c5051c6b975a821b2a8feb92b4f6")) + (1647000, uint256S("0x000080a5fef307a6c7a021fa84e76098da7b8780bf78bcc84b4972b3af51c6a4")) + (1648000, uint256S("0x000083eb156439adfb8e8add4e88817e7a7ffad59cc3aed94f74c80e53a7feb1")) + (1649000, uint256S("0x00001cf1b0e1f986e0329989c37bf7ffcaaf6503771a33651627fd3a7b41fac5")) + (1650000, uint256S("0x0000341800955e594bdea120916a3131511c32d586590eda7a18ac1763a9434f")) + (1651000, uint256S("0x00005dc73eece0d7a38f8095cd0a57661d85eb8bdba19a5376de9fda08e8b59c")) + (1652000, uint256S("0x0000091d1ba92ce6a8b919ee3558b6e8889c29afe2cefa5e51aedbd9a0aef905")) + (1653000, uint256S("0x0000898fdf7b998537a6f2df9126eddf01d050768cf51fadd7d528d8694a7217")) + (1654000, uint256S("0x00006b9a4f087edfbdd7cc997ee1fa01a7e52b01e4d3f83a9854291cbde98a30")) + (1655000, uint256S("0x00002aed67f5480edc71d0fd459674cc86e685593d61f5555e52b8734e58d4f6")) + (1656000, uint256S("0x00000590232098a61d9c26acafe54cb3563033ad9ba16528697c66ef5bff3e9e")) + (1657000, uint256S("0x000040a435e21e890c50b187005adc76a9a81ccf6834f17d162a86a4f77278d1")) + (1658000, uint256S("0x00000ba080a2caf2a742d242362a451c50d66ea3be0baac252ac91ae7174cb1d")) + (1659000, uint256S("0x000022de710944e4bf62a28c1000567fa288f8fe3eb89baea1ba65836ad5fc68")) + (1660000, uint256S("0x0000123057165ad76c5765d63c078527b8a9a7d3ddf80c781f0e07d58375b8bf")) + (1661000, uint256S("0x00003fc75ecc35908a9b5916de021e671d2f8f1b15c9fb2c363721b5b13ce43f")) + (1662000, uint256S("0x00004e0c496af94db6b2057891f0b2d0d747c4db6c08fae2f9a5a6ca637f7564")) + (1663000, uint256S("0x000024b66952bfe1ef5a6228f7a573b7a2f5bd9bc70b519fda30fd431fec6e68")) + (1664000, uint256S("0x000059fe0ea0712749e913c04e5b1e824773fc74f58f812d57e1bffc10088b71")) + (1665000, uint256S("0x00003f509758c91fd86416bd4240849b43cc02286187f68efa2adbda776b6c0d")) + (1666000, uint256S("0x000068fff377b050e748af622b1c8a5482b35217782b98a3874b6b1f6d09abb2")) + (1667000, uint256S("0x0000009982c44c36aa4ce8ff05994e96c5154b9e0503a57648bf367f4c961fa3")) + (1668000, uint256S("0x00005fa92c65a9da284ff520c51455f04e957c7c91c8e196fbff59046ad1593b")) + (1669000, uint256S("0x000010ac9235cf3f097b56fe9e5494c5ac226a32b2234501af1134d6a36d2f5e")) + (1670000, uint256S("0x000060e6cfa6e71aab1d9d44aa1adf456c33396edecb5418fd9e2849762cd2cc")) + (1671000, uint256S("0x00002226a841831cefb3d8920636d83cdc73512bffd80b119c32ac9125ff9769")) + (1672000, uint256S("0x000002d594d0764b8779f490478236831420e5eb83dde2d4e4e8cfc1ee8e6064")) + (1673000, uint256S("0x00002abfca9c79fba81bf242eaba00e8d9f9e10c260ea109b95840626f2c5133")) + (1674000, uint256S("0x00006262d539cb5f594ccbae69b0a387d0760ada296e23e229e23d392cc3d96b")) + (1675000, uint256S("0x000008f4476db222ad22d67993ccd1ed11868f30299ce7b5355e98c5f73abd3f")) + (1676000, uint256S("0x0000302ecb849d1c6cc2a305d483b41823a5e22071dd064ab0263e6d008aba33")) + (1677000, uint256S("0x00004012188d898755bcb78efa375bbe62e05f446b2d9a69b062a001d107e872")) + (1678000, uint256S("0x0000216d54a82a8fd2c28cf2f5415968001b8ba0440bc84bb4c5d213529e995a")) + (1679000, uint256S("0x00004a1cb97745b4b04eccfd9f287ef62733d931b1ada84d1ba92220a9ee3875")) + (1680000, uint256S("0x00002721896465b0ec8af7a2069a193eacc5a7a9c7047456f6001fc2644169fa")) + (1681000, uint256S("0x00001a8711411cac3920c3a6161b5fb5a1969831388e1f06437c48664e6af7b3")) + (1682000, uint256S("0x00006864dbb4d9651d6a61822a353ac65f3c6ec3d5215618cc4da57d44df98b4")) + (1683000, uint256S("0x0000208a56e23e55e5ce679b546ff704a44ba517a72b781d5eef507cfec130b1")) + (1684000, uint256S("0x000004b108f174bea0694ff5cd618f4445eb551eecb05bf136caa228d5ed1b1d")) + (1685000, uint256S("0x000010daca479695224871e567dfb65d436b81d93047984acc13fb1a8b3c23ee")) + (1686000, uint256S("0x0000499c2885f6795afef7103a59442ac0410fb1d9526b77de2940acc61a8a33")) + (1687000, uint256S("0x000005fa2cf764299602393a6741f176eb898243838f29c0413285466065932a")) + (1688000, uint256S("0x00003ecb391df53c4f930cc523baef8af0952b1fdaf4671a8564e44eae0cdf73")) + (1689000, uint256S("0x000080c793a5ee878128559ad85fd54e90f0b2fff148ee21baa5c95bedfb3ec8")) + (1690000, uint256S("0x00002cbcb844d35a17f8ebd41a9a01540c7a16b92e640c6889965ebc349026af")) + (1691000, uint256S("0x000020f50b5b53c503a6c9ae0f4ebdcea7065e9567200ad6744c5859c0c39c11")) + (1692000, uint256S("0x0000223fcb7689e457f7e7c453c5ff8a888c175c899f35d05a7cad1f28f1bc0a")) + (1693000, uint256S("0x0000359757ae580b1188c775d995eb9126357e07750929a3ae647154d57ae8ac")) + (1694000, uint256S("0x00000a7c783a580ba28d343200f3bac6dc1aa5a6c01308ff099ed9d7d67eb1e4")) + (1695000, uint256S("0x00000ca4b5edf2aaf9bfbc1e3ad364ffcdc03974ad7fa73acf808b0ca1d7d3a9")) + (1696000, uint256S("0x0000042e796b8853a76f909b0c70758debaf28412121f512cc937096bcab591b")) + (1697000, uint256S("0x000060b0578909cbb6c91950f7b286299838072c1c477774625a58769c36166e")) + (1698000, uint256S("0x00000a540aae639da81bbc2a07686a45cd3d7f03735a37ec254e79800a1c18ec")) + (1699000, uint256S("0x00005db831f885100ddadda005838f34c11d4d00de4ba4971dc563c99846c3c4")) + (1700000, uint256S("0x00004a95516d76f6982540fc933ccdc1a44ec8f1edf2cb7c965aec71766ba482")) + (1701000, uint256S("0x00006261d2a0f99cfc0e4c2a8137b8f4731ba0d82e4b13127b87ae3eeda2c787")) + (1702000, uint256S("0x000057b0af985ec048d6da7c808c9e217e9efc521eb3332d041e8cee840e5562")) + (1703000, uint256S("0x000013fbe29afed781ec71de8cabb49093668dc1e7359a8e237be872bc2c2fb2")) + (1704000, uint256S("0x00003a4d091f6ca4de7229120a4e3e19b16bb94daf239319c965f7b504f51f2d")) + (1705000, uint256S("0x00007bd1e1ffc013fcd293ef26e8ec0827ed7ec0a98364deefd7790b79ce3227")) + (1706000, uint256S("0x00004d4c6ebc035c2a3105b285e09b878aadc0be1464a94ec1680ac383839c85")) + (1707000, uint256S("0x0000705d5a4c6d2e834a9b5c990473ae1d705f960676ce3f77526864542809b9")) + (1708000, uint256S("0x0000736ad7684f46031f68c42b81d415152ad6411bafa375ec1008afc38d0a68")) + (1709000, uint256S("0x0000003e02c6a49ef5896ee889df7d5d9cedfc415ebfcefaf90da15e390c9953")) + (1710000, uint256S("0x0000226ba88350d59493cc577192bc5634bb6376f91a55eb8df78f9bada058f6")) + (1711000, uint256S("0x00001363dc6f9b184e487b3d6b46d2ccce1642c5c35ffe7110775834c90cd212")) + (1712000, uint256S("0x000042b848aa3c8e4626e9f5b05e4fdccdae46832aeedd9a4795f453cbb0dfc1")) + (1713000, uint256S("0x00003208279cb1b631c3afaef1b84f41cf6c9e0ffa33302e0f3ff81b00d8332f")) + (1714000, uint256S("0x000014c3746376fb86f4d0c2db30724aac972acc9ac887f9562c186bcb24c076")) + (1715000, uint256S("0x00006212a1279eebcefed3ed0f8f9cc890c99516bb878204d30831b676dd4c5a")) + (1716000, uint256S("0x00007e631d540419722ea9995cda51eb2d668ed2393b69d7cb74189faeed278d")) + (1717000, uint256S("0x00007eb08be2cb692987dd1b4c2edcd863197aadf43d3e6aa7b61f247d6c65b6")) + (1718000, uint256S("0x000027f48e25a622076c60f9e446e5595aedea7e55bcabf5a4af03af7ec642a1")) + (1719000, uint256S("0x000068ca92c455850aad16e9307ff75f8ae5961b87f408fb2278446e4c90f914")) + (1720000, uint256S("0x00006ea2d6a01d1090cf17bb92e03bd49b87e7438fe78d705f587488330b537a")) + (1721000, uint256S("0x00014c48ba5d9313ebf921798beb9ffa27d0f58857e95860cdc8757b53d54352")) + (1722000, uint256S("0x00008c893e990df3f3e396b92583cc835fbf69f868593eb09749d5a8b0ce3a5c")) + (1723000, uint256S("0x0000eff199f9ddaba01df2ce8578d9e4fff03924ac914ec0efa05bfa91d71e46")) + (1724000, uint256S("0x0000061f2edc3f2da6efdcfba010bd386e4b565bcabaeed8944edfc75b60979d")) + (1725000, uint256S("0x00008a69182eff8c5e509b6b1f1a112c552983a6a3fc6b07384faa6d4f519fa9")) + (1726000, uint256S("0x0000737781fe7bb4ce458e0af9f32adaabd83e82ce041cc004c4fa6847c2e7d0")) + (1727000, uint256S("0x00002475df37663dbcd0bcf001576a9ba6ca094e6ec2a39eedfde9a02f9e7290")) + (1728000, uint256S("0x00002b12751fd1c39ce157ba4529adfd986ec92a7e4c611dfa6a141a997ad176")) + (1729000, uint256S("0x0000659829f249b3dc18760dafc1b1e764dd36d89b7f5371009b2259f54a55ec")) + (1730000, uint256S("0x00001e84c6ee75c149141d2b89d4afbd5e96e0be9310d4f50e051b69a4259e09")) + (1731000, uint256S("0x0000190c63463d51f63c0584eea276f2c3cdae35230c81acf568425d0f8c392e")) + (1732000, uint256S("0x000042b4729edf292931a95e0317d034a37ff27af9e9d634673ee30314997048")) + (1733000, uint256S("0x00005618f4d169cadbe3115358327acdf057cd18c9824303262206406f5654ec")) + (1734000, uint256S("0x000030ef72eb4f37c6ac49194c057b65a06bfc0d6ec5d1d66ec0ae48dc2f1c7a")) + (1735000, uint256S("0x000039bef8acb4ce5e392c74d28d3a24722adc6b2733c0f894676ac8bbe91bda")) + (1736000, uint256S("0x0000077464238b381a7dc5439796d5ed448e1113c16da92fcaaeaff7d637ffb6")) + (1737000, uint256S("0x00006abdb2149c55d364365834521c8108944b5e7040586aed969c40ed0cff83")) + (1738000, uint256S("0x00003d5f979f6ed24676dcc75d1ef76d3929ef7b35ff97b3a1f373abbf572edf")) + (1739000, uint256S("0x0000610e4e2b9a22f6cf9b3c1c8383dbe878d84fb1de120c246660410eb7bc16")) + (1740000, uint256S("0x000052f50002d0f09d7cf561a3fe8750f4727c3de2b4878de7aad0ede2b4d2ac")) + (1741000, uint256S("0x000012814eb5a2b089d153726708a6583fdc022302e67f1d7316dbdbb82a1270")) + (1742000, uint256S("0x00006887727efd344cc499ed2c8007df9926f6044ffbf6249b7113f2e073b261")) + (1743000, uint256S("0x00005f43150dd9c4c29601684e968dc2b9e4efcef93ad4e6b1d1962d9a4d29cc")) + (1744000, uint256S("0x0000348b420511bfeefd29e0b3ae3cb94b7e36486eaa70f42f7744a2f074d432")) + (1745000, uint256S("0x000063bf697a3ebe403bd85dd22630526fb221e6627a89ddfa0596aafc1f67ba")) + (1746000, uint256S("0x0000579df26125bc0d7fcb19e5c0bdc3c8571fc2ab204c06062ab8eb76e9bb4b")) + (1747000, uint256S("0x0000718b472017ec78e26d7133e8e0a8f72c53c63bac42f28f7c04bcbd214af5")) + (1748000, uint256S("0x000069f38b9d3ec70b00719e01d4c9be2d912b1bd9146e5d85cb84f298a9685f")) + (1749000, uint256S("0x00004c068473477c1f30e7d710253ab08bf56f37f58461e47aa0a9aff70065ea")) + (1750000, uint256S("0x000043532ed42651b85e839a7f0069955ad773813b4d9e03769a3457ee153bba")) + (1751000, uint256S("0x00000603fa64452ef035ba66efaf61f9d1bef639589efcb5a9061e42e8f75807")) + (1752000, uint256S("0x000022e11684d01c3fc66be7cb1587b213629f5a195b9c3812e101aa150cb073")) + (1753000, uint256S("0x00005d60800f541c61d278cd04d10909d597b7192a6531e02d57d17b45a9fd7a")) + (1754000, uint256S("0x000053b6ae3e983f15973243614a78e966b288a7cc92597a7249cc439f6e09dd")) + (1755000, uint256S("0x00007fddfeadc361a3bd154a5f5df7dc102b447c63a780792ac17102799f5707")) + (1756000, uint256S("0x000018dd4ba5cde78e3dd088db5d0ddd556a311aa93f02dcff8795bfa5b74a64")) + (1757000, uint256S("0x0000582946323f8d1fcba249a36d6a9677e049d4ceb24787a2f977dbd5217658")) + (1758000, uint256S("0x000027b5b1620f01540b78e234f94d62497073b879f99dda7ed8942c4b26b37c")) + (1759000, uint256S("0x0000377be04a14eeda1211c39c6dda49d6b8ca79a61f555d5e4301e58a666c68")) + (1760000, uint256S("0x0000545a45b8d4ee4e4b423cb1ea74d67e3a04c320c6ea2f59ee06c08f91a117")) + (1761000, uint256S("0x0000492d39004b5ec46b2860ac851d98837e635462587707a5b2154de214547c")) + (1762000, uint256S("0x00000077d462411c597e2b7e66afe1036bdc7e105bc6e15d307eee545a030792")) + (1763000, uint256S("0x000009535b9fe334ca93fc225e0a4b171c9053de9fb153207d8ccb0d444274dc")) + (1764000, uint256S("0x00002f9119c70a9cacc5d86b978b8ea8be000f0c9f27fbb64f0dcaa3dd97232a")) + (1765000, uint256S("0x00002d4d5f079f97e87fd2f8d3704bd2ebbb2e2baf48da062c851ed2d0fae243")) + (1766000, uint256S("0x000020d73b8a5b01724916f1c2cc122469e8d9c1367b1783ad000b59a40587d7")) + (1767000, uint256S("0x000020f2db3f3e9bb3bf8b96b9c9138d3c44c264a6b1818166fd38d680bcdafe")) + (1768000, uint256S("0x000024707282a995239352ddfa4c671abdfbc5d142bc9b61e7c3a350bc8fe90d")) + (1769000, uint256S("0x000017423a6c5acb3cdd53270a883e92c9557502f745beacaaaac491db1c735e")) + (1770000, uint256S("0x0000179300c15684316293c7c5cb2aebc79a63fda0b65f7d87968a3ecbe23d11")) + (1771000, uint256S("0x00004326d56a8837e48404147df4387176a01ad47c6e634096934e9d245e4a0d")) + (1772000, uint256S("0x0000136fbf23b3b667634294a85a698301c5abf9c538c8c3e1ced5ba051fc5c8")) + (1773000, uint256S("0x00002c0b8ba35049d0ea5d47c0eb133662d6c94c9e5f26dfd58b06edb475b7bd")) + (1774000, uint256S("0x00002cddf958e4a803932dd603d55aa4c3a26f534d30ee93778f8b0c48389388")) + (1775000, uint256S("0x00000dc046856e9dcee55d1d60aa8b7cade2769f7912285a0717de2a19541deb")) + (1776000, uint256S("0x00002bfb75d5d36ee26f71cbb811803a2788e72a74fd23d93f9d25f2fdb578aa")) + (1777000, uint256S("0x00001f92ebaf6f147197db435256b1e31f9eab0f8c569cf821968ddafd2a36f5")) + (1778000, uint256S("0x00004dee827ebf83c33915d631c411d47031dc0359d2e3b8fe44141bc6e6fa0c")) + (1779000, uint256S("0x00002ad2827090b8d13a1f0d9eb18323960d531790387edb07f8db55eac01bfc")) + (1780000, uint256S("0x000031393466be34251e6351c1b11b10a8685c0326e2435865bbb51980d34288")) + (1781000, uint256S("0x000037604c32cbf0c5cca5307ca3eceb1603fc3355cd26cbc06a1ae688b1f65b")) + (1782000, uint256S("0x000031021d1aa374f327d494b065e8c38383599a86c36e4fbb447707d3fe68e0")) + (1783000, uint256S("0x00002a53844ccafafbbcfda174e5a3f1afacf7de1d263c38423fdfd1a1b36d21")) + (1784000, uint256S("0x00000277a95bec73fd0502358ef5bc229f65df2c97b63605d81b5b52ad403d7b")) + (1785000, uint256S("0x00001566e14ecfbc76e7c52198e6a25169ca00a4a2915a1d858ec93bc74262bd")) + (1786000, uint256S("0x0000087ad1507eddef08c30ca021b0b4c664366e150083e2d597fd792d38b44f")) + (1787000, uint256S("0x00001ff852fb5614b2ab958111e499ab534eefa5c3d52c207efb5ccad00c79c8")) + (1788000, uint256S("0x0000281d5440a594774e937806b986e4f127fb48ecc55d540a2ea3be686bb85f")) + (1789000, uint256S("0x00000823fe642a9cdab7ea2458e4b170c25a25af07d2bfa34faf35a76a9ae934")) + (1790000, uint256S("0x00002d304896196373a4c26a912a6c0a1d8d9ef463f473487c577d947f001b44")) + (1791000, uint256S("0x000059590c97e528c995ff0694f144118b4ac84b48983a2a6b98dc57fae52ecf")) + (1792000, uint256S("0x00004327ea2c863394f35629c955dbe9eb800a57f5ab4b7320d59a607a1c221d")) + (1793000, uint256S("0x0000164c30036f88fe7c510e6fc05db811778789b83c69c54d2ad6148cd11c0d")) + (1794000, uint256S("0x00000372d3809acbc2ab6f3aca9f1f4e32c220e62beafbccf4ac191785105580")) + (1795000, uint256S("0x00000dfaef69d7f7ee1b5b41075b7a581faf6cf970a5d45ff36926f88838948a")) + (1796000, uint256S("0x00001cbd8b9b409bb86040bc2fe677e259449f26546569159a155066703dd387")) + (1797000, uint256S("0x000041a5045f1ee4f7aee3ce68a415d669d8044aeab8ac32d4ec3359a70cb2b2")) + (1798000, uint256S("0x00000ed69a1643b2a47bd9ad767bc94159a1d792a11ae98210727e7da8f27e44")) + (1799000, uint256S("0x0000257ee2759bc55f39acb7843f3d3213551db807ec3aeabf6322d9dacb3ec7")) + (1800000, uint256S("0x00004d177912834d21b37de3b59c494adf644e4aa01593ba80c9efde53d1d602")) + (1801000, uint256S("0x00004b7d50c26ccb608481f69f72bb5e1921911a9e2e68f4648ef1d37c8b4216")) + (1802000, uint256S("0x00004c2492ea62980724aff4b13b5c133987732ec97f93b0751d52f04c0de015")) + (1803000, uint256S("0x000009ea2b863c3c7ad1b9724800f88b1e3a9a37f24a1fb503cbecf5393731fc")) + (1804000, uint256S("0x00002e0dc875feb75006a95d45f294466a57cfb35261de56aa6cb8e5e2909817")) + (1805000, uint256S("0x000018e30194fd650240928392b4a25a7bdae1b981b2e7eab2a9936c507a574b")) + (1806000, uint256S("0x00000bdb3a08aaa062f8a0a8106f98f925a48e55cc2a31f185f9077cb866d012")) + (1807000, uint256S("0x00001ed693e580ee930797bb166889ef018824d7abe54ec9387eaa53daf37876")) + (1808000, uint256S("0x000008ce256e55ed956eac705a9db497febdf74d91d7d2d28dcd221b30e70d2d")) + (1809000, uint256S("0x00003b580a73fd3ca8740d65a87797068a3214735d90275541563ad42af970bd")) + (1810000, uint256S("0x00001327b6cb0ce0db96faa692490fcf620878cb38a5a2380b0c4f21bd85eade")) + (1811000, uint256S("0x000022f05f794f3029b290d33d09695658f3920a53723e3301b33596e589781e")) + (1812000, uint256S("0x00003002dd06aff0475d2c7d4a944a0fbd8a83a1433cc18e2de77ad06015cddd")) + (1813000, uint256S("0x00003994472d12f636063b9885f07ea66cda525dfb2d91a8d98265dc3095e67d")) + (1814000, uint256S("0x000031726bddc50f1995c08e5dbcee7f99379e4c771ab84c30c2236060c91595")) + (1815000, uint256S("0x00002b97cdb9bfa9338e8c640e69610ef51ec6fe16a72896cd4cad9a97536cd0")) + (1816000, uint256S("0x000003764da45974bd00782e2fff4fc7ddee81ba08540c54283c99acc6f2ee85")) + (1817000, uint256S("0x00000008139da65b49118a2a35d8bf791226552b25c88ccdcb87dfb9b84193a0")) + (1818000, uint256S("0x000015be2d89fb2e85d0a5c7fee9c4f00fd03c45a415ad86d381349671247150")) + (1819000, uint256S("0x00001044e1eb1f1d4475c3948ad032d6f65cce82ea65e0892eef2a845d9283cf")) + (1820000, uint256S("0x00002d0a09117ff1a90cea9a00209084fe368119b389c3262847679a324b702f")) + (1821000, uint256S("0x000001a7e78ae32e7f874654d5cfa45ad7b3e1ec933ba2677a59d3329adf06cc")) + (1822000, uint256S("0x0000478474b4120e178487b1e1cebf1b9378b193e9608a08f3b11b190875f453")) + (1823000, uint256S("0x000024bf8a7823f352d546eb4bd35439964a8fbd60eedb1d7ca5805b27ea4fa5")) + (1824000, uint256S("0x00004c1f93698834235f3c09ef769f7add44e6b483284d3cb959907332597790")) + (1825000, uint256S("0x000036426a77aa950d2edb58978347c33937053a4c04c4c374b795046fd69c1e")) + (1826000, uint256S("0x000018e81a9f1558795749b437a609d815e8aa5eae047fd2ccaec7c5afadaffb")) + (1827000, uint256S("0x00002bb8823bf3e695cc69aeccd714e447bb2146c23ea4336fdec015aeef395b")) + (1828000, uint256S("0x00000119a21203c0a1c1c39d00397ce69da6257da836483329399178ece1588b")) + (1829000, uint256S("0x000001342230b7b218360b79f22fea82efa6b5d2f77937c5f1baebde80718b95")) + (1830000, uint256S("0x00004bb3bc3f7022b560c3a9bf1946e2a113050f6d3009cffc6b5cbeb3e17b73")) + (1831000, uint256S("0x0000184434c1ba71fe1de2df0ab46095ead9e2cb000f422b618da2db56d3997f")) + (1832000, uint256S("0x000037db47be2f0adb85ec262805a08f22d171bb82950ec9c08410d4c4d47b3f")) + (1833000, uint256S("0x0000057f6d476bea2406e5334362b529a74457fc4c7b8823308ccb37ea9ec9c6")) + (1834000, uint256S("0x00004387a61227d5d71e88ada082308503eeac0f64b21d613164a0dc9db84130")) + (1835000, uint256S("0x00000a5a80b37abf871735b2010a23be103d7e9a22c048805a2d60084cfb8344")) + (1836000, uint256S("0x00003616cfadfe6c85cc414aed7ad48faeca5ed2e533668c81f2254966c0ad26")) + (1837000, uint256S("0x00002b2de24e2b74ca129e722f7b1f15aa4f68f4380bc303e58da8aa64bf7d40")) + (1838000, uint256S("0x00002c9f1412d3c877cecdcfc3649a4050026637a5e9cbf242057a52f582ac47")) + (1839000, uint256S("0x00002a4bf1ef970685f674cad0b6fe824fa201181188d9e2683aff588ee9e249")) + (1840000, uint256S("0x0000049666c76067a8eb150b1c5e6c4140748a64eeccbaf03d958d1ade2badb5")) + (1841000, uint256S("0x00003178a2cbba3e840081176cd413ac30d14b07ff3e48c81f9a417b3c65afbb")) + (1842000, uint256S("0x00002d8db6095eeea60f6ac7113e3c124e502779222e13dcb789c0b4e6215b7d")) + (1843000, uint256S("0x00000d5dc82429ea32c9dadf1b7cdd1d75712a67a0e395b90d7ca447f30d3c33")) + (1844000, uint256S("0x00002efe1c19db85e54841d08a9a786986991287bc59fc43478c8c151ac15030")) + (1845000, uint256S("0x000026ce9418988c380f840113e6e3e3eaa620924041c6c9cd2c7d79f3ccecc9")) + (1846000, uint256S("0x00000b87d8eabce985d4b1c999d633588b8dfeae9e47c2580ec9ab04b838ee22")) + (1847000, uint256S("0x000035f4b8f0393865ac597893b643a0c4bc837cc332489e81fcc86897044cdf")) + (1848000, uint256S("0x00002ddaf6b5ca7758eefa3b67678bd16edce8dad01c41a0d5218761250e3414")) + (1849000, uint256S("0x00001fd4f3ca96ec1f63957a390ea2172130f7175f03fac2d11150b8fc716175")) + (1850000, uint256S("0x0000424fa1d6768f88f10563e2aa69c2ab6f97fe37d57b029a169d72389233e9")) + (1851000, uint256S("0x00002224c503bfd8f5d622cc81624bd78d2ebce3d67e324af027ecce811f7734")) + (1852000, uint256S("0x00000e1199210813dcce4e127dc5bc52f30b06a5eb5416bd56c955fb0a8e54e0")) + (1853000, uint256S("0x0000218e79ccb4df7aa66299e34c082b60437ba322d126d1c43ce1488094f93d")) + (1854000, uint256S("0x000001a1c26acaf58a62686b9ea5d5fc3388dab548f13f3778ccb98e67f2a87f")) + (1855000, uint256S("0x0000008267ab7b175a6c35b485dc00a3f7bbbd7d9abd7add2fb7b18700f3b059")) + (1856000, uint256S("0x000045fb57c33a23707a79e677ed91f98d6453b12c691d1dc11e4cd8fab7a209")) + (1857000, uint256S("0x00001220281a3ab0c1b58f5baf3a139e0e83a3ae030324da91271c05a61db492")) + (1858000, uint256S("0x000005ae054d316369e33879ff06f8be124e937529e8996c4745f4959added59")) + (1859000, uint256S("0x00002f6f3fb39dabd224ebc2593f269d3f8bd7d16850bafabc24bacd57bc65fb")) + (1860000, uint256S("0x000020f6f29bea2745ffe0cadeeeff215e3052fe0b61f8e27f3e9eea7ffb779d")) + (1861000, uint256S("0x0000357229f1cd15b9c73bd8728beb1319b667e5f8d7e4f80e53c5996129935a")) + (1862000, uint256S("0x000043abdb964ea432de3823344d8416df9d196b65e6dc1ecb29b3077b10d3be")) + (1863000, uint256S("0x0000066961d0bac9d8824d6a86aacf90756a6819f6fa8e06067637bd53f8dc66")) + (1864000, uint256S("0x000025ca771ac2de93c1b8e14a489c7fd17fabf6920db63944c8a1a2e3b0a940")) + (1865000, uint256S("0x000007ba4e0a76cf035ca1feab7415434042bba970441cd33908f0684daa8cd2")) + (1866000, uint256S("0x0000195a1b3300a7ce08c1007b1b154a37ae335017b0ad797612820b38d2af54")) + (1867000, uint256S("0x0000346138f5f16777eaf844e9dcda229ece2792e86bb657bb415ed466a082e4")) + (1868000, uint256S("0x00000d804e712de8600a5036968b88e1dd6462f1cc9aade1a65dbc84160feabf")) + (1869000, uint256S("0x00003e8cf567a677423bfe17e6e78ff5a2312bcfa49dccdd2745002e31d78a62")) + (1870000, uint256S("0x000004043ce0bae57b6fba659cc0619eb55b7128c2fe14073e138c0b160a0793")) + (1871000, uint256S("0x00001b62d21a7ac0e54217ec176672ff143c133e43e10f6d6801fd84360676ed")) + (1872000, uint256S("0x00002e12f2f9151ed18972d6ae9931797b99f8112e07ebd66c2695f889e6459d")) + (1873000, uint256S("0x000028a8063bbfc5fea56dd32d01deca8851c310b0f4c0ddcf03c6d0d7aa574d")) + (1874000, uint256S("0x00001e900616919eaff18e32a70b9bd58e7804974b955bbcf4c8fd87f23f7687")) + (1875000, uint256S("0x000042759d29bffbc14fb85e4c35d07bcd9c29ceff2f16f87039bb5b33354eae")) + (1876000, uint256S("0x00000d91cc65f998daed963a6c14dccc918828ce21c057d0baebc7438f7b7a2c")) + (1877000, uint256S("0x00000dd7fe48dac8f3ebc20a8f7f27fff90325122a37be730c274060cf85f38a")) + (1878000, uint256S("0x00003542d05bf8418f2e326e531d581d1d8908952ffa08bdbf636670d0be3496")) + (1879000, uint256S("0x0000018c331b67f75e6b9ab4a8b518b62406abdd109c51e5616dc29f863354fe")) + (1880000, uint256S("0x000049b5bef92c9049093a875b5270ca10f6b4e1a77632bb614c989212e7f1bf")) + (1881000, uint256S("0x00000d9754cd6eba7ed279a2ec10ef8712e27ff5fa0f43562a6e20d057e5d7f2")) + (1882000, uint256S("0x0000264871227584908351f569784366e1865db17245474094f17c454c485193")) + (1883000, uint256S("0x0000107b42cc1727814cb9fbb5ca659332d70cdbd9f9f02beed5cc745aefd446")) + (1884000, uint256S("0x00003903f35677ce512364b0ff1ecc5f09f2ca5e6c180b878c4d9c0c5750f78a")) + (1885000, uint256S("0x0000247350c0e90303e9f1dc7506949586a0cf625de97f520d9c33d5b17a54e4")) + (1886000, uint256S("0x00001dc199706b60226fe856d7f6ff04f28014909a0d9a430c951ed6cfccfa64")) + (1887000, uint256S("0x00000611d74189b91643e1b8712d97aa81b876e6084af7cee912c47009ebe9c9")) + (1888000, uint256S("0x000005ae04bbf411e9245d2f2985fe2c3b8c467bb0e79717638eebef2a507745")) + (1889000, uint256S("0x000008ab7ea173bdb6943914d5bb8656a8c49c0931a592a4cd2fe2b28d65ecf3")) + (1890000, uint256S("0x000014aa765fdff2c4f02beb2c701f5f3d3c0767c7f56d1954f5cb84bafbd46c")) + (1891000, uint256S("0x00003ee7dfb83348ba1bb1f9c837ec9a419b0cb1320ded4ab715c3f30b476a9c")) + (1892000, uint256S("0x00001633a2b8813350d09db7975e30c9d8d28dca047858974d8b8ffb1bfd939f")) + (1893000, uint256S("0x0000331c39874a0ed303dacb360cffeebf41c0949ec438beeaa8406ea4e7cc58")) + (1894000, uint256S("0x00001e946060f2be27e1e6195684647c55f0661c0f5c187936314b968489c05b")) + (1895000, uint256S("0x00000c8726eba17fb5202907d053eaddb1049f490ebd074618ea971ca835254e")) + (1896000, uint256S("0x00003c13a4c20b9e003823d81a9f4bd8447f2f85fbff804a4161055291264e8b")) + (1897000, uint256S("0x00000929cea5c0a05ede1a81f0c016990e0b8cf5656e047f48d2e1f989b6b7b4")) + (1898000, uint256S("0x000030a0faf3ce2ec5a55f73f6888c64d05bb1826e37a9f08019a875ef0b6781")) + (1899000, uint256S("0x00003ad9a56c85c0da0e120ba4bcadea34ba3abbecc6ac3ebc3a04c9330cda93")) + (1900000, uint256S("0x000044711e9a4b2036ce4f56af9452c4833fb310707740e5ccd04ca6ee0b09c7")) + (1901000, uint256S("0x00003d8bac43dc90a53d919e1a0eadb74163d02102a0305d72d984167bb9e6c2")) + (1902000, uint256S("0x00004533403a1ee06ce3b223c5c5c88ab27fb161652a29f1ddfbce70dd63c2b3")) + (1903000, uint256S("0x000034048aa077d6c167e7b629be9b6a14676cd044d5cefb17d04b38a5a7e402")) + (1904000, uint256S("0x000001d77dc01cc435b1d7be959cfccbce81f9c30dafdaf78c15e4a2273ed80b")) + (1905000, uint256S("0x000040dc127aafdeaa1fdf14ecf0ceacf18d266ebe5c1030d5d5330bbe83fe5a")) + (1906000, uint256S("0x00001cd510eda6996237691fffa8cb3d1d6ee7eaf1cc5561725f4f00af1f7de8")) + (1907000, uint256S("0x0000378ede679d4832429be7e974f98c4163b6544fa4d4283a4ff89e90651b07")) + (1908000, uint256S("0x0000254ebefeeaae62a3f776cb1983e381a1918e5e99047259e0e94f453b4aaf")) + (1909000, uint256S("0x00000dc70a54c85e18cc7cf91da60d1a8968a13e3ce7777f86b320db43cc1beb")) + (1910000, uint256S("0x000041a3c6506cfcf05d18100e23805847f8056da0862274c99b73598f814efa")) + (1911000, uint256S("0x0000174bf4e2c808999b471315a556e85cbeb824522d4269564b8e0583eeac2a")) + (1912000, uint256S("0x00004eaf2785ba66c24f4987089f0cb81a6b18ec53d021ff171376e8c40273bf")) + (1913000, uint256S("0x000046262842bad8eca53a75c9620001f2f03c388b05786857671fbf7bfb0382")) + (1914000, uint256S("0x000018d6e1b158eb149da42a0483533c2a4e9bdb6a1b762cf05085bf129462a9")) + (1915000, uint256S("0x00001412b425773e544fa908f72bc1391a446ea04c1f6f6b87031b89143e9b51")) + (1916000, uint256S("0x00003e5b28bd7bb944b0aa1271710ed947fe08fa9d4d65db183c4877757b8a72")) + (1917000, uint256S("0x000021ec26d5f609bb0ef14d0c37fd9f4dea255568bb43be612b02350d049052")) + (1918000, uint256S("0x0000534a2a114b1936a5c09d577d50a8f585b949d9913f751e133a297ec0e4a1")) + (1919000, uint256S("0x00003e7fcbad89da256a2aec7f0e6accd9f7f611b2445be76c12ff7d0c415054")) + (1920000, uint256S("0x000042010e0a2012d386e840cb217ae2565b9d7550ba8040a7621a8490127a26")) + (1921000, uint256S("0x0000277d86854829392bff4d2550615e971b8d1225c2bcf029f234dc7564f9fb")) + (1922000, uint256S("0x00004581cfb8ccb808b7b9630a7ea0e81e3bc8ea0ce3b4e135e4b48d72e86999")) + (1923000, uint256S("0x0000406bc6348600852520c9d19f8ba3f53cbaf1f46ca0f1d50a558f4bb3efd6")) + (1924000, uint256S("0x0000463d010a48ec93d7a33850260189cd0d02cdcf918e895241bf581b0eb8f6")) + (1925000, uint256S("0x00000b5243ed59cf73dabc55a8408c0b7566697b2010880197b02ffd22b24fd8")) + (1926000, uint256S("0x000037463499039725dab4659575bc67e9385e67eea8072c9aa8a76eb1ebc5bf")) + (1927000, uint256S("0x00001d41dd45ef6e603e1cea195862aeab747fb04a48a49522c834ccc733d07e")) + (1928000, uint256S("0x00002efd731aeb6adbdabd47609a84bf76b8b02aaed4155259f0c601740522ed")) + (1929000, uint256S("0x000056b643767b21ec46452d1ee590e00b5e404081e58fcfdb502611209c76e4")) + (1930000, uint256S("0x0000260f1170ff140086dccdafd86778e336caa8cefd59432168027d5172de38")) + (1931000, uint256S("0x0000452318831c8422a302a6c6f2772902f9391b1ad386e0a4eb52ea7c7a0124")) + (1932000, uint256S("0x00003b3691def9da9e51607d847b7195b1e878201a10c858e594cc63ce88c3ac")) + (1933000, uint256S("0x0000538b384a4444c1d6fdcfe84e6ea475e4ccbda5b4042a6fd7045a76aaaa33")) + (1934000, uint256S("0x0000208f15a39656adba456d8d28a7ec82f9c996bac4eb86b237bc28129b2bba")) + (1935000, uint256S("0x000046fd6e7016f7a65556095913b83b5b280c52eb7a924d2c280bc23141947e")) + (1936000, uint256S("0x0000184e94f1a62838733a0145d3e8906b194a91e4b3f0c62518ad848dc18f79")) + (1937000, uint256S("0x00000c91e30bfe354b48fe96b38cff8e94f5583e3b786204cef161288cc0cfd5")) + (1938000, uint256S("0x0000097189b091bd3552390cf1041a4333843deb86d681ac3c5375f9b270cf66")) + (1939000, uint256S("0x0000156efb44b4415b9ee78fa8a401d6ce0a5d50d2598fcc309647e0031ba93f")) + (1940000, uint256S("0x000003e23107a3e520eb2c6526790c2371f97081b9b282d1eba8cdfef27682e1")) + (1941000, uint256S("0x00002b7294d809ca65d6564aa66f5723431797dfbbed5b837ba259407a799df6")) + (1942000, uint256S("0x00002baa77a84dc632be42d95e6ccfbf01621b39520923f167de07de81ddb9c4")) + (1943000, uint256S("0x00002dec6c1fac01ab93da6c7ae01c70611ff228c103d73fad5868b1e31ccb9b")) + (1944000, uint256S("0x000001a5bac20e7f77586c043d04cc6095ecbe187bef7a47762974677d864972")) + (1945000, uint256S("0x00000e24a76e442d0ff337b223ebdba212a4a3c34ba0a76b70f617e2ce09fcb8")) + (1946000, uint256S("0x000032c801056d06025aa24927c9b36193a41cef583af858d4ea81df1d27fd73")) + (1947000, uint256S("0x000015686f3c81024408cc5dd1c456a90bd42946351c66983905e76685708a3c")) + (1948000, uint256S("0x0000035806b5a58010621a3d54ef406b479b332e126379e0267be97775358ba3")) + (1949000, uint256S("0x000024a02fb74fa9e93b7117b000fb78a59365f333de41d2dea533d04399ca8a")) + (1950000, uint256S("0x000021b8dbecf18fb352fa1ab5e4ab191b634defa59dc20176bc300e9d299a74")) + (1951000, uint256S("0x00000d1299498e8a6bc95078ad40e1c413d751bcb0fc20b666627293f6cf41b4")) + (1952000, uint256S("0x00001712fd4d2a211329ff640bf2d11aa81676f653d1de24a1106ca1e394a04e")) + (1953000, uint256S("0x000002762a13ec9d82e53fee25d3fea52c1ab41871f58f6578ca12d5a476962a")) + (1954000, uint256S("0x00002b263fee7a33b8053aae2e923bd374afbbc0e9a291496f503b289a274997")) + (1955000, uint256S("0x00001e88d33b934e2a8c3ef95c82d0585277bb565059e7b52ee4f52ee7cff07e")) + (1956000, uint256S("0x00000e07cc4c467355df9a32b0abd26a1b3dc4c903c9a21ec2b4b0d80a39d876")) + (1957000, uint256S("0x00000f6648f57243cf98dbebfe364edf53a13851373134b60eedfb88c8cd07bc")) + (1958000, uint256S("0x000010f64b007e067602db7b6e66115bb3b6cf8c3b04927b2aa3e64ba6183a5b")) + (1959000, uint256S("0x00002db39aae5a2acd7d39f38113b81ac1c4a0bb2393fce368324d8ad47cc4ab")) + (1960000, uint256S("0x00002ae5ef0edfe28e4dbab70c9fb472f4f2e23b884ec75352d39fc9a0f8655b")) + (1961000, uint256S("0x00000ea53b10fcd407f856511f8e6ae6b561cdbc649d4ec15ac8a456780d12fc")) + (1962000, uint256S("0x00001bf74750548084698e0fca101fc822240e157f52b60494ab882324024899")) + (1963000, uint256S("0x00000505629b666cf0a852e0c43108c68495f21c6090c8b71ba7fa2c17c73549")) + (1964000, uint256S("0x0000230bec0cb2fb13bcd7bb88e49ceeeaf0194728d92cf422b23562e771dc78")) + (1965000, uint256S("0x00000f515a1e5b920265b8137b2f98cc62c25585fedeff5d7dd5ef098f50aef1")) + (1966000, uint256S("0x000028d7c423aa50317bf81d7ea2f71c1ad191caeb51d37bbe57695c64d99adc")) + (1967000, uint256S("0x000030c18c1fa99d938f725d5226af38edfc19c66b243889dce63935f499799a")) + (1968000, uint256S("0x00000ff2f70b708f061bc4b4def956fb7adf4d95d5fb5aa6634dbe5005f2c4ea")) + (1969000, uint256S("0x00003088274b890ab575b9408f09b503f2ad09aada5155ca237f64498fb02f8a")) + (1970000, uint256S("0x0000279c2bf4f1599442a9594fc6800e867d529ac0d115264bffa3fc7d3f9854")) + (1971000, uint256S("0x00003080bb848845451e134f8410a16b6455cfcacca6187b833b2baea75170a8")) + (1972000, uint256S("0x00000062c67fe9e5905c549116b733a6367deab62b7e8a718d21e45aaf197182")) + (1973000, uint256S("0x000020153da6bf183ec8a0eb1ae599cc15a8fd4bdaa2bfcb8f6bee4e3e151f87")) + (1974000, uint256S("0x00001b93b8a8fe04244d14c5ad9ded58a204aa9f27da1623d90fca875b35ef64")) + (1975000, uint256S("0x000032c9cd323840737523738ac99ab03976ce8d6e3950193c8c517844a99b01")) + (1976000, uint256S("0x00000af53b71667ba7fe37e0403a29e23c1d373a7fdefd0295e5fb5023d77fae")) + (1977000, uint256S("0x000005b67346b971721ae793799f18b25925805f9614e4a45490c54e7801f740")) + (1978000, uint256S("0x00001b598193bc60a48a7f2f14f9119c2fbe408a50d352b465f71c55db3f2b27")) + (1979000, uint256S("0x000007a91095b5a1a8d0ff845f4c26ff58f23da8d091571d99370a4f61438aa9")) + (1980000, uint256S("0x00001f8a03b724f540d4b43e7ea872e350624845bf97a5ee405a6666d59bf265")) + (1981000, uint256S("0x0000236bc89391ea1ca45fd57ea7e1431b6cc3ab6da6cebc482096e59b9941e9")) + (1982000, uint256S("0x00003e3726a84f4fa50b0cc98830252d7a472e698eb3692ed6c7ac099ffce3be")) + (1983000, uint256S("0x00003048d056fa613d86179b3471482e9e70ba2778f9bdf003c4042fd527a666")) + (1984000, uint256S("0x000018bae47550289ec566b22ab5d421c43884a509fb44321fe86b6452069004")) + (1985000, uint256S("0x00000778d56dba646e821ae7bdcef99f086f17a4273af84ddfa51d5e4bf41494")) + (1986000, uint256S("0x000008466c036292b04b633cf44d5b4c545c6afc127a0b496597955e83ebc004")) + (1987000, uint256S("0x00000ba45f259aba2610af1482fb5ce1ddcf4b06e25c142f26ea025a49e04142")) + (1988000, uint256S("0x000024aebd93d9f185798883599c6dfc8e21fd96c38b7a94d9afb81967664409")) + (1989000, uint256S("0x00000494e3aa3076c6826c8c58673c8a5102e6e3af73f11114756d39995c28ab")) + (1990000, uint256S("0x000029a2bd9eba59be028bea999c261cac695417d12c425d21884475d4b1703d")) + (1991000, uint256S("0x00000dafd79082f2564a6e159fab99481cf0c964be876a52ad41a7f31b9d7c27")) + (1992000, uint256S("0x000048ada425d3da71b93311d60ed661d060436374cad7ec426fa86a073f7758")) + (1993000, uint256S("0x000047ec61961bd72cfdd954a117a0687bfe55aad747b46ff85f52a3cdd579f9")) + (1994000, uint256S("0x000029861cc04ad23a773b900da0a55b5e2f6e139deb7ed5ca7bc703d57919e0")) + (1995000, uint256S("0x0000116167475f835d109673469c2391b25866ce4978b1035fb8ec4eacd60768")) + (1996000, uint256S("0x000011d2820de15add29859641228a9fa1b697864db601d49200d21b1e62b2d6")) + (1997000, uint256S("0x00003c099fe6dfcea2df78d1623881699f6d15060f0e6a8a6f52f09cec6d07c9")) + (1998000, uint256S("0x0000224f7e25960d972a7585711a3d5b52ed9409f5d4ec848d0bca6b9ce63445")) + (1999000, uint256S("0x00001bbf5cc16ce7062d456e4ed375e7cc0e0b57004c974e813e69bc5c7dbe1f")) + (2000000, uint256S("0x000003fc9909851c4b887dff5a36ed039efc20eb1e682967f72a1074053a0b27")) + (2001000, uint256S("0x00003bb4f31f63d0987aea2962cc4ef689c3e82f941d1327e9b99079e22543f8")) + (2002000, uint256S("0x0000273a9d64245c139676120efb551de8141177de5227ae9b501b479ac1abbd")) + (2003000, uint256S("0x00000db99decdb8097344e6c5478a7820452c64825fe67a440595b1ad24fbfcb")) + (2004000, uint256S("0x00002338ca444e864b4185de4b3ecb050cff49328a325008d5ecb447a553ff89")) + (2005000, uint256S("0x000010896b3719a6bbb1ad5471ec17784bfc58dfa83097432cc29aba04e4ff68")) + (2006000, uint256S("0x000012581ee39f4cc4db7556463febd40937e89e064fa0c60c0a8035342c54f0")) + (2007000, uint256S("0x00000379bcf702208d8f8d5129d887905553fad9b6d9483d0740eb6850d7473d")) + (2008000, uint256S("0x000033e8f3eafd99a8f0cb98e43b203d6bc6cb2787aab82c088aa6c2b1cbc9c7")) + (2009000, uint256S("0x00001041a5234a74938637c0b6f24297cf76ab023734d7bbbd2432e291a4a4e0")) + (2010000, uint256S("0x00002688aa0078409e160b6cd8fb1679bd5939689aa3ff4fc534fea69a4989bd")) + (2011000, uint256S("0x00000604d5039d6acfb228edda87fd784cb35b287b9209945bf67c6615411465")) + (2012000, uint256S("0x00001c8d0f5a8ef4f6e9ecd9328ae515cb7151d67c72c28fb0d53093f4999519")) + (2013000, uint256S("0x000035d50354d90b3a0d2d8c3d03ee0787280eb164a1f365ef1171709fd15c6f")) + (2014000, uint256S("0x00000ac9ff011ae6f4c8f6c35ff2d714b65097c842b395f9e1982cfe9b511740")) + (2015000, uint256S("0x000006a6fb084695f11b347283916a8015b3acbac57c6f91ee2221e074ec05dc")) + (2016000, uint256S("0x00001fe6f2cd3f98fb3341435c8e4e46c7861e8af359aa30ae15cef99303d731")) + (2017000, uint256S("0x0000287dc113b2e87d5330087dd286b64e2f71795fee4b770153aec45d3e33ea")) + (2018000, uint256S("0x000010834e3d3f07e4f08a0d6d82824df704b7d7ac17687eb3df3e7877fa82ec")) + (2019000, uint256S("0x00003133df0599051d42c8cb70f9a7dc09bc296535bea26fc14433b4bda5746a")) + (2020000, uint256S("0x00000d372734ed0d800fe00c4310313ab033ae4536280aa416391764a68ea6b2")) + (2021000, uint256S("0x000046fc9a6c226126f5caf58c9831339c9ce96383cd1ee5121dd15a86b1827c")) + (2022000, uint256S("0x00005ad031b1fa79df85c29e2da50ac58ee26d86855b10e462e5da90740f39e1")) + (2023000, uint256S("0x00005702f5687ca6970e174beafa61966e769618d38de10b45836263e3045728")) + (2024000, uint256S("0x000050f5b8fb92b83dfcbb3434a28c4152e814cf63061d5fc1a177e6bd828dc0")) + (2025000, uint256S("0x00000f6eec4fd9b0ed717eba44c279e8456cb77e0e22c1b79b110ba749a477d4")) + (2026000, uint256S("0x00004758e55fa39025ce50e5348ffd32a06e2a543827c118f2704720ec59aeb3")) + (2027000, uint256S("0x00002fd61bb1a33a542a1117283ce26781b9268d69105c5ae029fb871b549f43")) + (2028000, uint256S("0x000058fe114c8d2d96dcae14d9fd180f04f7715339e9b82e6f45a40a116ee007")) + (2029000, uint256S("0x0000536617db60262c22ab00b52188d98f9875f59636efd98ecf6e0017ed4781")) + (2030000, uint256S("0x00001355501d7d0129ab267a1345f0f70bdf51b3cd5e50b9b4d78702ef87baa0")) + (2031000, uint256S("0x000023878618c37ce31743c620e6c020183b357bd7b2344c3fce31b4cdb302a7")) + (2032000, uint256S("0x00002326e6572b797e622bbc0181f031b41d7f3dcad8299aad900739beeb5b1e")) + (2033000, uint256S("0x0000251e0884d3f8125f426e330b6688245663ba85bd3f54000283b202d5d3a9")) + (2034000, uint256S("0x00004e047fbd14ad01f80e8dffafcb5e4b2cdb78a5643dd765a2a82900e0070d")) + (2035000, uint256S("0x00003b2ff98834444b7319d08ffcf15fd5acdf808d06237b25a0d4c032df9c76")) + (2036000, uint256S("0x000056d2bdde5f2e92bdf41c50d17ef6158a05805162924e9850ee5c5f6f7744")) + (2037000, uint256S("0x00003a5a1234fd3cd1b711bbc1b5338230733990c9104d32941429e7b0e8dac0")) + (2038000, uint256S("0x000035d1bb3a9f5a18434b5c4fedec2aacc55bba2dff9fa7aef3c3631f999eca")) + (2039000, uint256S("0x0000475b187bd302a98ee9a1b90a8c109de57c9812d61a9b15c78c23148457f0")) + (2040000, uint256S("0x0000497976d382da22e1848624d3e2129b5b2ca52ac36674494c5dbafbeef589")) + (2041000, uint256S("0x00002170387b8d705bee19bec26f01e2d1500cacffc65f5636e77853ef846e82")) + (2042000, uint256S("0x00003070b104804b97ddc65bef89c28e70b7db7feb0b50cf15b02b093baa6117")) + (2043000, uint256S("0x000035e0dd10437047b7dfd96f0c86636ba1bcc2ebfaca8bf88ae26aad0b7c9f")) + (2044000, uint256S("0x0000554a6c404edcf9fc492b912dd969907e8e6d85aec1cc71271bb6ba09b6e3")) + (2045000, uint256S("0x0000187c32831c813e91532c943a43b8cfa43dcc612b32939d80e59959e0b779")) + (2046000, uint256S("0x00003628f47776d694641ceb18f62a2f279c6fe4a04975bb39ddce5d28c1e2e8")) + (2047000, uint256S("0x00004aefcef0fe396a994b22db4ace160afa9d5958428947dea6bc769f49b5af")) + (2048000, uint256S("0x00000db2187236f2ae9028ee31a0fc696d1b075a9b79acc7a4721be1b6c121b6")) + (2049000, uint256S("0x0000354fd10c5fb2cdba185b0afbc11aace14dec5efc9069e93f4a3ba5df58dd")) + (2050000, uint256S("0x00002c4d7ce579578798ad759b01cb05a429cc936eb638d0325021cb2c708f42")) + (2051000, uint256S("0x0000595e5cece4307db06bf8557b1c86f8a2949562e794e51ae3e7a5b5174c38")) + (2052000, uint256S("0x000000456250a1e5732ea074b83a45f03ffe272e79daf09701dbc66e71c45e3a")) + (2053000, uint256S("0x000030bff9e35d7be9ea51f695759a4880b603e1cb6a61e274e2ce518d1a30f8")) + (2054000, uint256S("0x000017a0b47b69b827f961c6503f37fb7da5ad2e175bd60bd9429305a7cb7eb7")) + (2055000, uint256S("0x000047088afee483c26454d58243a5bcf5c6b27ec2a7c473167739f04799af71")) + (2056000, uint256S("0x00001dd3943351d84a0600316479713c366308605873de29ea4b7b8685244b85")) + (2057000, uint256S("0x00001918f2cd171ebd58e7068da9c7c7a58e6812090ef0b3f373802f19320cc1")) + (2058000, uint256S("0x00004f42cfbe2a70c1ad971116619b8977c7658720a1ab0a25076bb64a7076f8")) + (2059000, uint256S("0x00002c50199f0ef54902f0e47f00e5112144e55215779694aa859835cdb24c45")) + (2060000, uint256S("0x0000295db07b620d5282a7d9fa3862d76817f182e1f4a720e2f3d867bde0a43f")) + (2061000, uint256S("0x00005307c7e2cd7ef270b97cd1a4e508228af7d1911af262d8fee96149af93c3")) + (2062000, uint256S("0x000010cb0677f1898a4a253cd01562f80a6929e53ce037dcdd4a7ec5969f19a0")) + (2063000, uint256S("0x00002382e663f9aceeddfd534a4956d6d779b6ae0dccc516e667d2c17f257cb5")) + (2064000, uint256S("0x00002b31dc1a88fff4de3a05d5cfa578fc003cc474e8b45cc793aa4da3c50f57")) + (2065000, uint256S("0x0000400835648b6b4ca66b0eca3b74d035c0e68f710da18ea608a32ab6adf6fe")) + (2066000, uint256S("0x000036feb5ec70d429cd127f0e70331496839db4949342b4bf908892f6842861")) + (2067000, uint256S("0x00003819d7ce2d302f8dd875b2bd496c6a9d69fe4b6f8f69f911616c02bc7439")) + (2068000, uint256S("0x000016bfc4fc46720ba7fd168e7defa85eadab85af262d6cb2a6aa45b0f56e73")) + (2069000, uint256S("0x00003ffcec4951a586443bf478e5927780db46e8c5bb521c5acf0af16f8fc1a1")) + (2070000, uint256S("0x000006e7be7783f4aa24f15bdea567fd9e5eba0d0deca6f5bbe3a7b6fc140421")) + (2071000, uint256S("0x0000153bb015433092b069f6f5821a74f41fd901d1a1edc254b0619b6f93f367")) + (2072000, uint256S("0x00002195ccca2fa7386722588d69753fd713148d1098b9a4e625aa5ebd6f82cc")) + (2073000, uint256S("0x0000011a48c59dba7653436f9f09051c86440a8faae632ba3c239539428cbbea")) + (2074000, uint256S("0x00002a26a3f5985795932c7f02a865ec6f57270816709163d5f1a452fcc253ae")) + (2075000, uint256S("0x000054c73f635b3b42bd12d7530347661a4def5f74bbf9898185455633a1bf57")) + (2076000, uint256S("0x000023c5c7195d2eddd855d9854aac2d9b4e38b1e34f4d186e4031cb28f55cef")) + (2077000, uint256S("0x00001f83f74daaa524363a2f6cc6acc17c87688114a59b0f6727f434947899da")) + (2078000, uint256S("0x00002cd2c9d478c015aaeeb8e80a76c0a4d3aca28260712b7ebce390387dcd98")) + (2079000, uint256S("0x00000f9beb4c6363540d263084a18b2bc9edeef945cc888ea5f40f6ea46ec68d")) + (2080000, uint256S("0x00005443c0215ff5403ed505785af8f38cc50a2733761c2dc145b270b4c944ad")) + (2081000, uint256S("0x000014a5baedb0e02df6cd908c4eaeb3815b39c47267ba4b6dab66f235bf92f2")) + (2082000, uint256S("0x0000170a5930cef7a33464c29dd352d8d1a78cc69d30506e5928b5cefea2714a")) + (2083000, uint256S("0x000025a7e98ea21c13a9bdb66ae1c540d7e7e6901f5c7925d7c9c822d80dbd5b")) + (2084000, uint256S("0x000000d7cf5c64779d3de6fc66ae66861596f7fe19b6f13b5ee88499501d8d1b")) + (2085000, uint256S("0x00000d05247fcbca8097bd6e92f29a6aef25770632df4c4fb0bd3da11c565b91")) + (2086000, uint256S("0x0000068a30d125bb4d211ce6e6e63b5f0b36215c99ca8992fb8b9967ccecd082")) + (2087000, uint256S("0x000025c9ecd2f2a4ef13eebacfc18f32f9bcdd16d4aa81939af642eff50447e8")) + (2088000, uint256S("0x00004f2d011295dc96a7c5e64fbceb5bbd99148af05626546cbc5ea4e139c9b3")) + (2089000, uint256S("0x0000196e7df0ac7d0c261831dff607d6680231b5b8f20943e912787bf8ed5dd9")) + (2090000, uint256S("0x0000336bdf163dcabe6f2cf1504e6489c578ff6e9ddefdf091da4a5f898bf1a8")) + (2091000, uint256S("0x0000427b2f3cdd9be1d13f111db5899bfdc0ce2e3efcd491f56510c8b5a1f8ce")) + (2092000, uint256S("0x0000521471efa518b1f3723893994554f1fbfc2a820b1b6436b8c222eb2dd4d5")) + (2093000, uint256S("0x000024e68f152106fc6beb96feafeba766f50883189320b2866e5fd90932e3ab")) + (2094000, uint256S("0x000038f50bc7bedb0a7cf50f2573726a8a8260512f2e7a240f09db5a058db9be")) + (2095000, uint256S("0x0000344d8295373e1ffd9d9494b05c206a301ebde6d649e1445e6d44ef2fecbf")) + (2096000, uint256S("0x00003f0716b3dd36c47f206f0a9cb8c88d12678038deb3f6ff31e495a0230784")) + (2097000, uint256S("0x00000e8b7d4fe75bfc7c815216048399023d52301652c3d0985d1e6c2124b3a7")) + (2098000, uint256S("0x0000075c184357df685672023f623e8e566793031612c6f7658974c3bac670b7")) + (2099000, uint256S("0x000016352acd469d9e3aa35c3851eea7792ec70a8d7db60c4b6d02dff1177a31")) + (2100000, uint256S("0x00000a0e32f09b35098f22aeeb76aea01c35479309900efb04954b61f8b7010f")) + (2101000, uint256S("0x00004e5d521db363e469880a2710c3003228075b71ba9ed90c0cbf0dbc3e2b07")) + (2102000, uint256S("0x000050a68ce14b661803752ae4d6891cb3984bcfe7f887e216a4ab55ef2a8851")) + (2103000, uint256S("0x00003f6dfbdd2e3f60af5c02b4cfb4962f33fbe6ad7be84870530aceee263860")) + (2104000, uint256S("0x000000fb21378f1268633047139e512d5ad810d0391442294d53abe1abedbcc9")) + (2105000, uint256S("0x000014810dc3acc35f02dc476a1c0fd5cadee801d4bd5cdccd82a179f7683211")) + (2106000, uint256S("0x00001f0a35271990d6ec819674e55bcb9e1deb733b5849c030d5d862c3fc6fa8")) + (2107000, uint256S("0x00004cb77ed857aa24e56128ce62d78429feea548e023a333b90fd7a5afc0b02")) + (2108000, uint256S("0x0000093ec4d2688834bf651743884e3600ef4dcd6b108ff4b22d02e943357f3e")) + (2109000, uint256S("0x0000163827d086973e9b9f7b32b0e1382202ecf212651a5e56855c4be9315a0d")) + (2110000, uint256S("0x00000b05f05abf620f12425d13c5479ddb1f0d11a21bff33e879aad584741ffd")) + (2111000, uint256S("0x00001398d5f20e28eec8fad11bea224a0002165e2dfbb3739bf77a9b90629550")) + (2112000, uint256S("0x00003fba550235d06d60030064aa0a2e6b4d0f8a785b96acf85fc046fdad7d0a")) + (2113000, uint256S("0x000004467be0c49b53eb97ccf4f90bb32fb8ab677115f3eba34029dfcf917788")) + (2114000, uint256S("0x00000d34795ce6c25090db2827d56bacb2b6a3514ad2ff48b818ed7b923ea774")) + (2115000, uint256S("0x00003103f157efb85a4e3e68b99e9f161f8ba8fa1d139b107fb6778726346506")) + (2116000, uint256S("0x00000ff448278ba8f8b6412c3235bd89ab88b17312245ec4dbab9ac309188af5")) + (2117000, uint256S("0x0000231a443c8c304a183d27276733765c77a6b20ba0c5a7fe825d3ef4c376bf")) + (2118000, uint256S("0x00004fcff6d8d54b5cc410b342e0d6be159be6093430578ac3d08ed649bad735")) + (2119000, uint256S("0x0000060f20cfd6f7c919f5d15db3be2214094bdf7f6eaf15372c12c46f58cfae")) + (2120000, uint256S("0x00000ac463ee0b4a2abec658b98365a03737761b9492c83148bf54868ed10027")) + (2121000, uint256S("0x0000185b3050f55d25929ad3b8b1f1cb3b8bdf378c85f587eddf50be2c372768")) + (2122000, uint256S("0x00002d0a79a8330e665d4b12e6acccc1dc90e3ac45f74e0a8547649b05f37a7b")) + (2123000, uint256S("0x0000236096c0678892ef04d04df2136d17e1204a9d2d60e871a1dcccc5fd1ac1")) + (2124000, uint256S("0x000016ccd27f5c845286e745102b4ebbc4d512923b9aa8e7365274d7a926bed1")) + (2125000, uint256S("0x000018a0cd81cb71946af74a1cb689e62910c466af061fabdd551244da1637cc")) + (2126000, uint256S("0x00001da7124f72ee5761c2f98b3dc6781d321e26f31282beb1564a854e028041")) + (2127000, uint256S("0x00004353016d18e81e1283758b43e880cb339b16da59f82a4f103198864c2833")) + (2128000, uint256S("0x00002801530ef81113c0aded0ca9c743ca6b9c9329bc634ff7fc4cfe247a978e")) + (2129000, uint256S("0x000044c6fbae87d4b8ddd42075124977569543d7809ffab475670f188be5cf59")) + (2130000, uint256S("0x00002a7481591850d6f271c6e9cce6e9e9d5aa72a66dff5cacc0b2112b84a184")) + (2131000, uint256S("0x000044fb548ba1d422a70fcaba5f2c7eeb613ca3cba920d2dcc6a7487b0992ba")) + (2132000, uint256S("0x0000285227dd9094ec438d9d24c55958d9be1b11066f9ea48a4813a83d4021a8")) + (2133000, uint256S("0x00003214bfdd64768dcf252d4e2a96311f61534cd221d5c5f28c6c84a9763bb3")) + (2134000, uint256S("0x000003d734504c92481d97a593e624b44cbf53941697e7062df5379997bb5ef1")) + (2135000, uint256S("0x000013dbf61afbf16ba18d2db73dbf6e44efd7e9d2cc01365ee6a3462a63b15e")) + (2136000, uint256S("0x00002a283123ec89f3d770558a0e09e865e94e83120c129709bbd7e11efb3f6c")) + (2137000, uint256S("0x00002571251ad5e365049aceafaac9f4fba2057b2c38b2e9a598aff2c21de276")) + (2138000, uint256S("0x00000923ea9f77bc225eb7cc961fdb29c1177ed9689fa0f37819cd36f91d940f")) + (2139000, uint256S("0x000008256c52c7c03d5aad41638e8976451962615f7b4992aa0d3f6bb195d9b9")) + (2140000, uint256S("0x000028262c696e8f1d36d289058a4894632eed255a1e3b0a413322b53735af55")) + (2141000, uint256S("0x00004c477aee0dc009fa905af1df8597bef90935111e9a83b491ced4e82ac4c6")) + (2142000, uint256S("0x000047d25e1bf049136632c508e07e1160f594d771af117d805c8a43f0898d8d")) + (2143000, uint256S("0x000042edadfbb725479b328ea1771e54dc1cf267a15929d4c49cde52604e0070")) + (2144000, uint256S("0x00001fb62bf5aec823606242fcfe2362f54a05af8fd9944eb58d61df2654dc8e")) + (2145000, uint256S("0x00000a2f7a081dab938bcc32d9f420fa7737635f3a5d4fdc734a7e67f9efb412")) + (2146000, uint256S("0x000047c141583426e1a9bd9b1ff4895087f9e5fe85e5c26ee2754011f3f24c81")) + (2147000, uint256S("0x0000294ae2bb8cd7ddea7dbe6a2403f0154439be1f386503b5345dac14f82d3e")) + (2148000, uint256S("0x000013b354fbe685cdc869dd22a59c9ad6664f3a2cbe0794ecbc0239b97f3ab8")) + (2149000, uint256S("0x00001e31a5141cc23a58e3364dd02c3c659d2dd51720f12fed255ba858228ffa")) + (2150000, uint256S("0x0000117dc7a047855b1d35c2a59f62de19f8a9a1f08c7e481c00b981cd69ef18")) + (2151000, uint256S("0x00003af4c94ec4de372297c32ab75528c0be174ba731298026365096b020c4c2")) + (2152000, uint256S("0x000043588b5cc1a4f7152c75190f15168728418afd73365b2f0f4fc5fbf3c5e9")) + (2153000, uint256S("0x000021d981e26479db6bfb2aba34f8ac7f08843d255066b1ee07bc339eb2c35a")) + (2154000, uint256S("0x000036b0234536b6fcb430ca0ca67f4089174e56941ffb8ec0dc28cb0b138117")) + (2155000, uint256S("0x000039675c94676dcc0d5b5f3e52b97654d2d9a399c29931173d2051bfa52d5d")) + (2156000, uint256S("0x00001a0f410bd5878dfe58675aeb19b682cc7d800ceeb38253ded4662bc8a97f")) + (2157000, uint256S("0x000016309f790818aa081128b241342ac457a34ea44ca2a63b5f093254743784")) + (2158000, uint256S("0x00003f3e2e6f7318b3e94bb8ad9eac1b4481c85cf00c2b26a44bdbe763c8d31b")) + (2159000, uint256S("0x000025120ffeb838d6984766acff6e119be16aea4848b470550556cabb551f1a")) + (2160000, uint256S("0x000002f17a78820444246ae5c27302f2a597e34097a95720128488f70980f618")) + (2161000, uint256S("0x00003bf4ca73f42e8e3e215c006fa759befb6b43cd5adf8512ca3a2160946b08")) + (2162000, uint256S("0x000041eab9f575769b46a53be426cc226e55943f114b2117dada7f857c3bb7a4")) + (2163000, uint256S("0x00000f97f7599422d669275342938a20509352a05ac4ae98baed8da211f23562")) + (2164000, uint256S("0x00003c55c4ebe0dbab9b672de6d78777d6dfcd71df3e32a27d182b338c9ea474")) + (2165000, uint256S("0x00004135c65d6d027a62256f982a17f4615bfe55054872be8c66d0777d82e655")) + (2166000, uint256S("0x00000ed570fc180bd63ac6a487d1a6f63fe939b5e442f5f12b46c5fc2ff54e05")) + (2167000, uint256S("0x0000213e87e9a5419f498ec901e7ae1223003ddc807aff03e6f820b9aaa3efad")) + (2168000, uint256S("0x00001e46cc6da6efb8e8a3b6382f05eae303028396f3ba940fe589a877011ab2")) + (2169000, uint256S("0x000035221b8df3a8e5f20487fcfbefccbebcfee7601749ae0edaa599bac774ff")) + (2170000, uint256S("0x000027c5b23f6f32442bc7f8e3d9f02c9dfb7ac79325ea16e6edc197176aea1b")) + (2171000, uint256S("0x00000afaa05b374563fd0d0d82afdfa5f19614d44a7523bcb1b0b3e5290cce2d")) + (2172000, uint256S("0x0000372688030499969b033f8389aff6d5d53e85167b870e7d5c1d59cd1aae4b")) + (2173000, uint256S("0x0000016e744ac184a9028fe8f67d2b6202403997ae43891bd05a23eda4a54fcf")) + (2174000, uint256S("0x000056bd7d225778107323aff75b9d63e83393982da70351ff9b5c8383e4ec53")) + (2175000, uint256S("0x0000126b981794669924636392425da121e91d7266862d411deb9823dca4171f")) + (2176000, uint256S("0x000013023cd55b494f7e7a17d4dae305997001944a8398f5846fabde0cb307a8")) + (2177000, uint256S("0x0000127b68f0c38a3af3517184d52e47d2141741c3797612db1b3cb806611165")) + (2178000, uint256S("0x000002b9d569f8abb78dad22ad1146bbddedf24c469108c7cb58185a3a94a5f6")) + (2179000, uint256S("0x000038689eb58b1c6fb96bf629b51c595f21f4b022d8a0f756f9c0e4a92c2847")) + (2180000, uint256S("0x00004aa190fa6fa7e06f8c229b9c3f817135922767addc909e93052c4aef9e95")) + (2181000, uint256S("0x000042364987c5c5e6d1ae7cf2d149e0d41965697e7faf7b39b221273a6651c6")) + (2182000, uint256S("0x00003d89a24de2bddf7b3c3e066bd2ac93a794350722ec7732a757e9155cef69")) + (2183000, uint256S("0x00004b1fdf4c7c9f165089f53f8026ad8fcb3ff6456d4af621fbfa7bbbd9fc92")) + (2184000, uint256S("0x0000404ed2383489626e94c7e68f9c6a1d6adffe6a3b4cc34a10ce6d8b31629f")) + (2185000, uint256S("0x00004440fb4e64e60c587f59cd86dac3ccf8032856ead1cc89337e70547b912b")) + (2186000, uint256S("0x00003010de40802af7dcbf6350b79c2bb05604e81677ba650c475e49d468d58f")) + (2187000, uint256S("0x00004ee1c25fc639a17ecb0c78ce69eb28995af66c6fa7a79ef12a9ae3eb147c")) + (2188000, uint256S("0x00003b4a947e414c803cf90dcb6a5af1cfc6787b42e60857d97f94f81c55d3ff")) + (2189000, uint256S("0x000005a6e8cb330a998f0445cf1c12e3eb2268b16130b7e99eeba8256f7e56dc")) + (2190000, uint256S("0x00005004683702dde682956fefaf447305f943463df5175e9c97a0a30124c62a")) + (2191000, uint256S("0x0000269af38b7671a30192277d407f75c0783f6c24ca2e45e1de67e508a682bd")) + (2192000, uint256S("0x000010363d5c09b2edbe3d9e442d86f17018c4ac71c468857450ff8350bc606e")) + (2193000, uint256S("0x000003631be3015e740f3dd9ef416d0175c8926ef6d12c10b53fd7c86e2eab0b")) + (2194000, uint256S("0x000003759e964af8f840b9a6702e3f710c1f322ae5fcd414359519c280add83a")) + (2195000, uint256S("0x0000484480bade13f5e01a6d8a5ba37a543535affbaeb682a093de1edcee6c33")) + (2196000, uint256S("0x00000b211c753701f7f9e032242b16a1a16f3d3ef0fde37504324fecc71feaab")) + (2197000, uint256S("0x00004ac48eeffd5cc451c51a7046f90154df614a54c078b14b4dac2a23608502")) + (2198000, uint256S("0x00000ab044f3abc0cab9474e61c97ef61397e46cb7c239ccc019caf657017e45")) + (2199000, uint256S("0x0000530de3d6f535471149e631d9910673ad74e2899ef5db69f01a92968d1d4e")) + (2200000, uint256S("0x00003c75b78e2c8092b05bdeb4d53365125bf77bbc06e1e76418ba8f85845fb6")) + (2201000, uint256S("0x0000267336362cd45f4d049614945c62463c8d7847acebaa85dc4624bc3888d9")) + (2202000, uint256S("0x0000028c2cb0a72a727e85cf096f3f42e1f55544cb4275c3fbf645196056e946")) + (2203000, uint256S("0x000012f50eaf3b527892e3a079065406a1053133d911533e1c0981db1d0a4233")) + (2204000, uint256S("0x00001059513124f430aeb0aa9032bb414ebed1924ab16a7f3cff5681ca1bc650")) + (2205000, uint256S("0x000055e8070bbab66a01726cf981bd94102e55d4c3359edee8664720460b6fa8")) + (2206000, uint256S("0x00000139b310a46c3eed7ef7b2e012ff407f07bc32a84bfe94ecc778aafb4f82")) + (2207000, uint256S("0x0000245147d4b062f0ada83e093c38e98118168acb6cffb734d3564ec583c193")) + (2208000, uint256S("0x000032a0efa9302c36d353869ca237078a4fd1bdd1defc1307efe8a88895a5bb")) + (2209000, uint256S("0x00004d2820fbfaad18a682742e8cc1e7be48be0d796fb1d5c8cb3c59ff0c75ab")) + (2210000, uint256S("0x00000968eb429ede2e03af88adfc7fe56a0c066af88075694811cfa57fde1ee9")) + (2211000, uint256S("0x00003570e56f659f554ed3932667bd4e44aefb563fc7df5ccbd79f9c220cd9f1")) + (2212000, uint256S("0x000018c9a47c64b745f2e7c319c350c7ae8e63531158151b7d2be0884cd784d7")) + (2213000, uint256S("0x0000161b613df476524ed47714359fd2b92fe136c97f839c2847ca8749b022c6")) + (2214000, uint256S("0x00002fe5bda2ad47889e6b5bd0c2fb7d69da88b6389e35a1a6d982913099f090")) + (2215000, uint256S("0x00000836704f386a35aa724f5f6a0be9e6d9f098b82ae165b73e7f08562ee3e2")) + (2216000, uint256S("0x00001ceb64551337ab893a526bcf0f750f66b791c5cb0776473f83fdf1003a4a")) + (2217000, uint256S("0x00002ac1520f92840ad334d6b0f95c30deb14843e774e880a2f7a48dbbb1bfc3")) + (2218000, uint256S("0x00000edc53b526b6f56b551c9223d72e8ca640f349e84273a40b879d3e1f6883")) + (2219000, uint256S("0x00002a6486474331ed1646516e570cf2463948da729f35ce6a8600a264cb0f6d")) + (2220000, uint256S("0x0000353926a6aa20f7d15a621868bc840cb35ff7a2d815812aee339b218ff995")) + (2221000, uint256S("0x00002a113c1c8c40527f26b3cd61dafb51415dcb1483b841219f5d9ad8c76fad")) + (2222000, uint256S("0x000016c7a2795be4655a770acb5c9b48f993f9532fffc1b511d327ee79db0d8c")) + (2223000, uint256S("0x000025f79daaaca56b5a5c49ff4004b6c7e85f0a53a20d34be1723e00d6f5a03")) + (2224000, uint256S("0x000035e3afee025524eb79f11b959ad5679fdb8f3e7eae9926859a5422c9b74c")) + (2225000, uint256S("0x000045fa36a23d07b9d65e620a13fb46db631c989b1d3050d22af81a5850801e")) + (2226000, uint256S("0x000024892eba0fb80bc01df5ed4c76b13531d711cc9996ca6d4d94ff939e3a33")) + (2227000, uint256S("0x00000e11d886043624da09d85e04952eec3591d645078be51b8978683a4291a8")) + (2228000, uint256S("0x00000ef823ff95800352a2dc5da9ab1932a9fba007e9c9a2dd4d3ad2c4203d4c")) + (2229000, uint256S("0x0000372a5415a90c8912d145387844593ea45751736742dad5c2350bb4512e33")) + (2230000, uint256S("0x0000410bd162fc58d18e26c1c100d28ae9941d1a35ed992b577ab1da6bdafabe")) + (2231000, uint256S("0x00005ec2833af26811d1f1ce92c88a6b587ccab104dbc49b593c097e1ccd1eaa")) + (2232000, uint256S("0x000029934735720a6c852c9ad73da66e116a5262952228e8facc15628b3046c7")) + (2233000, uint256S("0x0000037e878e1606203e4d475c0a625fac8c834ac2e0bf785fd079eb72e685e2")) + (2234000, uint256S("0x00001eb46b75e2320e5aa6967107b6f632fdd661a03870d74a35fdd1d4ee3c49")) + (2235000, uint256S("0x0000092f56556a50ea1e90d7373bce71d57437e8c8d39c12871a4ccf4dd2bbee")) + (2236000, uint256S("0x000017fb5c98efd72e78545fe155738aca47edfcec1fa0c3b4152f1ad541881b")) + (2237000, uint256S("0x00001fd4156fb7d874a54e18bd959676ed3b1f100b0c63fe6b7bdaf0a1942a37")) + (2238000, uint256S("0x000050571a2aaea831a9b198ff130f3406defef0ec7625c44f8ef7b66ffd518b")) + (2239000, uint256S("0x000032125d15949a43a46ee1c88cd3925181ae1eec7d94d087a1397debc5b252")) + (2240000, uint256S("0x0000623792bc7dfdfb2c47022ff41e4fd7a4fbf91eedcdfc09431702c3430517")) + (2241000, uint256S("0x00005d36c7c64cc369d529ee517be31e67d7ebee5488c8867249f03e8ce9a5c3")) + (2242000, uint256S("0x00003706d4230aef85da3ca4c1647ef48eb768f470050f699c2ca2146516b1ef")) + (2243000, uint256S("0x00001fa6366b05e47f916583b3d68e28714e8e82b8f01c4486e743ba79ed1c41")) + (2244000, uint256S("0x00000a3940dc652a883f38f6795ad3cc2ea1d78cf57b55c502b011f3ce1c18c8")) + (2245000, uint256S("0x000026df815a28e8031ef1b9a358bdcd0b04f03e7c66733698f1c664f9da0b40")) + (2246000, uint256S("0x00002cc6b69f07f1075de08a4c35a43d864c3a0b034c183aa7624b94557b7a62")) + (2247000, uint256S("0x0000404475d281530c489a1adc29d7e947ff004cf350d1bdd94bdc74d7572f05")) + (2248000, uint256S("0x000031b67097dc97318ed9904e24f1fb31ef412edeaa61999128728a56e27bc8")) + (2249000, uint256S("0x00002b3c5cfc6265494b960e23fe2dc4a3acc04aa374d63eeea9c8a7eee364f0")) + (2250000, uint256S("0x000028cd62deeb5e810740499c3147bd6394d44a58c54e2bbff1b071804343ca")) + (2251000, uint256S("0x00004bbf376a8391b9fbd4a64150099ee2e0a04c1faab523d832ea30e1d97caf")) + (2252000, uint256S("0x000002aebd7d34a150146c6385d06ea7fbfbc5e0df0257732cbebd25d0c1a821")) + (2253000, uint256S("0x0000501755e78c2fff53c2e25ebd0f571d86f8ccdf63e1e6049a770e523909ae")) + (2254000, uint256S("0x000041724baf9c7769c5198f028c692dc5ba6b19163281359e59e686bacba5fb")) + (2255000, uint256S("0x000024a7e905e50cb37aa35eaf2e95fe4802ed71e6627ddbe18852885ac4398f")) + (2256000, uint256S("0x0000198a1cca62122da471f7d3c288375542976db55a3c5e2e940bc29c99b9da")) + (2257000, uint256S("0x00001a004f117fd65805aa828460d88964130e91fc6f57c661574edb53faf3b3")) + (2258000, uint256S("0x0000676afe3081fb6870c26831394c0636337d9b0fbcf5eb84ab8028eeea9006")) + (2259000, uint256S("0x000014d9a3074334976168b93749d5a185d6787fb9f0c8160da9601c06832631")) + (2260000, uint256S("0x00006149bd7600d47de36462f1560e2adb294ba590e9600bcf784b59270cae77")) + (2261000, uint256S("0x00002ff74dc446326097f14e917874ce69d7a3f6362ccdf6e156e2cc569953fc")) + (2262000, uint256S("0x000016b7a296c1cb25c4255e829d11207beff2c8f75a20ec8d9dc24ded91fe93")) + (2263000, uint256S("0x00003bf13cd7cb98d8936bf77c148a0dd742790394f06dda43cfc2fbc11054a3")) + (2264000, uint256S("0x00000af9a8865dd4acd3333c1ff088900469a7c25461b6dbeb451804cac92821")) + (2265000, uint256S("0x00000d9b07659eeda285d7272ccee76c6e938bdfc665ab83ae284cae779f2074")) + (2266000, uint256S("0x00000d9fe003964dd23c434a3c334bb2ba4c578c55829816f2a551d2d8263a00")) + (2267000, uint256S("0x00005d71d76237b2c78fc4c8817f3c7d6949a128e1c9e537ce94986061ce8ada")) + (2268000, uint256S("0x000038d18491bb2028248c6f548e428fea166e031edab2d734c0b56fd93f2807")) + (2269000, uint256S("0x000062866cb9aad2f24dfa87082f43386d5bd4b7fcabdba8d5194dd2a722829a")) + (2270000, uint256S("0x00002c8835060df6cffa87be9849faccab191bd4dd8719f75dac4b34e4fdb5b7")) + (2271000, uint256S("0x0000109c9238c8dceb0f079464d5eca1fe1b66701006f4d0f1abc2b657802ef1")) + (2272000, uint256S("0x00000e003fb270229b0d08de5882b89a3ca75235af0ab6b097b7d6a2969efc29")) + (2273000, uint256S("0x00000377d549507f4f18908429e05ad137318b352407478479adb2b7d3f240a3")) + (2274000, uint256S("0x00004032dd5cb09dc0b47e6cff670f8fc18cb4d04c17177143fb0b1cc4d4f4e7")) + (2275000, uint256S("0x00000805d1f6f463d3dde2962a2c757b4ae4a46914309a703b2216744132548b")) + (2276000, uint256S("0x0000463e28f09ad5548b0fa51130f3540d3769ef3f961e31fae9fb005ac8da47")) + (2277000, uint256S("0x00005292151318574567c9e3653b5689a4349fdc9479f5998d77e8422209c85c")) + (2278000, uint256S("0x000018eabebf46682ba0953964909a444ea295257fad7102362a39ed272e0521")) + (2279000, uint256S("0x000033f764e55ecda2294bfaf8820bbcb0422c225fc5c963695ea495e6b5e8d3")) + (2280000, uint256S("0x000010aba066577d86f268a859a5cc85f467edb456b427c6320e43b367f25703")) + (2281000, uint256S("0x00002fb37f3b5a54c289f911d88ad4fc47b072829abe9871e1b0cfd7db105e90")) + (2282000, uint256S("0x0000266963210e2b0d10201614747a78012b3a94f1a2079f1a46c3d8ebe5fb99")) + (2283000, uint256S("0x0000221de5c35bd2e5fe97a8f2c418402b7fed8b700e0817c2020cc3fc4379a5")) + (2284000, uint256S("0x00000b824166c7738b986f958c21a6fdae7493c61ea1c73b39dbdc8aaa2f5224")) + (2285000, uint256S("0x00001193031ae0f0c0d21207d07a127c5df7058c2169b71840f321a9577a4c24")) + (2286000, uint256S("0x000040fea647dbfcbd2fa6ad3aa2a79041a6dd5eb3dd1743230e6df8295dc811")) + (2287000, uint256S("0x00000aea28e1096baf42936f64ddfab1d460a1a3461825b8354171db51979c6b")) + (2288000, uint256S("0x0000217d2f21ff465db62b5e6a2e23837891d7dd0f7aa6b32a174afd1caee6bd")) + (2289000, uint256S("0x00000617a0d2591d90e8ab4bda2da1714038fcd4a1f7d380754d6e24360dab91")) + (2290000, uint256S("0x00002fff9f32112eb71ca61b2419b34701965d7ff7cc0e88e1ebd5811adeacda")) + (2291000, uint256S("0x000045d06fa029d7fad26f4ba40c2a23085ddfba4d22569bf3d81f246483a41d")) + (2292000, uint256S("0x000029788ae90c75a2b0bb7bacd7f23b74ba2001ed05a9191eef3b3a0727337b")) + (2293000, uint256S("0x00003604b611153c158eb967f6fca03d72d597123f67fd59be59fca4e8940748")) + (2294000, uint256S("0x0000623675a44b04c36bc6c8f44863be32c27f207903ee6ff541aef1bfcdd663")) + (2295000, uint256S("0x00001169800c5590f06b72bbb0298f94038515ac049efa6ca41c904183dc128b")) + (2296000, uint256S("0x00005563f4c813fdf446902709b79b1dacffa7f3993a30c8294e134d491f279b")) + (2297000, uint256S("0x000058a0be1265c88807e82dce7e8ad56f02ac24720b0a9c9e1e6fd2abb1812d")) + (2298000, uint256S("0x00005344443d98bcb8416f7d58af8ea7a7c542032dda56990cf0cb839b905c76")) + (2299000, uint256S("0x00003120ff3a639166ea62dfdec94c695b9c89e15d7c873c62e0d6f5b2bfabf8")) + (2300000, uint256S("0x0000304e0dddc169503d5f0fd3c7b2eddbcf1a7f87a8819368d67cd1dffbcada")) + (2301000, uint256S("0x0000464ddf4f34b463adbdbb32932da17617d973a6f98aee400c9faf454ea250")) + (2302000, uint256S("0x0000394bbb1af4ff2048e1fc5b8eebedee17a832d7e37f5aaa060f45585e9ee1")) + (2303000, uint256S("0x000038003d7121364ad72d2b561e5700ab1a89ffaaadc14aa504130b04f17755")) + (2304000, uint256S("0x0000022e3d976ccd0c4b85e5d969f1f646817bb107eb42128d6b0b4fdee22ab2")) + (2305000, uint256S("0x0000311678e26070ce7014645df117cfd86e9cc4d2fe3a2bda7c923951e91787")) + (2306000, uint256S("0x00003013a6c0fd2b0023a1718f96162065191e9a14efef92c9d9c62de0977855")) + (2307000, uint256S("0x000020081d8b33acc0f127dc97381c7df8a7f153206d61f976bf2518c7b688e5")) + (2308000, uint256S("0x000021f776dff5d566f3f1becb9bfea68b9a91831a682436efac0c0f45327a71")) + (2309000, uint256S("0x0000410145c455266bae76a3e763e7cc7ea9fe886a220c66bf6b1f50193d10ce")) + (2310000, uint256S("0x00004cc8e0e130149a871c86ca29e7ca5eeb60684dd2ae9f91ff5b30e7e4e3a1")) + (2311000, uint256S("0x000016091d836bbc9b716b87273ad8096c86421e57783c650ecb19f0585d02fe")) + (2312000, uint256S("0x00001bb300882cca422c6290ff64881bbea1b551e903a178240a1aaa18e08dbd")) + (2313000, uint256S("0x00001665a6292a627795615e8e5da10eee2dec5811279c9aca77821558daee25")) + (2314000, uint256S("0x000024d75332bf61ee3b47c17f193f4160bb32b4f2b23649f6ee471f95a72caf")) + (2315000, uint256S("0x00001c18f7e826710660132b919ba750b5a675f73a1b7dfb12c2ba3d7f4241f4")) + (2316000, uint256S("0x000019329499645844434f5fc3002e25fb76951d139de579affa692838d96f6b")) + (2317000, uint256S("0x00002a1130a36b7c84b6f72b00f5e08c6d99fe697082edb654bec8ef1d1c093b")) + (2318000, uint256S("0x000002f6c694f36424f36ba74d3494e084c98d8d44185e3f8d9b530fae2a557e")) + (2319000, uint256S("0x000018b05e2e3e5f3c74a1e4a1ed67c6322bb15da52cf010580f43479ef9ffaa")) + (2320000, uint256S("0x000000a3d41a59482b5bce0f8b0b6ca0c5c8c6148cd948571e577778fc2188d0")) + (2321000, uint256S("0x00001d1e77dcdb603c1fce01ce6e8805ec4732ae07da746680545b397e4c6f48")) + (2322000, uint256S("0x00000eb95b724d1eff743d5214fd79476a23602737eb063e38715150bf535e8c")) + (2323000, uint256S("0x0000467bf6da3c90d6912ecf50221ad38816ff879f79aa857c5d8e107b36a106")) + (2324000, uint256S("0x00005442cf85e9078d3b7d5832dfa845dda2640b4fc1a3fd74b983619334c46d")) + (2325000, uint256S("0x0000001794cb065de5aca0c3b3d77b9258b27b6e6f7de8aa008e2108f5c87de0")) + (2326000, uint256S("0x000015c48140190b7c3e62eec803af8130a19a426e29162c2a4c973e902d5b76")) + (2327000, uint256S("0x0000103114189750405dbca57a39d35a55defe2884c1a028ac42f35cb0bb5f45")) + (2328000, uint256S("0x0000329552839b78a5c765dca4bf88b2fc1c23baad297914e685ff6bc1d5f5e0")) + (2329000, uint256S("0x0000504b1b0ebe4724a29cd01283bf44196909129b102ed38c32dbc6b25f2992")) + (2330000, uint256S("0x000028dada7347ec97146c83c4e458d2a07cfcb56564e730074544bdd9c23c56")) + (2331000, uint256S("0x000038bbfb0008e827144b021f1fcf4de48d9edf1798a9612d73d86973cff816")) + (2332000, uint256S("0x0000378c5f4c8e6b2054fb42d7ecfea87f93cc47e506a2b37446e805d904bf85")) + (2333000, uint256S("0x00004fcf68d815950ad93925f89d7ada80c4a84ca11ce9d352ebebeb8be27005")) + (2334000, uint256S("0x0000298ffa38558340cfd66b28f340f5284046cfb3d8dc3a049ceb55fbd97fdd")) + (2335000, uint256S("0x00005112663121c21b7ca662a2b973c4005919394fee2a710625209baf9b50a2")) + (2336000, uint256S("0x0000565c5ae1fe348293ce8ad70c3aa4d2e2a53e2250625e55c7f5093a85176c")) + (2337000, uint256S("0x000012eb9636d43da5bb36a42cb1ab2178f7f65fc0b936f14d1dd80bca64b713")) + (2338000, uint256S("0x0000385511dd5d70d345a4874f67f740dfa4545d9bb2faa8b0149ccb38c6f133")) + (2339000, uint256S("0x00004c8b5b1d1c4dbb4932ee8839c01c42430e78b21f8e465e5ca50e714f6c65")) + (2340000, uint256S("0x00000d029a8682bcd1148c5357a3b298c320672737fb01d2c298575a348b83aa")) + (2341000, uint256S("0x000036462c12f287661c7ea2eebd22ad66cbae64f59236736d7d4c4f67d09940")) + (2342000, uint256S("0x000059c965be169d688bc8c628240fc0270ab1f755b9908568516dd117eb9a36")) + (2343000, uint256S("0x0000319367199abdfb31e5fe438f75f8f6a0b2ac1f8b3745f56b168e61716922")) + (2344000, uint256S("0x0000354a7e409f69f8f4703418e97fad05b435c8314a95630622a056c0d3359c")) + (2345000, uint256S("0x000019d33bb822ebacd3af6cdccd5f30d6c669820a739e82477a17137593c11e")) + (2346000, uint256S("0x00005c840bf66a5ef5e3f2338adf8a46b803ace6481e1e944600ac05fc26f0a4")) + (2347000, uint256S("0x000027cfed1aa676fd804fd8704705d9cc7a88798cdc418a9aae54a99f757c36")) + (2348000, uint256S("0x00001304bfe4820c4520bc1b1406f862899581f294b08bd58ff4e60c6dc17511")) + (2349000, uint256S("0x00002c98d82a30ab170cb6960342919611e10914e813c884366690fa7e9e6dda")) + (2350000, uint256S("0x00005edc83af71ce822a94f52207461eb22c5bbed6b97b4bb191ef76042af8c3")) + (2351000, uint256S("0x00005349b809bc768c365055c1d2b567f6f1e5c357e0de21a48d3b22b80eec9a")) + (2352000, uint256S("0x0000502e75229fa712a14d6d5e28dcc4035064f8c3e3b7ce107a44a18ff79e3a")) + (2353000, uint256S("0x000037d4c953e9f5ea3b15918c65c65e46b9058d7ebf4bb3744bf8a3297f904f")) + (2354000, uint256S("0x00001e449300307147aa70b45db10507e463ef9570d1177b3e9bfacc6882474f")) + (2355000, uint256S("0x00002a5aade28c0f7ab7ce7fbb142316dcb903c6187f3cdf1fd85ffa5a9a746c")) + (2356000, uint256S("0x0000141a772c173a16ee3bc8e202c9c213a9de2f27d4787f6c6e05bce268e2ee")) + (2357000, uint256S("0x00005b4d4bff33a1289e54a9fd94e8dded899cbec6226505c9010cdcfff1b161")) + (2358000, uint256S("0x00004536c82ed717395897c0917ff1a493c59bf8dc9683392358ae03e69e051b")) + (2359000, uint256S("0x00003e1f7b38f8793f9f5e06cfecb2bdac5e7c4cbc1bf578892c8276d11d2ae1")) + (2360000, uint256S("0x0000258b0cf718cdc03218d4f503b866f4b267db46fe4a10719c80f672d04abf")) + (2361000, uint256S("0x00005bb666284a242a6e819d847b5a6ad94d053c5455aacade7f2a43c37d65fe")) + (2362000, uint256S("0x00001f13f7efe996827d5cb797de88608eead137497a4f84338e6fcbd597db5b")) + (2363000, uint256S("0x0000100e1042483b63f10b6c5cc407b2fff8ae4d4669941c028c99254920e35a")) + (2364000, uint256S("0x000037e08cc4ef6f87f16b53b17347499c0be643888818d9a2dbd3294d4453c3")) + (2365000, uint256S("0x00004fd3b1fc85a12d1760782272f1685cc0ddb080317736eb249e46547cd19b")) + (2366000, uint256S("0x000004f297feb21d642c598fb870edb4fe91d780b3a3cdea3ae6032c310de64e")) + (2367000, uint256S("0x00001fb01d783168c5daad3f1bfd87ef61f58d1d9129a34000b6692e0ccd0aad")) + (2368000, uint256S("0x00000ca404568d6831effed6a4457ea6f6748edd06d1e6d070f3e12edd9e22ec")) + (2369000, uint256S("0x00004ae89b9f84892963d816cfa804d43192c493b7f9fcb04a76105acbe8d267")) + (2370000, uint256S("0x000052859d7d554dc460cd9135b462f28eecb3740537b936d2904887d1895bf7")) + (2371000, uint256S("0x000030acb538ef8bca7bc1b754474a3f6bb207c144bc1bce934520657177a65f")) + (2372000, uint256S("0x00003d1b60ca84a54a2d73ccd353ea5f50241103652ee537e1671b66831f0966")) + (2373000, uint256S("0x0000349e7da5293733b7c0eef13d507d2f47864f0911f466e2c6836e7e79d45a")) + (2374000, uint256S("0x000021c31e447a8c1099dbffb02ae34ff2c61e27a7c53e1329be6a153485bbb8")) + (2375000, uint256S("0x000045a10be187c48bd1cc4324768c7a9377f25dd3856cc92e7d559e1c0a0ab8")) + (2376000, uint256S("0x000041af5a7b5beb6c2588084356cd6acf19a39a09019585c9173cfb65a26df4")) + (2377000, uint256S("0x00003c505c5fee37c3a7141d56d7904485d2793e1b23d8778cfc972b95a87318")) + (2378000, uint256S("0x000014174d006060c582857381881d649ed4f8a13ebd7f56198e1be5e71fa28f")) + (2379000, uint256S("0x00000a6b29c94c0d01c790702963db151f560b62edb9b7626da871a4b3812418")) + (2380000, uint256S("0x000049cdbc8c487e694419e33b5fb7983535aed8b4b249c9ee9180e01abd2a4a")) + (2381000, uint256S("0x00004032c7965f8ad5220c043cbd4cee3cffc35fad1d6156e9206790abd710ff")) + (2382000, uint256S("0x000003cd8dd0b822ab4c4d745b924d95222171845e72043e3b880117e59b21ea")) + (2383000, uint256S("0x000012a6278a5c4c81c823d04eb7f958d9c79c37a6764c9ab8875aea08174bee")) + (2384000, uint256S("0x00001d3f34838deba6ec39715ac3e4333da4fef6688e426cd7819bc9669833f2")) + (2385000, uint256S("0x000009316270adee6a2624ede75d328c427b6c8bd423f3938860d040af1c671d")) + (2386000, uint256S("0x000010236cada090ea886757d6bb51ac14f035296386ccbfe7e9120134cbe597")) + (2387000, uint256S("0x000006189ad7a6028dbbe6d5ccc22345a7aa1c8fd7db7079cbc47515e38e7397")) + (2388000, uint256S("0x00001fdf769c3a9093eb4d41d3592028e6dd71656555ea40822f35858bcedd84")) + (2389000, uint256S("0x000021a1c2430092c5ec95897bd177ab276dda2f9a82400c05fe5f64402d8c79")) + (2390000, uint256S("0x000027acd3077f0d53fc3184e47479b268dbfa9493c7e1eb091c9ef168b76a1b")) + (2391000, uint256S("0x00002f6e4d97e9f10b16ad837bb4277f370d49ad823324ed71b0e64471d04658")) + (2392000, uint256S("0x000045a6676541d30bad5c46b815ae817a8a01b2452946505b47f10f3de6cdff")) + (2393000, uint256S("0x000044de5e73fb79f7cf96d5427327bc38e7a551043039c0e55ce596f22b15f2")) + (2394000, uint256S("0x00001e66c1e980b7faab01e6833237d15079247cad861407ad2f582a95ba76c7")) + (2395000, uint256S("0x0000301ace3f4b5cd502f1ce92abaffaeb9a5c09b47686aff828cb84068867d2")) + (2396000, uint256S("0x0000110706345aa37fb0b8abe67d7b3cc14a3f584e0146cbbb9f2ea786596471")) + (2397000, uint256S("0x00002ffbed3797a9e47c1f2721be8510f6b7eeabb8bcc2b9fa38a489b40fb9a6")) + (2398000, uint256S("0x00004d9d8a89eb5f56cc47d013a6fee42a4570ffe2f4990fec1ee807c09d82bf")) + (2399000, uint256S("0x00003944a80f19f58b198d4786da162b770ebc0c3f2a24f3af8722e07b769198")) + (2400000, uint256S("0x000044599652a8b2177d2ea19d35b0257fed071021812463616b58af8de02d22")) + (2401000, uint256S("0x000036c0b9f8d210079295b7160b05885733bb76ed29def6d270a0d6be7aa362")) + (2402000, uint256S("0x0000341954ab1daff43b131980c2d57cc39ad57e140308141aacf831aa380a33")) + (2403000, uint256S("0x0000151d97b9ce8159f7382e06986ac24bbe387de18cf7482173b0c1621578e9")) + (2404000, uint256S("0x000035254e234fe75f483b5d30c8bf8723370dbba7c7a6ed3b72346d5bae8699")) + (2405000, uint256S("0x000024fe0a46f18ed3bfd835a8aaeafa9938ff4221ce144bdcfe53fe0ca61432")) + (2406000, uint256S("0x000022c073272ca4556951f65cd2462653ae655db23422405e342b7b92a4c7a0")) + (2407000, uint256S("0x00003c1a4a416512a704dcd2c5cbfac3522f155778b09a14e78f9fd54167e486")) + (2408000, uint256S("0x0000d4aa6a830bd2d89eb0bf2af187466bd13ecda83f3468947e08184ef13fa6")) + (2409000, uint256S("0x0000c69ec0158d6072da00b53c5a0b6a544b760b6e7f8acc5fc0bceabd3fe9fa")) + (2410000, uint256S("0x0000a4901d4456384bfe9441970b5793bea4701d8bba828f19ed191309e67c3c")) + (2411000, uint256S("0x00000ccfe01119a0c621b1c6de7cf5bf9e3cd907e7acb07d041942a0be2297e5")) + (2412000, uint256S("0x00003c0c71f4f9543900d6d5325cfa4d667800948c732e1a69f5332a2ceb6467")) + (2413000, uint256S("0x0000386752d9856fc514482fbfb43a1422d5d451e6affbf73d6a7fa9f411b244")) + (2414000, uint256S("0x00007d250ec5903723999eda30d34b567d98915f45ea339c2f9e573bf4178f5d")) + (2415000, uint256S("0x0000623c6d1bd3fc5c6f7df11dca9730c82a48d79c0d3ab4284edfed23fffcb1")) + (2416000, uint256S("0x00004fde023580986fe07ff6159cb6d81faea3e7a1a65385784e3a1c0c6dc1ef")) + (2417000, uint256S("0x00003ec1858a17003cda9b26f8da1bfd49964327a13ca856c87b350465569704")) + (2418000, uint256S("0x000000451dd5e8d5f8d8db95071c25459fad44abe44b1ede69596ab9b7636acb")) + ,(int64_t) 1755488034, // time of last checkpointed block + (int64_t) 2495799, // total txs + (double) 2304 // txs in the last day before block 2418847 }; } else { // all other HAC's with no checkpoints From cae942a5c94a2af2d099da0b226b4f2f2952a1ec Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 20 Aug 2025 15:15:36 -0400 Subject: [PATCH 38/63] z_listlockunspent --- src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 6373d554d..a16dde687 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -460,6 +460,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, + { "wallet", "z_listlockunspent", &z_listlockunspent, false }, { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false }, { "wallet", "z_listreceivedaddress", &z_listreceivedaddress, false }, { "wallet", "z_getbalance", &z_getbalance, false }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 9a66fea43..eff98f9c2 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -295,6 +295,7 @@ extern UniValue getrawtransaction(const UniValue& params, bool fHelp, const CPub extern UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue lockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue listlockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); +extern UniValue z_listlockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue createrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue decoderawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue decodescript(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f6583bd17..e1ff70cfd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2645,6 +2645,45 @@ UniValue lockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) return true; } +UniValue z_listlockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 0) + throw runtime_error( + "z_listlockunspent\n" + "\nReturns list of temporarily unspendable outputs.\n" + "\nResult:\n" + "[\n" + " {\n" + " \"txid\" : \"transactionid\", (string) The transaction id locked\n" + " \"vout\" : n (numeric) The vout value\n" + " }\n" + " ,...\n" + "]\n" + "\nExamples:\n" + "\nList the locked Sapling notes\n" + + HelpExampleCli("z_listlockunspent", "") + + "\nAs a json rpc call\n" + + HelpExampleRpc("z_listlockunspent", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + vector ops = pwalletMain->ListLockedSaplingNotes(); + + UniValue ret(UniValue::VARR); + + BOOST_FOREACH(SaplingOutPoint &op, ops) { + UniValue o(UniValue::VOBJ); + + o.push_back(Pair("txid", op.hash.GetHex())); + ret.push_back(o); + } + + return ret; +} + UniValue listlockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) From 80f48a9338773c2514d34093f045d19262e05b31 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 01:56:24 -0400 Subject: [PATCH 39/63] Run z_listlockunspent in tests so we can see which notes are locked --- qa/rpc-tests/lockzins.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index 232667ab5..a073beca8 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -75,7 +75,7 @@ class LockZinsTest (BitcoinTestFramework): rpc.generate(11) self.sync_all() - rpc.z_listunspent() + # rpc.z_listunspent() rpc.z_getbalances() recipients = [] @@ -84,8 +84,11 @@ class LockZinsTest (BitcoinTestFramework): # queue 4 ztxs, which will try to spend the same funds multiple times # without correct locking of zins opid1 = rpc.z_sendmany(zaddr1,recipients,1,0) + rpc.z_listlockunspent() opid2 = rpc.z_sendmany(zaddr1,recipients,1,0) + rpc.z_listlockunspent() opid3 = rpc.z_sendmany(zaddr1,recipients,1,0) + rpc.z_listlockunspent() opid4 = rpc.z_sendmany(zaddr1,recipients,1,0) rpc.generate(1) From bf55e6daa55f9493427dd950bfed4f5e8bdd9356 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 01:56:53 -0400 Subject: [PATCH 40/63] Avoid useless warnings in tests --- src/hush_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 39ffd3e97..03c1af053 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1339,7 +1339,7 @@ void hush_statefname(char *fname,char *symbol,char *str) fname[len - n] = 0; else { - if ( strcmp(symbol,"REGTEST") != 0 ) + if ( strcmp(symbol,"ZZZ") != 0 ) printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,SMART_CHAIN_SYMBOL,n,len,&fname[len - n]); return; } From b0cbcc6152886d7554e2b373b894f0fdb84e9993 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 01:57:42 -0400 Subject: [PATCH 41/63] Unlock notes+utxos earlier --- src/wallet/asyncrpcoperation_sendmany.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index a6d708e53..ba09c09e7 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -169,6 +169,10 @@ void AsyncRPCOperation_sendmany::main() { set_error_message("unknown error"); } + unlock_notes(); + unlock_utxos(); + LogPrintf("%s: z_sendmany input notes+utxos unlocked\n", __func__, getId()); + #ifdef ENABLE_MINING #ifdef ENABLE_WALLET GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1)); @@ -179,6 +183,7 @@ void AsyncRPCOperation_sendmany::main() { stop_execution_clock(); + if (success) { set_state(OperationStatus::SUCCESS); } else { @@ -193,9 +198,6 @@ void AsyncRPCOperation_sendmany::main() { } LogPrintf("%s",s); - unlock_notes(); // clean up - unlock_utxos(); // clean up - LogPrint("zrpc", "%s: z_sendmany input notes+utxos unlocked\n", getId()); } // Notes: From 7c434ba03078241e49eaf41927bafd60551a6715 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 01:59:20 -0400 Subject: [PATCH 42/63] Log calls to GetFilteredNotes and only warn when witness root is actually invalid --- src/wallet/wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index db5cebc9b..da52b8c57 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1846,12 +1846,10 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, rt = witnesses[i]->root(); } else { if(*rt == witnesses[i]->root()) { - //fprintf(stderr,"%s: rt=%s\n",__func__,rt.GetHash().ToString().c_str()); - //fprintf(stderr,"%s: witnesses[%d]->root()=%s\n",__func__,i,witnesses[i]->root().GetHash().ToString().c_str()); + } else { // Something is fucky std::string err = string("CWallet::GetSaplingNoteWitnesses: Invalid witness root! rt=") + rt.get().ToString(); err += string("\n!= witness[i]->root()=") + witnesses[i]->root().ToString(); - //throw std::logic_error(err); fprintf(stderr,"%s: IGNORING %s\n", __func__,err.c_str()); } @@ -4880,6 +4878,8 @@ void CWallet::GetFilteredNotes( { LOCK2(cs_main, cs_wallet); + LogPrintf("%s ignoreLocked=%d\n", __func__, ignoreLocked); + for (auto & p : mapWallet) { CWalletTx wtx = p.second; From a719e05be4144b51512e8f98a94efc92b756713e Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 02:00:19 -0400 Subject: [PATCH 43/63] Add output index to z_listlockunspent --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e1ff70cfd..30cacabe3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2678,6 +2678,7 @@ UniValue z_listlockunspent(const UniValue& params, bool fHelp, const CPubKey& my UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", op.hash.GetHex())); + o.push_back(Pair("n", (int) op.n)); ret.push_back(o); } @@ -4120,7 +4121,6 @@ UniValue z_getbalances(const UniValue& params, bool fHelp, const CPubKey& mypk) return results; } - UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -5994,7 +5994,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); std::shared_ptr operation( - new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, saplingNoteInputs, recipient, nFee, contextInfo) ); + new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, saplingNoteInputs, recipient, nFee, contextInfo) ); q->addOperation(operation); AsyncRPCOperationId operationId = operation->getId(); From 564ff0cb3a45a20bf305394bba09076589b8d925 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:13:52 -0400 Subject: [PATCH 44/63] Update test_framework.py from upstream which fixes #476 --- qa/rpc-tests/test_framework/test_framework.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index d04bd8b95..1728c8dba 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -123,11 +123,16 @@ class BitcoinTestFramework(object): print("JSONRPC error: "+e.error['message']) traceback.print_tb(sys.exc_info()[2]) except AssertionError as e: - print("Assertion failed: "+e.message) + print("Assertion failed: " + str(e)) + traceback.print_tb(sys.exc_info()[2]) + except KeyError as e: + print("key not found: "+ str(e)) traceback.print_tb(sys.exc_info()[2]) except Exception as e: print("Unexpected exception caught during testing: "+str(e)) traceback.print_tb(sys.exc_info()[2]) + except KeyboardInterrupt as e: + print("Exiting after " + repr(e)) if not self.options.noshutdown: print("Stopping nodes") From 6e029a62ac195896f4521e1b929afb44a38cce22 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:14:23 -0400 Subject: [PATCH 45/63] Remove unused header inclusion --- src/wallet/asyncrpcoperation_mergetoaddress.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index ab4a949eb..b70eeb98f 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -1,6 +1,5 @@ // Copyright (c) 2017 The Zcash developers // Copyright (c) 2016-2024 The Hush developers - // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html @@ -28,12 +27,9 @@ #include "transaction_builder.h" #include "wallet.h" #include "zcash/Address.hpp" -#include "zcash/JoinSplit.hpp" - #include #include #include - #include // Default transaction fee if caller does not specify one. From d73c1b86e4d8146e4a9b0c49efe14da32b78ba77 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:14:47 -0400 Subject: [PATCH 46/63] Log amount if negative change happens --- src/transaction_builder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 76ba42302..893c292c7 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -150,7 +150,7 @@ boost::optional TransactionBuilder::Build() change -= tOut.nValue; } if (change < 0) { - LogPrintf("%s: negative change!\n", __func__); + LogPrintf("%s: negative change=%lu!\n", __func__, change); return boost::none; } From fcd939978f6e81e59077db826b18587173599052 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:15:11 -0400 Subject: [PATCH 47/63] More verbose logging in lockzins test --- qa/rpc-tests/lockzins.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index a073beca8..33f07a336 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -46,6 +46,8 @@ class LockZinsTest (BitcoinTestFramework): #'-debug', '-regtest', '--daemon', + '-zrpc', + '-zrpcunsafe' #'-rpcuser=hush', #'-rpcpassword=puppy' ]] From 8148c4f625c8e4b55405d1261a2e970f7f1d7e82 Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:26:55 -0400 Subject: [PATCH 48/63] More test logging --- qa/rpc-tests/lockzins.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index 33f07a336..314bcdb3f 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -47,9 +47,8 @@ class LockZinsTest (BitcoinTestFramework): '-regtest', '--daemon', '-zrpc', + '-zdebug', '-zrpcunsafe' - #'-rpcuser=hush', - #'-rpcpassword=puppy' ]] ) self.is_network_split = False From eb4fc522731df11d2e5055a34b8dbe2d2f6735fc Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 16:59:33 -0400 Subject: [PATCH 49/63] lockzins test finally passes because z_sendmany correctly locks notes now --- src/transaction_builder.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 72 ++++++++++++++++++----- src/wallet/asyncrpcoperation_sendmany.h | 9 ++- src/wallet/rpcwallet.cpp | 31 +++++++++- 4 files changed, 91 insertions(+), 23 deletions(-) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 893c292c7..f942296a8 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -150,7 +150,7 @@ boost::optional TransactionBuilder::Build() change -= tOut.nValue; } if (change < 0) { - LogPrintf("%s: negative change=%lu!\n", __func__, change); + LogPrintf("%s: negative change=%lu mtx.valueBalance=%lu fee=%lu!\n", __func__, change, mtx.valueBalance, fee); return boost::none; } diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index ba09c09e7..8e47993f7 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -63,11 +63,12 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( std::string fromAddress, std::vector tOutputs, std::vector zOutputs, + std::vector saplingNoteInputs, int minDepth, CAmount fee, UniValue contextInfo, CScript opret) : - tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo), opret_(opret) + tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), saplingNoteInputs_(saplingNoteInputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo), opret_(opret) { assert(fee_ >= 0); @@ -120,6 +121,10 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } + //TODO: lock_utxos() ? + // Lock shielded input notes (zins) stored in saplingNoteInputs + lock_notes(); + LogPrintf("%s: %s z_sendmany input notes locked\n", __func__, getId()); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { @@ -171,7 +176,7 @@ void AsyncRPCOperation_sendmany::main() { unlock_notes(); unlock_utxos(); - LogPrintf("%s: z_sendmany input notes+utxos unlocked\n", __func__, getId()); + LogPrintf("%s: %s z_sendmany input notes+utxos unlocked\n", __func__, getId()); #ifdef ENABLE_MINING #ifdef ENABLE_WALLET @@ -204,7 +209,6 @@ void AsyncRPCOperation_sendmany::main() { // 1. #1159 Currently there is no limit set on the number of shielded spends, so size of tx could be invalid. // 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them bool AsyncRPCOperation_sendmany::main_impl() { - assert(isfromtaddr_ != isfromzaddr_); bool isSingleZaddrOutput = (t_outputs_.size()==0 && z_outputs_.size()==1); @@ -233,9 +237,11 @@ bool AsyncRPCOperation_sendmany::main_impl() { } } + /* if (isfromzaddr_ && !find_unspent_notes()) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); } + */ // Lock UTXOs lock_utxos(); @@ -246,8 +252,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { } CAmount z_inputs_total = 0; - for (auto t : z_sapling_inputs_) { - z_inputs_total += t.note.value(); + for (auto t : saplingNoteInputs_) { + //z_inputs_total += t.note.value(); + z_inputs_total += std::get<1>(t).value(); } CAmount t_outputs_total = 0; @@ -261,8 +268,11 @@ bool AsyncRPCOperation_sendmany::main_impl() { z_outputs_total += std::get<1>(t); } + LogPrintf("%s: z_inputs_total=%s z_outputs_total=%s\n", __func__, FormatMoney(z_inputs_total), FormatMoney(z_outputs_total) ); + CAmount sendAmount = z_outputs_total + t_outputs_total; CAmount targetAmount = sendAmount + minersFee; + LogPrintf("%s: targetAmount=%s sendAmount=%s minersFee=%s\n", __func__, FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee) ); assert(!isfromtaddr_ || z_inputs_total == 0); assert(!isfromzaddr_ || t_inputs_total == 0); @@ -410,6 +420,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { std::vector notes; CAmount sum = 0; + /* //NOTE: z_sapling_inputs_ is a list of all potential notes to spend // saplingNoteInputs_ is a list of notes we will actually spend // and need to lock. It is a subset of z_sapling_inputs_ @@ -431,9 +442,11 @@ bool AsyncRPCOperation_sendmany::main_impl() { break; } } + */ - // Lock shielded input notes (zins) stored in saplingNoteInputs - lock_notes(); + for(const auto t : saplingNoteInputs_) { + ops.push_back(std::get<0>(t)); + } // Fetch Sapling anchor and witnesses //LogPrintf("%s: Gathering anchors and witnesses\n", __FUNCTION__); @@ -444,14 +457,30 @@ bool AsyncRPCOperation_sendmany::main_impl() { pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor); } + LogPrintf("%s: ops.size=%d witnesses.size=%d\n", __func__, ops.size(), witnesses.size() ); + // Add Sapling spends - for (size_t i = 0; i < notes.size(); i++) { + //TODO: should be using saplingNoteInputs_ + for (size_t i = 0; i < saplingNoteInputs_.size(); i++) { + //LOCK2(cs_main, pwalletMain->cs_wallet); + if (!witnesses[i]) { throw JSONRPCError(RPC_WALLET_ERROR, - strprintf( "Missing witness for Sapling note at outpoint %s", z_sapling_inputs_[i].op.ToString()) + //strprintf( "Missing witness for Sapling note at outpoint %s", saplingNoteInputs_[i].op.ToString()) + strprintf( "Missing witness for Sapling note at outpoint %s", std::get<0>(saplingNoteInputs_[i]).ToString()) ); } - assert(builder_.AddSaplingSpend(expsk, notes[i], anchor, witnesses[i].get())); + if(fZdebug) + LogPrintf("%s: Adding Sapling spend\n", __func__); + assert(builder_.AddSaplingSpend(expsk, std::get<1>(saplingNoteInputs_[i]), anchor, witnesses[i].get())); + + /* + // notes we are currently spending should be locked + if(pwalletMain->IsLockedNote(ops[i])) { + } else { + throw JSONRPCError(RPC_WALLET_ERROR, "Note we are spending is not locked!" ); + } + */ } // Add Sapling outputs @@ -463,7 +492,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { assert(boost::get(&addr) != nullptr); auto to = boost::get(addr); if(fZdebug) - LogPrintf("%s: Adding Sapling output to address %s\n", __FUNCTION__, address.c_str()); + LogPrintf("%s: Adding Sapling output with value=%s to address %s\n", __func__, FormatMoney(value), address.c_str()); auto memo = get_memo_from_hex_string(hexMemo); @@ -497,6 +526,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Send the transaction // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction auto signedtxn = EncodeHexTx(tx_); + if (!testmode) { UniValue params = UniValue(UniValue::VARR); params.push_back(signedtxn); @@ -668,6 +698,7 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { return t_inputs_.size() > 0; } +/* // find unspent notes which are also unlocked bool AsyncRPCOperation_sendmany::find_unspent_notes() { if(fZdebug) @@ -708,6 +739,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { return true; } +*/ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { @@ -828,17 +860,27 @@ void AsyncRPCOperation_sendmany::unlock_utxos() { // Lock input notes void AsyncRPCOperation_sendmany::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %lu notes to lock\n", __func__, saplingNoteInputs_.size() ); + LogPrintf("%s: found %lu notes to lock\n", __func__, saplingNoteInputs_.size() ); for (auto note : saplingNoteInputs_) { - pwalletMain->LockNote(std::get<0>(note)); + if(pwalletMain->IsLockedNote(std::get<0>(note))) { + //TODO: deal with this + LogPrintf("%s: note already locked!\n", __func__); + } else { + pwalletMain->LockNote(std::get<0>(note)); + } } } // Unlock input notes void AsyncRPCOperation_sendmany::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - fprintf(stderr,"%s: found %lu notes to unlock\n", __func__, saplingNoteInputs_.size() ); + LogPrintf("%s: found %lu notes to unlock\n", __func__, saplingNoteInputs_.size() ); for (auto note : saplingNoteInputs_) { - pwalletMain->UnlockNote(std::get<0>(note)); + if(pwalletMain->IsLockedNote(std::get<0>(note))) { + //TODO: deal with this + pwalletMain->UnlockNote(std::get<0>(note)); + } else { + LogPrintf("%s: note already unlocked!\n", __func__); + } } } diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 271daba3d..2d06b0c48 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -27,11 +27,9 @@ #include "transaction_builder.h" #include "zcash/Address.hpp" #include "wallet.h" - #include #include #include - #include // Default transaction fee if caller does not specify one. @@ -45,8 +43,8 @@ typedef std::tuple SendManyRecipient; // Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase) typedef std::tuple SendManyInputUTXO; -// Input note is a tuple of output, note, amount -typedef std::tuple SendManyInputSaplingNote; +// Input note is a tuple of output, note, amount, spending key +typedef std::tuple SendManyInputSaplingNote; class AsyncRPCOperation_sendmany : public AsyncRPCOperation { public: @@ -56,6 +54,7 @@ public: std::string fromAddress, std::vector tOutputs, std::vector zOutputs, + std::vector saplingNoteInputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue, @@ -95,7 +94,7 @@ private: std::vector t_outputs_; std::vector z_outputs_; std::vector t_inputs_; - std::vector z_sapling_inputs_; + //std::vector z_sapling_inputs_; std::vector saplingNoteInputs_; TransactionBuilder builder_; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 30cacabe3..482d2997b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5191,6 +5191,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) } } + // Recipients std::vector taddrRecipients; std::vector zaddrRecipients; @@ -5280,6 +5281,31 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) nTotalOut += nAmount; } + + std::vector saplingEntries; + // find all unspent and unlocked notes in this zaddr + pwalletMain->GetFilteredNotes(saplingEntries, fromaddress); + + CAmount total_value = 0; + + std::vector saplingNoteInputs; + // Decide which sapling notes will be spent + for (const SaplingNoteEntry& entry : saplingEntries) { + CAmount nValue = entry.note.value(); + libzcash::SaplingExtendedSpendingKey extsk; + if (!pwalletMain->GetSaplingExtendedSpendingKey(entry.address, extsk)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find spending key for payment address."); + } + saplingNoteInputs.emplace_back(entry.op, entry.note, nValue, extsk.expsk); + total_value += nValue; + LogPrintf("%s: adding note to spend with value=%s, total_value=%s\n", __func__, FormatMoney(nValue), FormatMoney(total_value) ); + if (total_value >= nTotalOut) { + // we have enough note value to make the tx + LogPrintf("%s: found enough notes, nTotalOut=%s total_value=%s\n", __func__, FormatMoney(nTotalOut), FormatMoney(total_value) ); + break; + } + } + // SIETCH: Sprinkle our cave with some magic privacy zdust // End goal is to have this be as large as possible without slowing xtns down too much // A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations @@ -5400,7 +5426,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut))); } } - } + } } // Use input parameters as the optional context info to be returned by z_getoperationstatus and z_getoperationresult. @@ -5423,8 +5449,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); - std::shared_ptr operation( new AsyncRPCOperation_sendmany(builder, contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo, opret) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(builder, contextualTx, fromaddress, taddrRecipients, zaddrRecipients, saplingNoteInputs, nMinDepth, nFee, contextInfo, opret) ); q->addOperation(operation); + if(fZdebug) LogPrintf("%s: Submitted to async queue\n", __FUNCTION__); AsyncRPCOperationId operationId = operation->getId(); From 90f00ac8a4d56b2aeb5687f15997cfdf7389533d Mon Sep 17 00:00:00 2001 From: Duke Date: Thu, 21 Aug 2025 17:05:16 -0400 Subject: [PATCH 50/63] cleanup --- src/wallet/asyncrpcoperation_sendmany.cpp | 59 ----------------------- 1 file changed, 59 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 8e47993f7..2eb089c66 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -237,12 +237,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { } } - /* - if (isfromzaddr_ && !find_unspent_notes()) { - throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); - } - */ - // Lock UTXOs lock_utxos(); @@ -253,7 +247,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { CAmount z_inputs_total = 0; for (auto t : saplingNoteInputs_) { - //z_inputs_total += t.note.value(); z_inputs_total += std::get<1>(t).value(); } @@ -460,7 +453,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { LogPrintf("%s: ops.size=%d witnesses.size=%d\n", __func__, ops.size(), witnesses.size() ); // Add Sapling spends - //TODO: should be using saplingNoteInputs_ for (size_t i = 0; i < saplingNoteInputs_.size(); i++) { //LOCK2(cs_main, pwalletMain->cs_wallet); @@ -473,14 +465,6 @@ bool AsyncRPCOperation_sendmany::main_impl() { if(fZdebug) LogPrintf("%s: Adding Sapling spend\n", __func__); assert(builder_.AddSaplingSpend(expsk, std::get<1>(saplingNoteInputs_[i]), anchor, witnesses[i].get())); - - /* - // notes we are currently spending should be locked - if(pwalletMain->IsLockedNote(ops[i])) { - } else { - throw JSONRPCError(RPC_WALLET_ERROR, "Note we are spending is not locked!" ); - } - */ } // Add Sapling outputs @@ -698,49 +682,6 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { return t_inputs_.size() > 0; } -/* -// find unspent notes which are also unlocked -bool AsyncRPCOperation_sendmany::find_unspent_notes() { - if(fZdebug) - LogPrintf("%s: For address %s depth=%d\n", __FUNCTION__, fromaddress_.c_str(), mindepth_); - - std::vector saplingEntries; - { - LOCK2(cs_main, pwalletMain->cs_wallet); - // GetFilteredNotes ignores locked notes by default - pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_); - } - - for (auto entry : saplingEntries) { - // locked status of note may have changed since GetFilteredNotes() - // returned data, so we check again - const bool isLocked = pwalletMain->IsLockedNote(entry.op); - if (isLocked) { - LogPrintf("%s: skipping locked note %s:%d\n", __func__, entry.op.hash.ToString().substr(0,10).c_str(), entry.op.n); - continue; - } - - z_sapling_inputs_.push_back(entry); - - std::string data(entry.memo.begin(), entry.memo.end()); - LogPrint("zrpcunsafe", "%s: found unspent Sapling note (txid=%s, vShieldedSpend=%d, amount=%s, memo=%s)\n", - getId(), - entry.op.hash.ToString().substr(0, 10), - entry.op.n, - FormatMoney(entry.note.value()), - HexStr(data).substr(0, 10)); - } - - // sort in descending order, so big notes appear first - std::sort(z_sapling_inputs_.begin(), z_sapling_inputs_.end(), - [](SaplingNoteEntry i, SaplingNoteEntry j) -> bool { - return i.note.value() > j.note.value(); - }); - - return true; -} -*/ - void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { CMutableTransaction rawTx(tx_); From ae170e9899d209cbef50123b69a3d2166ef58911 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 05:43:21 -0400 Subject: [PATCH 51/63] Spendable notes are now locked and 1159 seems to be an irrelevant upstream issue --- src/wallet/asyncrpcoperation_sendmany.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 2eb089c66..5d23d75f6 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -206,8 +206,7 @@ void AsyncRPCOperation_sendmany::main() { } // Notes: -// 1. #1159 Currently there is no limit set on the number of shielded spends, so size of tx could be invalid. -// 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them +// 1. Currently there is no limit set on the number of shielded spends, so size of tx could be invalid. bool AsyncRPCOperation_sendmany::main_impl() { assert(isfromtaddr_ != isfromzaddr_); From 7e3ce02d876705228ec95d728e63772babbcba60 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 06:16:25 -0400 Subject: [PATCH 52/63] Bring back sorting notes descending by value which was in find_unspent_notes() --- src/wallet/rpcwallet.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 482d2997b..859349052 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5286,6 +5286,13 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // find all unspent and unlocked notes in this zaddr pwalletMain->GetFilteredNotes(saplingEntries, fromaddress); + // sort notes from largest to smallest, which means + // we will spend the largest first + std::sort(saplingEntries.begin(), saplingEntries.end(), + [](SaplingNoteEntry i, SaplingNoteEntry j) -> bool { + return i.note.value() > j.note.value(); + }); + CAmount total_value = 0; std::vector saplingNoteInputs; From 4ef3554307ed5e657df12ead112c48cfeea54ed8 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 06:47:27 -0400 Subject: [PATCH 53/63] Update authproxy --- qa/rpc-tests/test_framework/authproxy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py index e55570636..d88d98bc3 100644 --- a/qa/rpc-tests/test_framework/authproxy.py +++ b/qa/rpc-tests/test_framework/authproxy.py @@ -1,3 +1,4 @@ +# Copyright (c) 2016-2025 The Hush developers """ Copyright 2011 Jeff Garzik @@ -40,11 +41,11 @@ import logging from http.client import HTTPConnection, HTTPSConnection, BadStatusLine from urllib.parse import urlparse -USER_AGENT = "AuthServiceProxy/0.1" +USER_AGENT = "HushAuthServiceProxy/0.1" HTTP_TIMEOUT = 600 -log = logging.getLogger("BitcoinRPC") +log = logging.getLogger("RPC") class JSONRPCException(Exception): def __init__(self, rpc_error): From fb7d669f1422e47e012a699a1966f60ba351917b Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 07:09:15 -0400 Subject: [PATCH 54/63] Remove commented out code --- src/wallet/asyncrpcoperation_sendmany.cpp | 27 +---------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 5d23d75f6..448a4bcf8 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -409,33 +409,8 @@ bool AsyncRPCOperation_sendmany::main_impl() { if(fZdebug) LogPrintf("%s: Selecting Sapling notes\n", __FUNCTION__); std::vector ops; - std::vector notes; CAmount sum = 0; - /* - //NOTE: z_sapling_inputs_ is a list of all potential notes to spend - // saplingNoteInputs_ is a list of notes we will actually spend - // and need to lock. It is a subset of z_sapling_inputs_ - for (const auto t : z_sapling_inputs_) { - // locked status of these inputs may have changed, check again - const bool isLocked = pwalletMain->IsLockedNote(t.op); - if (isLocked) { - LogPrintf("%s: skipping locked note %s\n", __func__, t.op.hash.ToString().substr(0,10).c_str()); - continue; - } - - // keep track of currently unlocked notes to lock later on in lock_notes() - saplingNoteInputs_.emplace_back(t.op, t.note, t.note.value() ); - - ops.push_back(t.op); - notes.push_back(t.note); - sum += t.note.value(); - if (sum >= targetAmount) { - break; - } - } - */ - for(const auto t : saplingNoteInputs_) { ops.push_back(std::get<0>(t)); } @@ -455,9 +430,9 @@ bool AsyncRPCOperation_sendmany::main_impl() { for (size_t i = 0; i < saplingNoteInputs_.size(); i++) { //LOCK2(cs_main, pwalletMain->cs_wallet); + //TODO: avoid coredump here if this index does not exist if (!witnesses[i]) { throw JSONRPCError(RPC_WALLET_ERROR, - //strprintf( "Missing witness for Sapling note at outpoint %s", saplingNoteInputs_[i].op.ToString()) strprintf( "Missing witness for Sapling note at outpoint %s", std::get<0>(saplingNoteInputs_[i]).ToString()) ); } From 34829af017dbbe744f02b33c4740433fbf58d47c Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 07:34:11 -0400 Subject: [PATCH 55/63] Avoid coredump if witness index does not exist --- src/wallet/asyncrpcoperation_sendmany.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 448a4bcf8..0c58cb25e 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -428,16 +428,14 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Add Sapling spends for (size_t i = 0; i < saplingNoteInputs_.size(); i++) { - //LOCK2(cs_main, pwalletMain->cs_wallet); - - //TODO: avoid coredump here if this index does not exist - if (!witnesses[i]) { + if (!witnesses.at(i)) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf( "Missing witness for Sapling note at outpoint %s", std::get<0>(saplingNoteInputs_[i]).ToString()) ); } if(fZdebug) LogPrintf("%s: Adding Sapling spend\n", __func__); + assert(builder_.AddSaplingSpend(expsk, std::get<1>(saplingNoteInputs_[i]), anchor, witnesses[i].get())); } From 727f4d9a29fb5afebc1807360476b66eb1be6978 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 11:33:13 -0400 Subject: [PATCH 56/63] Sleep as a hack for lacking fullyNotified in some places --- qa/rpc-tests/lockzins.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index 314bcdb3f..e71c8cfcd 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -94,14 +94,15 @@ class LockZinsTest (BitcoinTestFramework): rpc.generate(1) self.sync_all() + + # syncing is not perfect, oh well + time.sleep(3) + wait_and_assert_operationid_status(self.nodes[0], opid1) wait_and_assert_operationid_status(self.nodes[0], opid2) wait_and_assert_operationid_status(self.nodes[0], opid3) wait_and_assert_operationid_status(self.nodes[0], opid4) - # give time for all z_sendmany's to run - #time.sleep(10) - rpc.z_getoperationstatus() if __name__ == '__main__': From 04ec2be8c882e44fdee17cfd4caa1512512dd74a Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 13:17:36 -0400 Subject: [PATCH 57/63] Add fullyNotified to getblockchaininfo and use it in tests --- qa/rpc-tests/test_framework/util.py | 2 -- src/rpc/blockchain.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index ff1115b88..98d045442 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -57,8 +57,6 @@ def sync_blocks(rpc_connections, wait=1): break time.sleep(wait) - return - # Now that the block counts are in sync, wait for the internal # notifications to finish while True: diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index abcc49c45..5f1394a80 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1335,6 +1335,12 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my obj.push_back(Pair("pruneheight", block->GetHeight())); } + + // this helps our tests work correctly + if (Params().NetworkIDString() == "regtest") { + obj.pushKV("fullyNotified", ChainIsFullyNotified()); + } + return obj; } From aa69b87505f8da3f38596a9c86996db95600ca03 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 21:21:15 -0400 Subject: [PATCH 58/63] These are unrelated to ztxs and should be -debug --- src/txdb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 6a6f7c086..4d402d072 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -271,13 +271,13 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { CDBBatch batch(*this); - if (fZdebug) + if (fDebug) fprintf(stderr, "%s: Writing block files\n", __FUNCTION__); for (const auto& it : fileInfo) { batch.Write(make_pair(DB_BLOCK_FILES, it.first), *it.second); } batch.Write(DB_LAST_BLOCK, nLastFile); - if (fZdebug) + if (fDebug) fprintf(stderr, "%s: Writing block index\n", __FUNCTION__); for (const auto& it : blockinfo) { std::pair key = make_pair(DB_BLOCK_INDEX, it->GetBlockHash()); From a555f64ad99fb9549a71314e60fa4080eff076d1 Mon Sep 17 00:00:00 2001 From: Duke Date: Fri, 22 Aug 2025 21:26:05 -0400 Subject: [PATCH 59/63] Has the sleeper awakened? --- qa/rpc-tests/lockzins.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/lockzins.py b/qa/rpc-tests/lockzins.py index e71c8cfcd..4c46fea0f 100755 --- a/qa/rpc-tests/lockzins.py +++ b/qa/rpc-tests/lockzins.py @@ -95,8 +95,8 @@ class LockZinsTest (BitcoinTestFramework): rpc.generate(1) self.sync_all() - # syncing is not perfect, oh well - time.sleep(3) + # now that we have fullyNotified, this may not be needed? + #time.sleep(3) wait_and_assert_operationid_status(self.nodes[0], opid1) wait_and_assert_operationid_status(self.nodes[0], opid2) From e421dfc6a564fabec437da4261493277a762afda Mon Sep 17 00:00:00 2001 From: Duke Date: Sat, 23 Aug 2025 06:15:33 -0400 Subject: [PATCH 60/63] Improve rpc docs of z_listlockunspent --- src/wallet/rpcwallet.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 859349052..6eeafd012 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2653,12 +2653,15 @@ UniValue z_listlockunspent(const UniValue& params, bool fHelp, const CPubKey& my if (fHelp || params.size() > 0) throw runtime_error( "z_listlockunspent\n" - "\nReturns list of temporarily unspendable outputs.\n" + "\nReturns list of temporarily locked shielded outputs which are currently unspendable. They are locked\n" + "\nbecause they are currently in the process of being spent by an operation such as z_sendmany/z_mergetoaddress/etc.\n" + "\nIf that operation succeeds, they will become spent. If it fails they will be unlocked and become\n" + "\nspendable again.\n" "\nResult:\n" "[\n" " {\n" - " \"txid\" : \"transactionid\", (string) The transaction id locked\n" - " \"vout\" : n (numeric) The vout value\n" + " \"txid\" : \"transactionid\", (string) The transaction id locked\n" + " \"outindex\" : n (integer) The shielded output index\n" " }\n" " ,...\n" "]\n" @@ -2678,7 +2681,7 @@ UniValue z_listlockunspent(const UniValue& params, bool fHelp, const CPubKey& my UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", op.hash.GetHex())); - o.push_back(Pair("n", (int) op.n)); + o.push_back(Pair("outindex", (int) op.n)); ret.push_back(o); } From cb81fc3b9589ebeb7e0bd58f174683756908b725 Mon Sep 17 00:00:00 2001 From: Duke Date: Wed, 24 Sep 2025 09:30:33 -0400 Subject: [PATCH 61/63] Less noise unless -debug is used --- qa/rpc-tests/test_framework/util.py | 4 ++-- src/init.cpp | 12 +++++++++--- src/wallet/asyncrpcoperation_sendmany.cpp | 2 -- test.sh | 3 +++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 98d045442..e8a16251d 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -274,7 +274,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= devnull.close() port = extra_args[3] #port = rpc_port(i) - print("port=%s" % port) + #print("port=%s" % port) username = rpc_username() password = rpc_password() url = "http://%s:%s@%s:%s" % (username, password, rpchost or '127.0.0.1', port[9:]) @@ -283,7 +283,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= proxy = AuthServiceProxy(url, timeout=timewait) else: proxy = AuthServiceProxy(url) - print("created proxy") + #print("created proxy") proxy.url = url # store URL on proxy for info return proxy diff --git a/src/init.cpp b/src/init.cpp index 94bb2d977..4d5b7b3b0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -146,7 +146,9 @@ std::atomic fRequestShutdown(false); void StartShutdown() { - fprintf(stderr,"%s: fRequestShudown=true\n", __FUNCTION__); + if(fDebug) { + fprintf(stderr,"%s: fRequestShudown=true\n", __FUNCTION__); + } fRequestShutdown = true; } bool ShutdownRequested() @@ -208,7 +210,9 @@ void Shutdown() RenameThread(shutoffstr); mempool.AddTransactionsUpdated(1); - fprintf(stderr,"%s: stopping HUSH HTTP/REST/RPC\n", __FUNCTION__); + if(fDebug) { + fprintf(stderr,"%s: stopping HUSH HTTP/REST/RPC\n", __FUNCTION__); + } StopHTTPRPC(); StopREST(); StopRPC(); @@ -225,7 +229,9 @@ void Shutdown() GenerateBitcoins(false, 0); #endif #endif - fprintf(stderr,"%s: stopping node\n", __FUNCTION__); + if(fDebug) { + fprintf(stderr,"%s: stopping node\n", __FUNCTION__); + } StopNode(); StopTorControl(); UnregisterNodeSignals(GetNodeSignals()); diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 0c58cb25e..f2a698d05 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -776,7 +776,6 @@ void AsyncRPCOperation_sendmany::lock_notes() { LogPrintf("%s: found %lu notes to lock\n", __func__, saplingNoteInputs_.size() ); for (auto note : saplingNoteInputs_) { if(pwalletMain->IsLockedNote(std::get<0>(note))) { - //TODO: deal with this LogPrintf("%s: note already locked!\n", __func__); } else { pwalletMain->LockNote(std::get<0>(note)); @@ -790,7 +789,6 @@ void AsyncRPCOperation_sendmany::unlock_notes() { LogPrintf("%s: found %lu notes to unlock\n", __func__, saplingNoteInputs_.size() ); for (auto note : saplingNoteInputs_) { if(pwalletMain->IsLockedNote(std::get<0>(note))) { - //TODO: deal with this pwalletMain->UnlockNote(std::get<0>(note)); } else { LogPrintf("%s: note already unlocked!\n", __func__); diff --git a/test.sh b/test.sh index 5d81d4850..a48d5f3f8 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Copyright 2016-2025 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #export PYTHON_DEBUG=1 export PYTHONPATH=./qa/rpc-tests/test_framework/ From 2f7082c7135d5fd87a3d0755d77854fb5fc2677b Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 13 Oct 2025 14:28:54 -0400 Subject: [PATCH 62/63] Update relnotes --- doc/relnotes/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 21d952a27..65bacb9fb 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -10,6 +10,19 @@ and no longer on Github, since they banned Duke Leto and also because they censor many people around the world and work with evil organizations. They also use all your "private" repos to train their AI. +# Hush 3.10.5 "" + + * Concurrent `z_sendmany` now works + * A longstanding bug relating to run multiple `z_sendmany` operations at + once has been fixed. You can now queue up many `z_sendmany` operations + and they will succeed because they now understand how to avoid spending + coins that another `z_sendmany` process is trying to spend. + * New RPC `z_listlockunspent` + * Lists shielded notes (coins inside a zaddr) which are temporarily unspendable because an RPC process is currently trying to spend them. + * If that operation succeeds, they will become spent. If it fails they will be unlocked and become spendable again. + * Fixed DragonX checkpoints + * ... + # Hush 3.10.4 "Hazy Hākuturi" This is an OPTIONAL but RECOMMENDED upgrade. Some seed nodes have changed so if you are having From 2980108cdc54757d38c0ff17406180145a5b0cc5 Mon Sep 17 00:00:00 2001 From: Duke Date: Mon, 13 Oct 2025 14:45:10 -0400 Subject: [PATCH 63/63] Update relnotes --- doc/relnotes/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 65bacb9fb..cb9172162 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -21,7 +21,10 @@ evil organizations. They also use all your "private" repos to train their AI. * Lists shielded notes (coins inside a zaddr) which are temporarily unspendable because an RPC process is currently trying to spend them. * If that operation succeeds, they will become spent. If it fails they will be unlocked and become spendable again. * Fixed DragonX checkpoints - * ... + * Hush checkpoints were mistakenly listed as checkpoints in the 3.10.4 + release, which caused some nodes to be unable to sync. + * This release fixes this issue. + * Updated test framework and tests which allowed the fixing of the `z_sendmany` bug above # Hush 3.10.4 "Hazy Hākuturi"