From 30a6ca44479d520a7f7d044b905aed78e54c7247 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 18:47:15 -0400 Subject: [PATCH 001/115] Built-in stratum server --- src/Makefile.am | 2 + src/chainparamsbase.h | 1 + src/init.cpp | 14 + src/rpc/register.h | 6 +- src/stratum.cpp | 2132 +++++++++++++++++++++++++++++++++++++++++ src/stratum.h | 21 + 6 files changed, 2175 insertions(+), 1 deletion(-) create mode 100644 src/stratum.cpp create mode 100644 src/stratum.h diff --git a/src/Makefile.am b/src/Makefile.am index 0711b52cc..abdf0f874 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -203,6 +203,7 @@ BITCOIN_CORE_H = \ script/standard.h \ serialize.h \ streams.h \ + stratum.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ support/cleanse.h \ @@ -315,6 +316,7 @@ libbitcoin_server_a_SOURCES = \ rpc/server.cpp \ script/serverchecker.cpp \ script/sigcache.cpp \ + stratum.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 9379e95b4..1fbdec8bd 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -40,6 +40,7 @@ public: const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } + int StratumPort() const { return (RPCPort() + 1000); } protected: CBaseChainParams() {} diff --git a/src/init.cpp b/src/init.cpp index 01916ee76..acce70062 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -36,6 +36,7 @@ #include "httprpc.h" #include "key.h" #include "notarizationdb.h" +#include "stratum.h" #ifdef ENABLE_MINING #include "key_io.h" @@ -89,6 +90,7 @@ using namespace std; #include "hush_defs.h" +static const bool DEFAULT_STRATUM_ENABLE = false; extern void ThreadSendAlert(); extern bool hush_dailysnapshot(int32_t height); extern int32_t HUSH_LOADINGBLOCKS; @@ -187,6 +189,7 @@ static boost::scoped_ptr globalVerifyHandle; void Interrupt(boost::thread_group& threadGroup) { + InterruptStratumServer(); InterruptHTTPServer(); InterruptHTTPRPC(); InterruptRPC(); @@ -218,6 +221,7 @@ void Shutdown() StopHTTPRPC(); StopREST(); StopRPC(); + StopStratumServer(); StopHTTPServer(); #ifdef ENABLE_WALLET if (pwalletMain) @@ -582,6 +586,13 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-metricsui", _("Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise)")); strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600)); } + + strUsage += HelpMessageGroup(_("Stratum server options:")); + strUsage += HelpMessageOpt("-stratum", _("Enable stratum server (default: off)")); + strUsage += HelpMessageOpt("-stratumbind=", _("Bind to given address to listen for Stratum work requests. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); + strUsage += HelpMessageOpt("-stratumport=", strprintf(_("Listen for Stratum work requests on (default: %u or testnet: %u)"), BaseParams().StratumPort(), BaseParams().StratumPort())); + strUsage += HelpMessageOpt("-stratumallowip=", _("Allow Stratum work requests from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); + strUsage += HelpMessageGroup(_("Hush Smart Chain options:")); strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash")); strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60")); @@ -941,10 +952,13 @@ static void ZC_LoadParams( bool AppInitServers(boost::thread_group& threadGroup) { + fprintf(stderr,"%s: start\n",__func__); RPCServer::OnStopped(&OnRPCStopped); RPCServer::OnPreCommand(&OnRPCPreCommand); if (!InitHTTPServer()) return false; + if (GetBoolArg("-stratum", DEFAULT_STRATUM_ENABLE) && !InitStratumServer()) + return false; if (!StartRPC()) return false; if (!StartHTTPRPC()) diff --git a/src/rpc/register.h b/src/rpc/register.h index 2493e447b..7c545da48 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -1,7 +1,7 @@ +// Copyright (c) 2016-2021 The Hush developers // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html - /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -38,6 +38,9 @@ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); /** Register test transaction RPC commands */ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); +/** Register stratum RPC commands */ +void RegisterStratumRPCCommands(CRPCTable &tableRPC); + static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) { @@ -49,6 +52,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) #ifdef TESTMODE RegisterTesttransactionsRPCCommands(tableRPC); #endif + RegisterStratumRPCCommands(tableRPC); } #endif diff --git a/src/stratum.cpp b/src/stratum.cpp new file mode 100644 index 000000000..3619c9ea1 --- /dev/null +++ b/src/stratum.cpp @@ -0,0 +1,2132 @@ +// Copyright (c) 2021-2021 The Hush developers +// Copyright (c) 2020-2021 The Freicoin Developers +// Copyright (c) 2021-2021 Decker +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +// Stratum protocol: +// - https://en.bitcoin.it/wiki/Stratum_mining_protocol - Stratum mining protocol +// - https://github.com/slushpool/poclbm-zcash/wiki/Stratum-protocol-changes-for-ZCash - Stratum protocol changes for ZCash + +#include "stratum.h" +#include "base58.h" +#include "chainparams.h" +#include "consensus/validation.h" +#include "crypto/sha256.h" +#include "httpserver.h" +#include "miner.h" +#include "netbase.h" +#include "net.h" +#include "rpc/server.h" +#include "serialize.h" +#include "streams.h" +#include "sync.h" +#include "txmempool.h" +#include "uint256.h" +#include "util.h" +#include "utilstrencodings.h" +#include +#include // for std::reverse +#include +#include + +#include // for boost::trim +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif + +#include "main.h" // cs_main +#include +#include "ui_interface.h" +#include // make_unique + +#include +#include + +#include +#include + +// https://en.cppreference.com/w/cpp/types/integer - cinttypes for format constants, like PRId64, etc. +#include + + +extern uint16_t ASSETCHAINS_RPCPORT; // don't want to include komodo_globals.h +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); // rpc/blockchain.cpp +bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); // src/core_read.cpp + +static const long jobRebroadcastTimeout = 30; +static const long txMemPoolCheckTimeout = 10; + +/** + * Begin of helper routines, + * included: missed in httpserver.cpp in our codebase, missed + * constructors for CSubNet(...), etc. +*/ + +namespace { // better to use anonymous namespace for helper routines + + class CStratumParams { + private: + const arith_uint256 defaultHashTarget; + arith_uint256 currentHashTarget; + public: + CStratumParams() : defaultHashTarget(UintToArith256(uint256S("00ffff0000000000000000000000000000000000000000000000000000000000"))), + currentHashTarget(defaultHashTarget), fAllowLowDiffShares(false), fCheckEquihashSolution(true), + fstdErrDebugOutput(false) { } + ~CStratumParams() {} + + void setTarget(const arith_uint256& target) { currentHashTarget = target; } + arith_uint256 getTarget() { return currentHashTarget; } + + bool fAllowLowDiffShares; + bool fCheckEquihashSolution; + bool fstdErrDebugOutput; + + } instance_of_cstratumparams; + + /** Check if a network address is allowed to access the Stratum server */ + static bool ClientAllowed(const std::vector& allowed_subnets, const CNetAddr& netaddr) + { + if (!netaddr.IsValid()) + return false; + for(const CSubNet& subnet : allowed_subnets) + if (subnet.Match(netaddr)) + return true; + return false; + } + + /** Initialize ACL list for Stratum server */ + static bool InitStratumAllowList(std::vector& allowed_subnets) + { + allowed_subnets.clear(); + allowed_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet + allowed_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost + if (mapMultiArgs.count("-stratumallowip")) { + const std::vector& vAllow = mapMultiArgs["-stratumallowip"]; + for(const std::string& strAllow : vAllow) { + CSubNet subnet(strAllow); + if (!subnet.IsValid()) { + uiInterface.ThreadSafeMessageBox( + strprintf("Invalid -stratumallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), + "", CClientUIInterface::MSG_ERROR); + return false; + } + allowed_subnets.push_back(subnet); + } + } + return true; + } + + double GetDifficultyFromBits(uint32_t bits) { + + uint32_t powLimit = UintToArith256(Params().GetConsensus().powLimit).GetCompact(); + int nShift = (bits >> 24) & 0xff; + int nShiftAmount = (powLimit >> 24) & 0xff; + + double dDiff = + (double)(powLimit & 0x00ffffff) / + (double)(bits & 0x00ffffff); + + while (nShift < nShiftAmount) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > nShiftAmount) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; + } + + std::string DateTimeStrPrecise() // or we can use standart one, like DateTimeStrFormat("[%Y-%m-%d %H:%M:%S.%f]", GetTime()) + { + // https://stackoverflow.com/questions/28136660/format-a-posix-time-with-just-3-digits-in-fractional-seconds + // https://www.boost.org/doc/libs/1_35_0/doc/html/date_time/date_time_io.html#date_time.format_flags + + // std::locale takes ownership of the pointer + boost::posix_time::ptime const date_time = boost::posix_time::microsec_clock::local_time(); + std::locale loc(std::locale::classic(), new boost::posix_time::time_facet("[%Y-%m-%d %H:%M:%S.%f] ")); + std::stringstream ss; + ss.imbue(loc); + // ss << boost::posix_time::from_time_t(nTime); + ss << date_time; + return ss.str(); + } + + std::string get_stripped_username(const std::string& username) { + std::string res(username); + size_t dotpos = username.find('.'); + if (dotpos != std::string::npos) + res.resize(dotpos); + return res; + } + + // C++11 map initialization + const std::map mapColors = { + { "cl_N", "\x1B[0m" }, + { "cl_RED", "\x1B[31m" }, + { "cl_GRN", "\x1B[32m" }, + { "cl_YLW", "\x1B[33m" }, + { "cl_BLU", "\x1B[34m" }, + { "cl_MAG", "\x1B[35m" }, + { "cl_CYN", "\x1B[36m" }, + { "cl_BLK", "\x1B[22;30m" }, /* black */ + { "cl_RD2", "\x1B[22;31m" }, /* red */ + { "cl_GR2", "\x1B[22;32m" }, /* green */ + { "cl_YL2", "\x1B[22;33m" }, /* dark yellow */ + { "cl_BL2", "\x1B[22;34m" }, /* blue */ + { "cl_MA2", "\x1B[22;35m" }, /* magenta */ + { "cl_CY2", "\x1B[22;36m" }, /* cyan */ + { "cl_SIL", "\x1B[22;37m" }, /* gray */ + { "cl_LRD", "\x1B[01;31m" }, /* light red */ + { "cl_LGR", "\x1B[01;32m" }, /* light green */ + { "cl_LYL", "\x1B[01;33m" }, /* tooltips */ + { "cl_LBL", "\x1B[01;34m" }, /* light blue */ + { "cl_LMA", "\x1B[01;35m" }, /* light magenta */ + { "cl_LCY", "\x1B[01;36m" }, /* light cyan */ + { "cl_WHT", "\x1B[01;37m" }, /* white */ + }; + + enum ColorType + { + cl_N, cl_RED, cl_GRN, cl_YLW, cl_BLU, cl_MAG, cl_CYN, cl_BLK, cl_RD2, cl_GR2, cl_YL2, cl_BL2, cl_MA2, cl_CY2, cl_SIL, cl_LRD, cl_LGR, cl_LYL, cl_LBL, cl_LMA, cl_LCY, cl_WHT + }; + + char const* ColorTypeNames[]= + { + "\x1B[0m" , "\x1B[31m" , "\x1B[32m" , "\x1B[33m" , "\x1B[34m" , + "\x1B[35m" , "\x1B[36m" , "\x1B[22;30m", "\x1B[22;31m", "\x1B[22;32m", + "\x1B[22;33m", "\x1B[22;34m", "\x1B[22;35m", "\x1B[22;36m", "\x1B[22;37m", + "\x1B[01;31m", "\x1B[01;32m", "\x1B[01;33m", "\x1B[01;34m", "\x1B[01;35m", + "\x1B[01;36m", "\x1B[01;37m" + }; +} + +namespace ccminer { + + bool hex2bin(void *output, const char *hexstr, size_t len) + { + unsigned char *p = (unsigned char *) output; + char hex_byte[4]; + char *ep; + + hex_byte[2] = '\0'; + + while (*hexstr && len) { + if (!hexstr[1]) { + LogPrint("stratum", "hex2bin str truncated"); + return false; + } + hex_byte[0] = hexstr[0]; + hex_byte[1] = hexstr[1]; + *p = (unsigned char) strtol(hex_byte, &ep, 16); + if (*ep) { + LogPrint("stratum", "hex2bin failed on '%s'", hex_byte); + return false; + } + p++; + hexstr += 2; + len--; + } + + return (len == 0 && *hexstr == 0) ? true : false; + } + + // equi/equi-stratum.cpp + double target_to_diff_equi(uint32_t* target) + { + unsigned char* tgt = (unsigned char*) target; + uint64_t m = + (uint64_t)tgt[30] << 24 | + (uint64_t)tgt[29] << 16 | + (uint64_t)tgt[28] << 8 | + (uint64_t)tgt[27] << 0; + + if (!m) + return 0.; + else + return (double)0xffff0000UL/m; + } + + void diff_to_target_equi(uint32_t *target, double diff) + { + uint64_t m; + int k; + + for (k = 6; k > 0 && diff > 1.0; k--) + diff /= 4294967296.0; + m = (uint64_t)(4294901760.0 / diff); + if (m == 0 && k == 6) + memset(target, 0xff, 32); + else { + memset(target, 0, 32); + target[k + 1] = (uint32_t)(m >> 8); + target[k + 2] = (uint32_t)(m >> 40); + //memset(target, 0xff, 6*sizeof(uint32_t)); + for (k = 0; k < 28 && ((uint8_t*)target)[k] == 0; k++) + ((uint8_t*)target)[k] = 0xff; + } + } + + void kmd_diff_to_target_equi(uint32_t *target, double diff) + { + uint64_t m; + int k; + + for (k = 6; k > 0 && diff > 1.0; k--) + diff /= (double)((uint64_t)0x100000000); + m = (uint64_t)((uint64_t)0x0f0f0f0f / diff); + if (m == 0 && k == 6) + memset(target, 0xff, 32); + else { + memset(target, 0, 32); + target[k + 1] = (uint32_t)(m >> 8); + target[k + 2] = (uint32_t)(m >> 40); + //memset(target, 0xff, 6*sizeof(uint32_t)); + + for (k = 0; k < 28 && ((uint8_t*)target)[k] == 0; k++) + ((uint8_t*)target)[k] = 0xff; + for (k = 0; k < 32; k++) ((uint8_t*)target)[31-k] = ((uint8_t*)target)[31-k-1]; + ((uint8_t*)target)[0] = 0xff; + } + } + + /* compute nbits to get the network diff */ + double equi_network_diff(uint32_t nbits) + { + //KMD bits: "1e 015971", + //KMD target: "00 00 015971000000000000000000000000000000000000000000000000000000", + //KMD bits: "1d 686aaf", + //KMD target: "00 0000 686aaf0000000000000000000000000000000000000000000000000000", + // uint32_t nbits = work->data[26]; + + uint32_t bits = (nbits & 0xffffff); + int16_t shift = (/*swab32*/bswap_32(nbits) & 0xff); + shift = (31 - shift) * 8; // 8 bits shift for 0x1e, 16 for 0x1d + uint64_t tgt64 = /*swab32*/bswap_32(bits); + tgt64 = tgt64 << shift; + // applog_hex(&tgt64, 8); + uint8_t net_target[32] = { 0 }; + for (int b=0; b<8; b++) + net_target[31-b] = ((uint8_t*)&tgt64)[b]; + // applog_hex(net_target, 32); + double d = target_to_diff_equi((uint32_t*)net_target); + return d; + } + + double equi_stratum_target_to_diff(const std::string& target) + { + uint8_t target_bin[32], target_be[32]; + + const char *target_hex = target.c_str(); + if (!target_hex || strlen(target_hex) == 0) + return false; + + hex2bin(target_bin, target_hex, 32); + memset(target_be, 0xff, 32); + int filled = 0; + for (int i=0; i<32; i++) { + if (filled == 3) break; + target_be[31-i] = target_bin[i]; + if (target_bin[i]) filled++; + } + + double d = target_to_diff_equi((uint32_t*) &target_be); + return d; + } + + /* Subtract the `struct timeval' values X and Y, + storing the result in RESULT. + Return 1 if the difference is negative, otherwise 0. */ + int timeval_subtract(struct timeval *result, struct timeval *x, + struct timeval *y) + { + /* Perform the carry for the later subtraction by updating Y. */ + if (x->tv_usec < y->tv_usec) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + } + if (x->tv_usec - y->tv_usec > 1000000) { + int nsec = (x->tv_usec - y->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + * `tv_usec' is certainly positive. */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* Return 1 if result is negative. */ + return x->tv_sec < y->tv_sec; + } + +} + +/** + * End of helper routines +*/ + +struct StratumClient +{ + evconnlistener* m_listener; + evutil_socket_t m_socket; + bufferevent* m_bev; + CService m_from; + int m_nextid; + uint256 m_secret; + + CService GetPeer() const + { return m_from; } + + std::string m_client; + + bool m_authorized; + CBitcoinAddress m_addr; + double m_mindiff; + + uint32_t m_version_rolling_mask; + + CBlockIndex* m_last_tip; + bool m_second_stage; + bool m_send_work; + + bool m_supports_aux; + std::set m_aux_addr; + + bool m_supports_extranonce; + + StratumClient() : m_listener(0), m_socket(0), m_bev(0), m_nextid(0), m_authorized(false), m_mindiff(0.0), m_version_rolling_mask(0x00000000), m_last_tip(0), m_second_stage(false), m_send_work(false), m_supports_aux(false), m_supports_extranonce(false) { GenSecret(); } + StratumClient(evconnlistener* listener, evutil_socket_t socket, bufferevent* bev, CService from) : m_listener(listener), m_socket(socket), m_bev(bev), m_nextid(0), m_from(from), m_authorized(false), m_mindiff(0.0), m_version_rolling_mask(0x00000000), m_last_tip(0), m_second_stage(false), m_send_work(false), m_supports_aux(false), m_supports_extranonce(false) { GenSecret(); } + + void GenSecret(); + std::vector ExtraNonce1(uint256 job_id) const; +}; + +void StratumClient::GenSecret() +{ + GetRandBytes(m_secret.begin(), 32); +} + +std::vector StratumClient::ExtraNonce1(uint256 job_id) const +{ + CSHA256 nonce_hasher; + nonce_hasher.Write(m_secret.begin(), 32); + + if (m_supports_extranonce) { + nonce_hasher.Write(job_id.begin(), 32); + } + + uint256 job_nonce; + nonce_hasher.Finalize(job_nonce.begin()); + return {job_nonce.begin(), job_nonce.begin()+8}; +} + +struct StratumWork { + CBlockTemplate m_block_template; + // First we generate the segwit commitment for the miner's coinbase with + // ComputeFastMerkleBranch. + std::vector m_cb_wit_branch; + // Then we compute the initial right-branch for the block-tx Merkle tree + // using ComputeStableMerkleBranch... + std::vector m_bf_branch; + // ...which is appended to the end of m_cb_branch so we can compute the + // block's hashMerkleRoot with ComputeMerkleBranch. + std::vector m_cb_branch; + bool m_is_witness_enabled; + + int32_t nHeight; + std::string local_diff; + + // The cached 2nd-stage auxiliary hash value, if an auxiliary proof-of-work + // solution has been found. + boost::optional m_aux_hash2; + + StratumWork() : m_is_witness_enabled(false),nHeight(0) { }; + StratumWork(const CBlockTemplate& block_template, bool is_witness_enabled); + + CBlock& GetBlock() + { return m_block_template.block; } + const CBlock& GetBlock() const + { return m_block_template.block; } +}; + +StratumWork::StratumWork(const CBlockTemplate& block_template, bool is_witness_enabled) + : m_block_template(block_template) + , m_is_witness_enabled(is_witness_enabled), nHeight(0) +{ + // Generate the block-witholding secret for the work unit. + + std::vector leaves; + for (const auto& tx : m_block_template.block.vtx) { + leaves.push_back(tx.GetHash()); + } + + std::vector vMerkleTree; uint256 merkleRoot; bool fMutated; + + merkleRoot = BuildMerkleTree(&fMutated, leaves, vMerkleTree); + m_cb_branch = GetMerkleBranch(0, leaves.size(), vMerkleTree); + // m_cb_branch = ComputeMerkleBranch(leaves, 0); +}; + +//! Critical seciton guarding access to any of the stratum global state +static CCriticalSection cs_stratum; + +//! List of subnets to allow stratum connections from +static std::vector stratum_allow_subnets; + +//! Bound stratum listening sockets +static std::map bound_listeners; + +//! Active miners connected to us +static std::map subscriptions; + +//! Mapping of stratum method names -> handlers +static std::map > stratum_method_dispatch; + +//! A mapping of job_id -> work templates +static std::map work_templates; + +//! The job_id of the first work unit to have its auxiliary proof-of-work solved +//! for the current block, or boost::none if no solution has been returned yet. +static boost::optional half_solved_work; + +//! A thread to watch for new blocks and send mining notifications +static boost::thread block_watcher_thread; + +std::string HexInt4(uint32_t val) +{ + std::vector vch; + vch.push_back((val >> 24) & 0xff); + vch.push_back((val >> 16) & 0xff); + vch.push_back((val >> 8) & 0xff); + vch.push_back( val & 0xff); + return HexStr(vch); +} + +uint32_t ParseHexInt4(const UniValue& hex, const std::string& name) +{ + std::vector vch = ParseHexV(hex, name); + if (vch.size() != 4) { + throw JSONRPCError(RPC_INVALID_PARAMETER, name+" must be exactly 4 bytes / 8 hex"); + } + uint32_t ret = 0; + ret |= vch[0] << 24; + ret |= vch[1] << 16; + ret |= vch[2] << 8; + ret |= vch[3]; + return ret; +} + +uint256 ParseUInt256(const UniValue& hex, const std::string& name) +{ + if (!hex.isStr()) { + throw std::runtime_error(name+" must be a hexidecimal string"); + } + std::vector vch = ParseHex(hex.get_str()); + if (vch.size() != 32) { + throw std::runtime_error(name+" must be exactly 32 bytes / 64 hex"); + } + uint256 ret; + std::copy(vch.begin(), vch.end(), ret.begin()); + return ret; +} + +static double ClampDifficulty(const StratumClient& client, double diff) +{ + if (client.m_mindiff > 0) { + diff = client.m_mindiff; + } + diff = std::max(diff, 0.001); + return diff; +} + +static std::string GetExtraNonceRequest(StratumClient& client, const uint256& job_id) +{ + // https://en.bitcoin.it/wiki/Stratum_mining_protocol#mining.set_extranonce + // mining.set_extranonce("extranonce1", extranonce2_size) + + std::string ret; + if (client.m_supports_extranonce) + { + std::vector extranonce1 = client.ExtraNonce1(job_id); + + const std::string k_extranonce_req = std::string() + + "{" + + "\"id\":"; + const std::string k_extranonce_req2 = std::string() + + "," + + "\"method\":\"mining.set_extranonce\"," + + "\"params\":[" + + "\""; + const std::string k_extranonce_req3 = std::string() + + "\"," // extranonce1 + + strprintf("%d", 32 - extranonce1.size()) // extranonce2.size() = 32 - extranonce1.size() + + "]" + + "}" + + "\n"; + + ret = k_extranonce_req + + strprintf("%d", client.m_nextid++) + + k_extranonce_req2 + + HexStr(extranonce1) + + k_extranonce_req3; + } + return ret; +} + +/** + * @brief + * + * @param client + * @param current_work + * @param addr + * @param extranonce1 + * @param extranonce2 + * @param cb + * @param bf + * @param cb_branch + */ +void CustomizeWork(const StratumClient& client, const StratumWork& current_work, const CBitcoinAddress& addr, const std::vector& extranonce1, const std::vector& extranonce2, CMutableTransaction& cb, CMutableTransaction& bf, std::vector& cb_branch) +{ + if (current_work.GetBlock().vtx.empty()) { + const std::string msg = strprintf("%s: no transactions in block template; unable to submit work", __func__); + LogPrint("stratum", "%s\n", msg); + throw std::runtime_error(msg); + } + + cb = CMutableTransaction(current_work.GetBlock().vtx[0]); + + if (cb.vin.size() != 1) { + const std::string msg = strprintf("%s: unexpected number of inputs; is this even a coinbase transaction?", __func__); + LogPrint("stratum", "%s\n", msg); + throw std::runtime_error(msg); + } + + std::vector nonce(extranonce1); + + if ((nonce.size() + extranonce2.size()) != 32) { + const std::string msg = strprintf("%s: unexpected combined nonce length: extranonce1(%d) + extranonce2(%d) != 32; unable to submit work", __func__, nonce.size(), extranonce2.size()); + LogPrint("stratum", "%s\n", msg); + throw std::runtime_error(msg); + } + nonce.insert(nonce.end(), extranonce2.begin(), extranonce2.end()); + + // nonce = extranonce1 + extranonce2 + // if (instance_of_cstratumparams.fstdErrDebugOutput) { + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " nonce = " << HexStr(nonce) << std::endl; + // } + + if (cb.vin.empty()) { + const std::string msg = strprintf("%s: first transaction is missing coinbase input; unable to customize work to miner", __func__); + LogPrint("stratum", "%s\n", msg); + throw std::runtime_error(msg); + } + // cb.vin[0].scriptSig = + // CScript() + // << cb.lock_height + // << nonce; + + /* actually we will change only cb destination on the miner address */ + { + if (cb.vout.empty()) { + const std::string msg = strprintf("%s: coinbase transaction is missing outputs; unable to customize work to miner", __func__); + LogPrint("stratum", "%s\n", msg); + throw std::runtime_error(msg); + } + if (cb.vout[0].scriptPubKey == (CScript() << OP_FALSE)) { + cb.vout[0].scriptPubKey = GetScriptForDestination(addr.Get()); + } + } + + // cb_branch = current_work.m_cb_branch; +} + +std::string GetWorkUnit(StratumClient& client) +{ + // LOCK(cs_main); + + /* if (!g_connman) { + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + } */ + + /* if (!Params().MineBlocksOnDemand() && g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) { + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Komodo is not connected!"); + } */ + + bool fvNodesEmpty; + { + LOCK(cs_vNodes); + fvNodesEmpty = vNodes.empty(); + } + + if (Params().MiningRequiresPeers() && fvNodesEmpty) + { + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Komodo is not connected!"); + } + + if (IsInitialBlockDownload()) { + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Komodo is downloading blocks..."); + } + + if (!client.m_authorized && client.m_aux_addr.empty()) { + throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a Komodo address as the username."); + } + + static CBlockIndex* tip = NULL; // pindexPrev + static uint256 job_id; + static unsigned int transactions_updated_last = 0; + static int64_t last_update_time = 0; + + // rpc/mining.cpp -> getblocktemplate -> Update block + if ( tip != chainActive.Tip() || + (mempool.GetTransactionsUpdated() != transactions_updated_last && (GetTime() - last_update_time) > 5) || + !work_templates.count(job_id)) + { + CBlockIndex *tip_new = chainActive.Tip(); + + /** + * We will check script later inside CustomizeWork, if it will be == CScript() << OP_FALSE it will mean + * that work need to be customized, and in that case cb.vout[0],scriptPubKey will be set to GetScriptForDestination(addr.Get()) . + * In other words to the address with which stratum client is authorized. + */ + const CScript scriptDummy = CScript() << OP_FALSE; + std::unique_ptr new_work(CreateNewBlock(CPubKey(), scriptDummy, HUSH_MAXGPUCOUNT, false)); // std::unique_ptr new_work = BlockAssembler(Params()).CreateNewBlock(script); + + /* test values for debug */ + // new_work->block.nBits = 0x200f0f0f; + // new_work->block.nTime = 1623567886; + // new_work->block.hashPrevBlock = uint256S("027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71"); + // new_work->block.hashMerkleRoot = uint256S("29f0e769c762b691d81d31bbb603719a94ef04d53d332f7de5e5533ddfd08e19"); + // new_work->block.hashFinalSaplingRoot = uint256S("3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb"); + // DecodeHexTx(new_work->block.vtx[0], "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff01aa2ce73b0000000023210325b4ca6736f90679f712be1454c5302050aae6edb51b0d2a051156bc868fec16ac4aabc560"); + + if (!new_work) { + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + } + + // if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << "hashMerkleRoot = " << new_work->block.hashMerkleRoot.ToString() << std::endl; + + // So that block.GetHash() is correct + //new_work->block.hashMerkleRoot = BlockMerkleRoot(new_work->block); + new_work->block.hashMerkleRoot = new_work->block.BuildMerkleTree(); + + // NB! here we have merkle with scriptDummy script in coinbase, after CustomizeWork we should recalculate it (!) + // if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << "hashMerkleRoot = " << new_work->block.hashMerkleRoot.ToString() << std::endl; + + job_id = new_work->block.GetHash(); + //work_templates[job_id] = StratumWork(*new_work, new_work->block.vtx[0]->HasWitness()); + work_templates[job_id] = StratumWork(*new_work, false); + + tip = tip_new; + + transactions_updated_last = mempool.GetTransactionsUpdated(); + last_update_time = GetTime(); + + LogPrint("stratum", "New stratum block template (%d total): %s\n", work_templates.size(), HexStr(job_id.begin(), job_id.end())); + + // Remove any old templates + std::vector old_job_ids; + boost::optional oldest_job_id = boost::none; + uint32_t oldest_job_nTime = last_update_time; + for (const auto& work_template : work_templates) { + // If, for whatever reason the new work was generated with + // an old nTime, don't erase it! + if (work_template.first == job_id) { + continue; + } + // Build a list of outdated work units to free. + if (work_template.second.GetBlock().nTime < (last_update_time - 900)) { + old_job_ids.push_back(work_template.first); + } + // Track the oldest work unit, in case we have too much + // recent work. + if (work_template.second.GetBlock().nTime <= oldest_job_nTime) { + oldest_job_id = work_template.first; + oldest_job_nTime = work_template.second.GetBlock().nTime; + } + } + // Remove all outdated work. + for (const auto& old_job_id : old_job_ids) { + work_templates.erase(old_job_id); + LogPrint("stratum", "Removed outdated stratum block template (%d total): %s\n", work_templates.size(), HexStr(old_job_id.begin(), old_job_id.end())); + } + // Remove the oldest work unit if we're still over the maximum + // number of stored work templates. + if (work_templates.size() > 30 && oldest_job_id) { + work_templates.erase(oldest_job_id.get()); + LogPrint("stratum", "Removed oldest stratum block template (%d total): %s\n", work_templates.size(), HexStr(oldest_job_id.get().begin(), oldest_job_id.get().end())); + } + } + + StratumWork& current_work = work_templates[job_id]; + + + CBlockIndex tmp_index; + + // Native proof-of-work difficulty + tmp_index.nBits = current_work.GetBlock().nBits; + double diff = ClampDifficulty(client, GetDifficulty(&tmp_index)); + + UniValue set_target(UniValue::VOBJ); + set_target.push_back(Pair("id", client.m_nextid++)); + set_target.push_back(Pair("method", "mining.set_target")); + UniValue set_target_params(UniValue::VARR); + + std::string strTarget; // set_target + { + arith_uint256 hashTarget; bool fNegative,fOverflow; + /* + + // Targets Table Example: komodo diff and ccminer diff are different (!), + // Komodo diff = NiceHash diff, ccminer_diff = Yiimp diff. + + hashTarget.SetCompact(HUSH_MINDIFF_NBITS,&fNegative,&fOverflow); // blkhdr.nBits + hashTarget = UintToArith256(uint256S("0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f")); + hashTarget.SetHex("0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); + + hashTarget.SetHex("00ffff0000000000000000000000000000000000000000000000000000000000"); // komodo_diff = 15.0591, ccminer_diff = 1 + hashTarget.SetHex("003fffc000000000000000000000000000000000000000000000000000000000"); // komodo_diff = 60.2362, ccminer_diff = 4 + hashTarget.SetHex("0007fff800000000000000000000000000000000000000000000000000000000"); // komodo_diff = 481.89, ccminer_diff = 31.9999 + hashTarget.SetHex("c7ff3800ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // komodo_diff = 0.0752956, ccminer_diff = 1.00303 + hashTarget.SetHex("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); // komodo_diff = 1, ccminer_diff = 16.9956 + */ + + arith_uint256 aHashTarget = instance_of_cstratumparams.getTarget(); + + // arith_uint256 aHashTarget = UintToArith256(uint256S("00ffff0000000000000000000000000000000000000000000000000000000000")); // 1.0 + // aHashTarget = aHashTarget / 8704; // komodo_diff = 131074 (NiceHash), ccminer_diff = 8704 (Yiimp) + + /* here we can adjust diff by some algo, note that 00ffff0000000000000000000000000000000000000000000000000000000000 / 8704 = + 0000078780000000000000000000000000000000000000000000000000000000, which is equivalent to komodo_diff = 131074 (NiceHash), + ccminer_diff = 8704 (Yiimp) + */ + + hashTarget = aHashTarget; + strTarget = hashTarget.GetHex(); + current_work.local_diff = strTarget; + + if (instance_of_cstratumparams.fstdErrDebugOutput) { + std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << + strprintf(" target = %s, komodo_diff = %g, ccminer_diff = %g", + strTarget, GetDifficultyFromBits(hashTarget.GetCompact(false)), ccminer::equi_stratum_target_to_diff(strTarget)) << std::endl; + } + } + + set_target_params.push_back(UniValue(strTarget)); // TODO: send real local diff (!) + set_target.push_back(Pair("params", set_target_params)); + + CMutableTransaction cb, bf; + std::vector cb_branch; + + // if (instance_of_cstratumparams.fstdErrDebugOutput) + // { + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " [1] cb = " << CTransaction(cb).ToString() << std::endl; + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " [1] current_work.GetBlock().vtx[0] = " << current_work.GetBlock().vtx[0].ToString() << std::endl; + // } + + { + std::vector extranonce1 = client.ExtraNonce1(job_id); + + static const std::vector dummy(32-extranonce1.size(), 0x00); // extranonce2 + CustomizeWork(client, current_work, client.m_addr, extranonce1, dummy, cb, bf, cb_branch); + + // without 2 lines below equihash solutinon on SubmitWork will be incorrect, bcz we should + // change vtx[0] in current work and re-calc hashMerkleRoot + // TODO: refactor all of these ... may be change this in current_work directly is bad idea, + // and we should do all checks and hashMerkleRoot at SubmitBlock(...) + + current_work.GetBlock().vtx[0] = cb; + current_work.GetBlock().hashMerkleRoot = current_work.GetBlock().BuildMerkleTree(); + + } + + // if (instance_of_cstratumparams.fstdErrDebugOutput) + // { + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " [2] cb = " << CTransaction(cb).ToString() << std::endl; + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " [2] current_work.GetBlock().vtx[0] = " << current_work.GetBlock().vtx[0].ToString() << std::endl; + // } + + CBlockHeader blkhdr; + // Setup native proof-of-work + + blkhdr = current_work.GetBlock().GetBlockHeader(); // copy entire blockheader created with CreateNewBlock to blkhdr + // CDataStream ds(SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS); + CDataStream ds(SER_GETHASH, PROTOCOL_VERSION); + ds << cb; + + /* + HexInt4(blkhdr.nVersion) = 00000004, so we can't use it here, will use swab conversion via 1 of 3 methods: + + (1) params.push_back(HexStr((unsigned char *)&blkhdr.nVersion, (unsigned char *)&blkhdr.nVersion + sizeof(blkhdr.nVersion))); // VERSION + (2) std::vector vnVersion(4, 0); + WriteLE64(&vnVersion[0], blkhdr.nVersion); + params.push_back(HexStr(vnVersion)); + (3) params.push_back(HexInt4(bswap_32(blkhdr.nVersion))); + + Bytes order, cheatsheet: + + [ need ] fbc2f4300c01f0b7820d00e3347c8da4ee614674376cbc45359daa54f9b5493e - HexStr(ToByteVector(blkhdr.hashFinalSaplingRoot)) + [ need ] fbc2f4300c01f0b7820d00e3347c8da4ee614674376cbc45359daa54f9b5493e - HexStr(blkhdr.hashFinalSaplingRoot) + [ ---- ] 3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb - blkhdr.hashFinalSaplingRoot.GetHex() + [ ---- ] 3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb - blkhdr.hashFinalSaplingRoot.ToString() + */ + + /* mining.notify params */ + UniValue params(UniValue::VARR); // mining.notify params + params.push_back(HexStr(job_id.begin(), job_id.end())); // JOB_ID + params.push_back(HexInt4(bswap_32(blkhdr.nVersion))); // VERSION (0x4 -> "04000000") + params.push_back(HexStr(blkhdr.hashPrevBlock)); // PREVHASH + params.push_back(HexStr(blkhdr.hashMerkleRoot)); // MERKLEROOT + params.push_back(HexStr(blkhdr.hashFinalSaplingRoot)); // RESERVED -> hashFinalSaplingRoot + + UpdateTime(&blkhdr, Params().GetConsensus(), tip /* or pindexPrev [tip-1] is needed? */); + // blkhdr.nTime = GetTime(); + + params.push_back(HexInt4(bswap_32(blkhdr.nTime))); // TIME + params.push_back(HexInt4(bswap_32(blkhdr.nBits))); // BITS + + // Clean Jobs. If true, miners should abort their current work and immediately use the new job. + // If false, they can still use the current job, but should move to the new one after exhausting the current nonce range. + + UniValue clean_jobs(UniValue::VBOOL); + clean_jobs = client.m_last_tip != tip; + params.push_back(clean_jobs); // CLEAN_JOBS + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << "New job: " << HexStr(job_id) << " " << strprintf("%08x", blkhdr.nTime) << std::endl; + + client.m_last_tip = tip; + + UniValue mining_notify(UniValue::VOBJ); + mining_notify.push_back(Pair("id", client.m_nextid++)); + mining_notify.push_back(Pair("method", "mining.notify")); + mining_notify.push_back(Pair("params", params)); + + return GetExtraNonceRequest(client, job_id) + + set_target.write() + "\n" + + mining_notify.write() + "\n"; +} +bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork& current_work, + const std::vector& extranonce1, const std::vector& extranonce2, + boost::optional nVersion, uint32_t nTime, const std::vector& sol) +{ + // called from stratum_mining_submit and uses following data, came from client: + // ["WORKER_NAME", "JOB_ID", "TIME", "NONCE_2", "EQUIHASH_SOLUTION"] + // all other params we have saved in other places + + if (extranonce1.size() + extranonce2.size() != 32) { + std::string msg = strprintf("extranonce1 [%d] length + extranonce2 [%d] length != %d", extranonce1.size(), extranonce2.size(), 32); + LogPrint("stratum", "%s\n", msg); + throw JSONRPCError(RPC_INVALID_PARAMETER, msg); + } + + // TODO: change hardcoded constants on actual determine of solution size, depends on equihash algo type: 200.9, etc. + if (sol.size() != 1347) { + std::string msg = strprintf("%s: solution is wrong length (received %d bytes; expected %d bytes", __func__, extranonce2.size(), 1347); + LogPrint("stratum", "%s\n", msg); + throw JSONRPCError(RPC_INVALID_PARAMETER, msg); + } + + CMutableTransaction cb, bf; + std::vector cb_branch; + CustomizeWork(client, current_work, client.m_addr, extranonce1, extranonce2, cb, bf, cb_branch); + + bool res = false; + { + // Check native proof-of-work + uint32_t version = current_work.GetBlock().nVersion; + + if (nVersion) version = *nVersion; + CBlockHeader blkhdr(current_work.GetBlock()); + + blkhdr.nVersion = version; + blkhdr.hashPrevBlock = current_work.GetBlock().hashPrevBlock; + // blkhdr.hashMerkleRoot = ComputeMerkleRootFromBranch(cb.GetHash(), cb_branch, 0); + // blkhdr.hashMerkleRoot = blkhdr.BuildMerkleTree(); + blkhdr.nTime = nTime; + blkhdr.nBits = current_work.GetBlock().nBits; + + // just an example of how-to reverse the things, don't needed in real life + // std::vector noncerev(extranonce1); + // std::reverse(noncerev.begin(), noncerev.end()); + // noncerev.insert(noncerev.begin(), extranonce2.rbegin(), extranonce2.rend()); + + std::vector nonce(extranonce1); + nonce.insert(nonce.end(), extranonce2.begin(), extranonce2.end()); + + blkhdr.nSolution = std::vector(sol.begin() + 3, sol.end()); + + blkhdr.hashFinalSaplingRoot = current_work.GetBlock().hashFinalSaplingRoot; + blkhdr.hashMerkleRoot = current_work.GetBlock().hashMerkleRoot; + blkhdr.nNonce = (uint256) nonce; + + // example how to display constructed block + // if (instance_of_cstratumparams.fstdErrDebugOutput) { + // CBlockIndex index {blkhdr}; + // index.SetHeight(current_work.nHeight); + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " blkhdr.hashPrevBlock = " << blkhdr.hashPrevBlock.GetHex() << std::endl; + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " blkhdr = " << blockToJSON(blkhdr, &index).write() << std::endl; + // } + + // block is constructed, now it's time to VerifyEH + + if (instance_of_cstratumparams.fCheckEquihashSolution && !CheckEquihashSolution(&blkhdr, Params())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid equihash solution"); + + arith_uint256 bnTarget; bool fNegative, fOverflow; + bnTarget.SetCompact(blkhdr.nBits, &fNegative, &fOverflow); + + // check range + // if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) + // return false; + + if (UintToArith256(blkhdr.GetHash()) > bnTarget) { + res = false; + } else { + uint8_t pubkey33[33]; int32_t height = current_work.nHeight; + res = CheckProofOfWork(blkhdr, pubkey33, height, Params().GetConsensus()); + } + // if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << "res[1] = " << res << std::endl; + + uint256 hash = blkhdr.GetHash(); + + // bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus()); + + static uint64_t counter_TotalBlocks, counter_TotalShares, counter_prev; + if (res) + counter_TotalBlocks++; + counter_TotalShares++; + + // https://en.cppreference.com/w/cpp/types/integer - PRId64, PRIu64 (people always forget about various OS and format specifications) + + // native proof-of-work difficulty + CBlockIndex tmp_index; + + tmp_index.nBits = blkhdr.nBits; + double kmd_target_diff = GetDifficulty(&tmp_index); // diff from nbits (target) + tmp_index.nBits = UintToArith256(hash).GetCompact(); + double kmd_real_diff = GetDifficulty(&tmp_index); // real diff (from hash) + tmp_index.nBits = arith_uint256(current_work.local_diff).GetCompact(); + double kmd_local_diff = GetDifficulty(&tmp_index); // local diff (from local port diff) + + double ccminer_real_diff = ccminer::equi_stratum_target_to_diff(hash.ToString()); + double ccminer_target_diff = ccminer::equi_stratum_target_to_diff(arith_uint256().SetCompact(blkhdr.nBits).ToString()); + double ccminer_local_diff = ccminer::equi_stratum_target_to_diff(current_work.local_diff); + + static std::chrono::high_resolution_clock::time_point start; + std::chrono::high_resolution_clock::time_point finish = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed; + uint64_t shares_accepted_since_last; + + // TODO: we need to check hash > local port diff, and if it's true -> throw an exception -> diff too low (!) + if (!instance_of_cstratumparams.fAllowLowDiffShares) + if (UintToArith256(blkhdr.GetHash()) > arith_uint256(current_work.local_diff)) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Low diff share (diff %g, local %g)", kmd_real_diff, kmd_local_diff)); + + if (finish > start) + { + elapsed = finish - start; + shares_accepted_since_last = counter_TotalShares - counter_prev; + start = finish; + counter_prev = counter_TotalShares; + // std::cerr << strprintf("%f ms - %" PRIu64 "", elapsed.count(), shares_accepted_since_last) << std::endl; + } + + bool fDisplayDiffKMD = true; // otherwise it will display ccminer diff + + std::cerr << DateTimeStrPrecise() << + strprintf("%saccepted: %" PRIu64 "/%" PRIu64 "%s ", ColorTypeNames[cl_WHT], counter_TotalBlocks, counter_TotalShares, ColorTypeNames[cl_N] ); + if (fDisplayDiffKMD) { + /* komodod diff display */ + std::cerr << strprintf("%slocal %g%s ", "\x1B[90m", kmd_local_diff, ColorTypeNames[cl_N]) << + strprintf("%s(diff %g, target %g) %s ", ColorTypeNames[cl_WHT], kmd_real_diff, kmd_target_diff, ColorTypeNames[cl_N]); + } + else + { /* ccminer diff display */ + std::cerr << strprintf("%slocal %.3f%s ", "\x1B[90m", ccminer_local_diff, ColorTypeNames[cl_N]) << + strprintf("%s(diff %.3f, target %.3f) %s", ColorTypeNames[cl_WHT], ccminer_real_diff, ccminer_target_diff, ColorTypeNames[cl_N]); // ccminer diff + } + + std::cerr << "" << + strprintf("%f ms ", elapsed.count()) << // 1 share took elapsed ms + strprintf("%s%s%s ", ColorTypeNames[cl_LGR], (res ? "yay!!!": "yes!"), ColorTypeNames[cl_N]) << + std::endl; + + // (diff %g, target %g), % + if (res) { + + LogPrintf("GOT BLOCK!!! by %s: %s\n", client.m_addr.ToString(), hash.ToString()); + + CBlock block(current_work.GetBlock()); + // block.vtx[0] = MakeTransactionRef(std::move(cb)); + block.vtx[0] = cb; + + // if (!current_work.m_aux_hash2 && current_work.m_is_witness_enabled) { + // block.vtx.back() = MakeTransactionRef(std::move(bf)); + // } + block.nVersion = version; + // block.hashMerkleRoot = BlockMerkleRoot(block); + block.hashMerkleRoot = block.BuildMerkleTree(); + //if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << "hashMerkleRoot = " << block.hashMerkleRoot.GetHex() << std::endl; + + block.nTime = nTime; + // block.nNonce = nNonce; + // nNonce <<= 32; nNonce >>= 16; // clear the top and bottom 16 bits (for local use as thread flags and counters) + + block.nNonce = (uint256) nonce; + block.nSolution = std::vector(sol.begin() + 3, sol.end()); + + // example how to pre-check the equihash solution + // if(instance_of_cstratumparams.fstdErrDebugOutput) { + // CBlockIndex index {blkhdr}; + // index.SetHeight(-1); + // std::cerr << "block = " << blockToJSON(block, &index, true).write(1) << std::endl; + // std::cerr << "CheckEquihashSolution = " << CheckEquihashSolution(&block, Params()) << std::endl; + // } + + // std::shared_ptr pblock = std::make_shared(block); + // res = ProcessNewBlock(Params(), pblock, true, NULL); + + CValidationState state; + res = ProcessNewBlock(0,0,state, NULL, &block, true /* forceProcessing */ , NULL); + + //if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << "res[2] = " << res << std::endl; + + if (res) { + // LOCK(cs_main); + if (!mapBlockIndex.count(hash)) { + LogPrintf("Unable to find new block index entry; cannot prioritise block 0x%s\n", hash.ToString()); + } else + { + CBlockIndex* block_index = mapBlockIndex.at(hash); + CValidationState state; + // we haven't PreciousBlock, so we can't prioritize the block this way for now + + // PreciousBlock(state, Params(), block_index); + // if (!state.IsValid()) { + // LogPrintf("Database error while prioritising new block 0x%s: %d (%s) %s\n", hash.ToString(), state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage()); + // } + } + } + } else { + LogPrintf("NEW SHARE!!! by %s: %s\n", client.m_addr.ToString(), hash.ToString()); + } + } + + if (res) { + client.m_send_work = true; + } + + return res; +} + +void BoundParams(const std::string& method, const UniValue& params, size_t min, size_t max) +{ + if (params.size() < min) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s expects at least %d parameters; received %d", method, min, params.size())); + } + + if (params.size() > max) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s receives no more than %d parameters; got %d", method, max, params.size())); + } +} + +UniValue stratum_mining_subscribe(StratumClient& client, const UniValue& params) +{ + const std::string method("mining.subscribe"); + BoundParams(method, params, 0, 4); + + if (params.size() >= 1) { + client.m_client = params[0].get_str(); + LogPrint("stratum", "Received subscription from client %s\n", client.m_client); + } + + // According to 'Stratum protocol changes for ZCash' - https://github.com/slushpool/poclbm-zcash/wiki/Stratum-protocol-changes-for-ZCash + // mining.subscribe params looks like following: + + // {"id": 1, "method": "mining.subscribe", "params": ["CONNECT_HOST", CONNECT_PORT, "MINER_USER_AGENT", "SESSION_ID"]} + // So, params[params.size()-1] should be SESSION_ID, but currently we don't support it. + + // Also we should answer with these: + // {"id": 1, "result": ["SESSION_ID", "NONCE_1"], "error": null} + // {"id":1,"result":[null,"81000001"],"error":null} + + // NONCE_1 is first part of the block header nonce (in hex). + + // By protocol, Zcash's nonce is 32 bytes long. The miner will pick NONCE_2 such that len(NONCE_2) = 32 - len(NONCE_1). + // Please note that Stratum use hex encoding, so you have to convert NONCE_1 from hex to binary before. + + // ["CONNECT_HOST", CONNECT_PORT, "MINER_USER_AGENT", "SESSION_ID"] + // ["NiceHash/1.0.0", null, "stratum3.decker.host", 18776] // ua, session_id, host, port? + // ["ccminer/2.3.1"] + + UniValue ret(UniValue::VARR); + + // ExtraNonce1 -> client.m_supports_extranonce is false, so the job_id isn't used + std::vector vExtraNonce1 = client.ExtraNonce1(uint256()); + + // std::string sExtraNonce1 = HexStr(vExtraNonce1.begin(), vExtraNonce1.begin() + (vExtraNonce1.size() > 3 ? 4 : vExtraNonce1.size())); + std::string sExtraNonce1 = HexStr(vExtraNonce1); + + /** + * Potentially we can use something like strprintf("%08x", GetRand(std::numeric_limits::max()) + * here to generate sExtraNonce1, but don't forget that client.ExtraNonce1 method return 8 bytes + * job_nonce:8 = sha256(client.m_secret:32 + client.job_id:32) , so, somewhere in future we can re-calculate + * sExtraNonce1 for a given client based on m_secret. + */ + + // if (instance_of_cstratumparams.fstdErrDebugOutput && vExtraNonce1.size() > 3) { + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " " << strprintf("client.m_supports_extranonce = %d, [%d, %d, %d, %d], %s", client.m_supports_extranonce, vExtraNonce1[0], vExtraNonce1[1], vExtraNonce1[2], vExtraNonce1[3], sExtraNonce1) << std::endl; + // // recalc from client.m_secret example + // uint256 sha256; + // CSHA256().Write(client.m_secret.begin(), 32).Finalize(sha256.begin()); + // std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << " " << HexStr(std::vector(sha256.begin(), sha256.begin() + 4)) << std::endl; + // } + + ret.push_back(NullUniValue); + ret.push_back(sExtraNonce1); + + // On mining.subscribe we don't need ti send anything else, we will send + // mining.set_target and mining.notify bit later, inside GetWorkUnit. + // Scheme is the following: + // 1. stratum_read_cb(bufferevent * bev, void * ctx) + // 2. if (client.m_send_work) -> GetWorkUnit + // 3. CustomizeWork (throw if error and exit from GetWorkUnit) + // 4. set_target + // 5. ... + // Last. GetWorkUnit returns string data (!) to send to client ( ... + mining.set_target + mining.notify + ... ) + + return ret; +} + +UniValue stratum_mining_authorize(StratumClient& client, const UniValue& params) +{ + const std::string method("mining.authorize"); + BoundParams(method, params, 1, 2); + + std::string username = params[0].get_str(); + boost::trim(username); + + // params[1] is the client-provided password. We do not perform + // user authorization, so we ignore this value. + + double mindiff = 0.0; + size_t pos = username.find('+'); + if (pos != std::string::npos) { + // Extract the suffix and trim it + std::string suffix(username, pos+1); + boost::trim_left(suffix); + // Extract the minimum difficulty request + mindiff = boost::lexical_cast(suffix); + // Remove the '+' and everything after + username.resize(pos); + boost::trim_right(username); + } + + CBitcoinAddress addr(get_stripped_username(username)); + + if (!addr.IsValid()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid Komodo address: %s", username)); + } + + client.m_addr = addr; + client.m_mindiff = mindiff; + client.m_authorized = true; + + client.m_send_work = true; + + LogPrintf("Authorized stratum miner %s from %s, mindiff=%f\n", addr.ToString(), client.GetPeer().ToString(), mindiff); + + return true; +} + +UniValue stratum_mining_configure(StratumClient& client, const UniValue& params) +{ + const std::string method("mining.configure"); + BoundParams(method, params, 2, 2); + + UniValue res(UniValue::VOBJ); + + UniValue extensions = params[0].get_array(); + UniValue config = params[1].get_obj(); + for (int i = 0; i < extensions.size(); ++i) { + std::string name = extensions[i].get_str(); + + if ("version-rolling" == name) { + uint32_t mask = ParseHexInt4(find_value(config, "version-rolling.mask"), "version-rolling.mask"); + size_t min_bit_count = find_value(config, "version-rolling.min-bit-count").get_int(); + client.m_version_rolling_mask = mask & 0x1fffe000; + res.push_back(Pair("version-rolling", true)); + res.push_back(Pair("version-rolling.mask", HexInt4(client.m_version_rolling_mask))); + LogPrint("stratum", "Received version rolling request from %s\n", client.GetPeer().ToString()); + } + + else { + LogPrint("stratum", "Unrecognized stratum extension '%s' sent by %s\n", name, client.GetPeer().ToString()); + } + } + + return res; +} + +UniValue stratum_mining_submit(StratumClient& client, const UniValue& params) +{ + // {"id": 4, "method": "mining.submit", "params": ["WORKER_NAME", "JOB_ID", "TIME", "NONCE_2", "EQUIHASH_SOLUTION"]}\n + + // NONCE_1 is first part of the block header nonce (in hex). + // By protocol, Zcash's nonce is 32 bytes long. The miner will pick NONCE_2 such that len(NONCE_2) = 32 - len(NONCE_1). Please note that Stratum use hex encoding, so you have to convert NONCE_1 from hex to binary before. + // NONCE_2 is the second part of the block header nonce. + /** + * + * {"method":"mining.submit","params":[ + [0] WORKER_NAME "RDeckerSubnU8QVgrhj27apzUvbVK3pnTk", + [1] JOB_ID "1", + [2] TIME "0eaec560", + [3] NONCE_2 "0000000000000000d890000001000000000000000000000000000000", + [4] EQUIHASH_SOLUTION(1347) "fd400501762fe7c0d228a4b249727f52d85c3d5d989b3f9d07148506820a50e6db2ba3456b4ccfb168d7eb65651c7d7b893d87fb77077b56224a6fc9b9ca283b7a44a25be67d956ee55f9aaeca80eae765076495fd2eb50cf3e279a68dfd15ae6b30e911db6331d6717f352510b5834d3045db3833cdf74d1fe8379ab7b4fe46fe0d855c964085d5779701a25dbcd601ea87fb5d4bbe16c39e9c5fa22c874b4922605ed21411353cef39ce02b954a09961742d8011060a3c45f6b5b316d4a1d75530bd45722945d7a8d4698e75f49b86a485b7f1851b47d10d66d74eebb492c4269d34ca3691a459a80427f79f6d01e469bb250715fc49420d6e87383b598804bdf8b50b8510e44fd0740aa5650ed5ba19543c8657f67b5164d610bbb0ab75da1c48e81e9a8a9861bc119a31c695c5c3530ae271cf9ab4a2fa08d2b4fc851e273c324dc926d6901ca20ba5fed13118f12925760871909e8351d9e944c2959a61bf74238a587dd32826de63ab4819473bb3fad67c9a54baeddd137cb6350a25969531fa055dee51464b36cbdfb6afc4be0cee0f0fe11188c8d70d0238b3ba0c6459cd34d8b7bd8b1cdaa2b7728d51269707a70c54faac778eb4bcb6492e5fcc32406ed87fdfaecc52c9f461af3f4c3c51b529e2ab9a0e15a15b3cdcb35fe3bfe4854952ae975e3171cd2600a54509d386d45ecf668b5a17249b157a13212d0e465bc1796048d63c7b4027cb0850b9607261800e4fe6217e1fba2a28601aec9b524dac787a6c14df668a7c4fabf51f8885be7ed84ca72d0ff9a7491fddae1f5309441d243cb6d5c5c4f45a08b1b858bd15ef4d1ca1565c39000f9298b52e4221723457a0ec2e904aa6cd96e854cd8c1bbd07f1c9237c831d694817227aafe7873c43826e691d3971e82e87b538c42a48603696075b19c72b85c7d20863635621da1939d9024a434f6d840cac7a30058a51650485eabf9c0735163fd9b468249ea5889c62b4f739f58665d7f8c5010a661c1355ea7e9d85b6a18424b0027e86df5aa42b1bc2bb7a38b69c8db620251c4138b69956235640c502e26185d923a045777919984e71558edb77fb54981c6ac3dc979cd0b4f704874f02536daae894da78f31913554f91a30d6badc935fe58cc9d29d152138dde520ddb9906966e077ee3380641ce88fa74a658245202a8183e1807100c3f7d22df6577f309e4d85429e94a6f6f5dbaec3653ca6414bf6ed8794db84b7860be1984cb525b235cdb263cd527c74aa6d336615e1d361f4965ddad1fd191bc4a72fa92acc13a7c92b6e0ee077d70911004f422813e408a49ba38b950ead458b72cacb1ede9e35e2fd002eaaad0ecc2cf62801e4fe010a2cfd7190c51337513f1819acf170dda5f3b23452f36d28c20509a39fedd658f45c5e58a02feb64b0e027e05804350afc3220e53fe1761e93d018f3be9eb3554ecc98fe9fdc584ac06c0dcd63812180e94876f42f2955e242358d590a8b521b641b9729e6c7dcf6164571758ac2b2ee7656f0b0e986abf7f6b569daca304c944ded083ff202a80e8636fe9aeae39707401b321a6094c4a59cc7bcec9852189c746697963f7062304d57335795ec60dd49081a4329d3b1a8c9d55f67d11f36fb54133e67fe8a362a1f8db601aa054d97d3002f898374fd201f10af65393c9c3634e0139551e362da976b7aa0f4f8156aef59620bd24a216663784d205ef5976aa3cf6a9eed571de7cb350a355c35b67c621184608f72357d32d49842e5534f232567ed7ef9a0edc109b3b487e86d1cdd9231969a76e5d7c54bc3e28942e99301a89c13895c2bc5acac2111f53182951183f50c839601dc5fabfd39d95258c79b93a140ab727288179ce1262b13e8cc5a829edf26e7d241fbf6b" + ], + "id":10} + */ + + const std::string method("mining.submit"); + BoundParams(method, params, 5,5); + // First parameter is the client username, which is ignored. + + /* EWBF 31 bytes job_id fix */ + bool fEWBFJobIDFixNeeded = false; + uint256 ret; + if (params[1].isStr()) { + //std::cerr << "\"" << params[1].get_str() << "\"" << std::endl; + const std::string job_id_str = params[1].get_str(); + const std::string hexDigits = "0123456789abcdef"; + // std::cerr << strprintf("\"%s\" (%d)", job_id_str, job_id_str.length()) << std::endl; + if (job_id_str.length() == 63) { + fEWBFJobIDFixNeeded = true; + for(const auto& hexDigit : hexDigits) { + ret = uint256(ParseHex(job_id_str + hexDigit)); + if (work_templates.count(ret)) break; + } + } + } + + uint256 job_id; + if (!fEWBFJobIDFixNeeded) + job_id = ParseUInt256(params[1], "job_id"); + else + job_id = ret; + + // uint256 job_id = ParseUInt256(params[1], "job_id"); + if (!work_templates.count(job_id)) { + LogPrint("stratum", "Received completed share for unknown job_id : %s\n", HexStr(job_id.begin(), job_id.end())); + return false; + } + + StratumWork ¤t_work = work_templates[job_id]; + + uint32_t nTime = bswap_32(ParseHexInt4(params[2], "nTime")); + + std::vector sol = ParseHexV(params[4], "solution"); + if (sol.size() != 1347) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("solution is wrong length (received %d bytes; expected %d bytes", sol.size(), 1347)); + } + + std::vector extranonce1 = client.ExtraNonce1(job_id); + std::vector extranonce2 = ParseHexV(params[3], "extranonce2"); + boost::optional nVersion = 4; // block version always 4 + + SubmitBlock(client, job_id, current_work, extranonce1, extranonce2, nVersion, nTime, sol); + + return true; +} + +UniValue stratum_mining_extranonce_subscribe(StratumClient& client, const UniValue& params) +{ + const std::string method("mining.extranonce.subscribe"); + BoundParams(method, params, 0, 0); + + /*client.m_supports_extranonce = true; + + return true;*/ + client.m_supports_extranonce = false; + + return true; +} + +UniValue stratum_mining_multi_version(StratumClient& client, const UniValue& params) +{ + const std::string method("mining.multi_version"); + BoundParams(method, params, 0, 1); + + /* + Received stratum request from Miner: {"id": 135828, "method": "mining.multi_version", "params": [1]} + Sending stratum response to Miner : {"result":null,"error":{"code":-32601,"message":"Method 'mining.multi_version' not found"},"id":135828} + */ + + return false; +} + + + +/** Callback to write from a stratum connection. */ +static void stratum_write_cb(bufferevent *bev, void *ctx) +{ + /* template */ +} + +/** Callback to read from a stratum connection. */ +static void stratum_read_cb(bufferevent *bev, void *ctx) +{ + evconnlistener *listener = (evconnlistener*)ctx; + LOCK(cs_stratum); + // Lookup the client record for this connection + if (!subscriptions.count(bev)) { + LogPrint("stratum", "Received read notification for unknown stratum connection 0x%x\n", (size_t)bev); + return; + } + StratumClient& client = subscriptions[bev]; + // Get links to the input and output buffers + evbuffer *input = bufferevent_get_input(bev); + assert(input); + evbuffer *output = bufferevent_get_output(bev); + assert(output); + + // Process each line of input that we have received + char *cstr = 0; + size_t len = 0; + while ((cstr = evbuffer_readln(input, &len, EVBUFFER_EOL_CRLF))) { + std::string line(cstr, len); + free(cstr); + LogPrint("stratum", "Received stratum request from %s : %s\n", client.GetPeer().ToString(), line); + + //JSONRPCRequest jreq; + JSONRequest jreq; + + std::string reply; + try { + // Parse request + UniValue valRequest; + if (!valRequest.read(line)) { + // Not JSON; is this even a stratum miner? + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + } + if (!valRequest.isObject()) { + // Not a JSON object; don't know what to do. + throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + } + if (valRequest.exists("result")) { + // JSON-RPC reply. Ignore. + LogPrint("stratum", "Ignoring JSON-RPC response\n"); + continue; + } + jreq.parse(valRequest); + + // Dispatch to method handler + UniValue result = NullUniValue; + if (stratum_method_dispatch.count(jreq.strMethod)) { + result = stratum_method_dispatch[jreq.strMethod](client, jreq.params); + } else { + throw JSONRPCError(RPC_METHOD_NOT_FOUND, strprintf("Method '%s' not found", jreq.strMethod)); + } + + // Compose reply + reply = JSONRPCReply(result, NullUniValue, jreq.id); + } catch (const UniValue& objError) { + reply = JSONRPCReply(NullUniValue, objError, jreq.id); + } catch (const std::exception& e) { + reply = JSONRPCReply(NullUniValue, JSONRPCError(RPC_INTERNAL_ERROR, e.what()), jreq.id); + } + + LogPrint("stratum", "Sending stratum response to %s : %s", client.GetPeer().ToString(), reply); + assert(output); + if (evbuffer_add(output, reply.data(), reply.size())) { + LogPrint("stratum", "Sending stratum response failed. (Reason: %d, '%s')\n", errno, evutil_socket_error_to_string(errno)); + } + } + + // If required, send new work to the client. + if (client.m_send_work) { + std::string data; + try { + data = GetWorkUnit(client); + } catch (const UniValue& objError) { + data = JSONRPCReply(NullUniValue, objError, NullUniValue); + } catch (const std::exception& e) { + data = JSONRPCReply(NullUniValue, JSONRPCError(RPC_INTERNAL_ERROR, e.what()), NullUniValue); + } + + LogPrint("stratum", "Sending requested stratum work unit to %s : %s", client.GetPeer().ToString(), data); + assert(output); + if (evbuffer_add(output, data.data(), data.size())) { + LogPrint("stratum", "Sending stratum work unit failed. (Reason: %d, '%s')\n", errno, evutil_socket_error_to_string(errno)); + } + + client.m_send_work = false; + } +} + +/** Callback to handle unrecoverable errors in a stratum link. */ +static void stratum_event_cb(bufferevent *bev, short what, void *ctx) +{ + evconnlistener *listener = (evconnlistener*)ctx; + LOCK(cs_stratum); + // Fetch the return address for this connection, for the debug log. + std::string from("UNKNOWN"); + if (!subscriptions.count(bev)) { + LogPrint("stratum", "Received event notification for unknown stratum connection 0x%x\n", (size_t)bev); + return; + } else { + from = subscriptions[bev].GetPeer().ToString(); + } + // Report the reason why we are closing the connection. + if (what & BEV_EVENT_ERROR) { + LogPrint("stratum", "Error detected on stratum connection from %s\n", from); + } + if (what & BEV_EVENT_EOF) { + LogPrint("stratum", "Remote disconnect received on stratum connection from %s\n", from); + } + // Remove the connection from our records, and tell libevent to + // disconnect and free its resources. + if (what & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { + LogPrint("stratum", "Closing stratum connection from %s\n", from); + subscriptions.erase(bev); + if (bev) { + bufferevent_free(bev); + bev = NULL; + } + } +} + +/** Callback to accept a stratum connection. */ +static void stratum_accept_conn_cb(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx) +{ + // Parse the return address + CService from; + from.SetSockAddr(address); + // Early address-based allow check + + if (!ClientAllowed(stratum_allow_subnets, from)) + { + // evconnlistener_free(listener); + + /* + Here we shouldn't free listener, bcz if somebody will connect on stratum port from + disallowed network -> future connections will be anavailable. + */ + LogPrint("stratum", "Rejected connection from disallowed subnet: %s\n", from.ToString()); + return; + } + + { + LOCK(cs_stratum); + // Should be the same as EventBase(), but let's get it the official way. + event_base *base = evconnlistener_get_base(listener); + // Create a buffer for sending/receiving from this connection. + bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); + // Disable Nagle's algorithm, so that TCP packets are sent + // immediately, even if it results in a small packet. + int one = 1; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)); + // Setup the read and event callbacks to handle receiving requests + // from the miner and error handling. A write callback isn't + // needed because we're not sending enough data to fill buffers. + bufferevent_setcb(bev, stratum_read_cb, NULL, stratum_event_cb, (void*)listener); + // Enable bidirectional communication on the connection. + bufferevent_enable(bev, EV_READ|EV_WRITE); + // Record the connection state + subscriptions[bev] = StratumClient(listener, fd, bev, from); + // Log the connection. + LogPrint("stratum", "Accepted stratum connection from %s\n", from.ToString()); + } +} + +/** Setup the stratum connection listening services */ +static bool StratumBindAddresses(event_base* base) +{ + int stratumPort = BaseParams().StratumPort(); + int defaultPort = GetArg("-stratumport", stratumPort); + std::vector > endpoints; + + // Determine what addresses to bind to + if (!mapArgs.count("-stratumallowip")) { // Default to loopback if not allowing external IPs + endpoints.push_back(std::make_pair("::1", defaultPort)); + endpoints.push_back(std::make_pair("127.0.0.1", defaultPort)); + if (mapArgs.count("-stratumbind")) { + LogPrintf("WARNING: option -stratumbind was ignored because -stratumallowip was not specified, refusing to allow everyone to connect\n"); + } + } else if (mapArgs.count("-stratumbind")) { // Specific bind address + const std::vector& vbind = mapMultiArgs["-stratumbind"]; + for (std::vector::const_iterator i = vbind.begin(); i != vbind.end(); ++i) { + int port = defaultPort; + std::string host; + SplitHostPort(*i, port, host); + endpoints.push_back(std::make_pair(host, port)); + } + } else { // No specific bind address specified, bind to any + endpoints.push_back(std::make_pair("::", defaultPort)); + endpoints.push_back(std::make_pair("0.0.0.0", defaultPort)); + } + + // Bind each addresses + for (const auto& endpoint : endpoints) { + LogPrint("stratum", "Binding stratum on address %s port %i\n", endpoint.first, endpoint.second); + // Use CService to translate string -> sockaddr + CNetAddr netaddr; + std::vector vIP; + + LookupHost(endpoint.first.c_str(), vIP, 1, true); + assert(vIP.size() >= 1); + + netaddr = vIP[0]; + + CService socket(netaddr, endpoint.second); + union { + sockaddr ipv4; + sockaddr_in6 ipv6; + } addr; + socklen_t len = sizeof(addr); + socket.GetSockAddr((sockaddr*)&addr, &len); + // Setup an event listener for the endpoint + evconnlistener *listener = evconnlistener_new_bind(base, stratum_accept_conn_cb, NULL, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (sockaddr*)&addr, len); + // Only record successful binds + if (listener) { + bound_listeners[listener] = socket; + } else { + LogPrintf("Binding stratum on address %s port %i failed. (Reason: %d, '%s')\n", endpoint.first, endpoint.second, errno, evutil_socket_error_to_string(errno)); + } + } + + return !bound_listeners.empty(); +} + +/** Watches for new blocks and send updated work to miners. */ +static bool g_shutdown = false; + +void BlockWatcher() +{ + RenameThread("blkwatcher"); + boost::unique_lock lock(csBestBlock); + boost::system_time checktxtime; + boost::system_time starttime = boost::get_system_time(); + + unsigned int txns_updated_last = 0; + boost::posix_time::time_duration time_passed = boost::posix_time::seconds(0); + bool fRebroadcastAnyway = false; + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + while (true) { // (A) + /* This will execute before waiting of cvBlockChange */ + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + checktxtime = boost::get_system_time() + boost::posix_time::seconds(txMemPoolCheckTimeout); + // - time_passed + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + + if (!cvBlockChange.timed_wait(lock, checktxtime)) { + // Timeout: Check to see if mempool was updated. + + /* This will execute after txMemPoolCheckTimeout seconds */ + unsigned int txns_updated_next = mempool.GetTransactionsUpdated(); + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << ColorTypeNames[cl_WHT] << " seconds_passed = " << (boost::get_system_time() - starttime) << ColorTypeNames[cl_N] << " txns_updated_last = " << txns_updated_last << " txns_updated_next = " << txns_updated_next << std::endl; + time_passed = boost::posix_time::time_duration(boost::get_system_time() - starttime); + + if ((boost::get_system_time() - starttime) < boost::posix_time::seconds(jobRebroadcastTimeout)) { + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << "seconds_passed < jobRebroadcastTimeout" << std::endl; + fRebroadcastAnyway = false; + if (txns_updated_last == txns_updated_next) continue; // (A) + } else { + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << ColorTypeNames[cl_GRN] << "Force update work!"<< ColorTypeNames[cl_N] << " seconds_passed >= jobRebroadcastTimeout" << std::endl; + // in case of rebroadcast we should "emulate" that everything is changed and clients must go for new work + mempool.AddTransactionsUpdated(1); + for (auto& subscription : subscriptions) { + subscription.second.m_last_tip = (subscription.second.m_last_tip ? nullptr : chainActive.Tip()); + } + fRebroadcastAnyway = true; + starttime += boost::posix_time::seconds(jobRebroadcastTimeout); + } + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << std::endl; + txns_updated_last = txns_updated_next; + } + + /* This will excute after wait cvBlockChange will completed, or if 'timeout branch' will allow + execution goes here (mean, if it will not use condition with `continue`) */ + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + + if (g_shutdown) { + break; + } + + // Either new block, or updated transactions. Either way, + // send updated work to miners. + { + LOCK(cs_stratum); + for (auto& subscription : subscriptions) { + + bufferevent* bev = subscription.first; + + if (!bev) + continue; + evbuffer *output = bufferevent_get_output(bev); + if (!output) + continue; + + StratumClient& client = subscription.second; + // Ignore clients that aren't authorized yet. + if (!client.m_authorized && client.m_aux_addr.empty()) { + continue; + } + // Ignore clients that are already working on the new block. + // Typically this is just the miner that found the block, who was + // immediately sent a work update. This check avoids sending that + // work notification again, moments later. Due to race conditions + // there could be more than one miner that have already received an + // update, however. + if (!fRebroadcastAnyway && client.m_last_tip == chainActive.Tip()) { + continue; + } + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + + // Get new work + std::string data; + try { + data = GetWorkUnit(client); + } catch (const UniValue& objError) { + data = JSONRPCReply(NullUniValue, objError, NullUniValue); + } catch (const std::exception& e) { + // Some sort of error. Ignore. + std::string msg = strprintf("Error generating updated work for stratum client: %s", e.what()); + LogPrint("stratum", "%s\n", msg); + data = JSONRPCReply(NullUniValue, JSONRPCError(RPC_INTERNAL_ERROR, msg), NullUniValue); + } + // Send the new work to the client + + assert(output); + if (evbuffer_add(output, data.data(), data.size())) { + LogPrint("stratum", "Sending stratum work unit failed. (Reason: %d, '%s')\n", errno, evutil_socket_error_to_string(errno)); + } + } + } + + if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << " time = " << boost::get_system_time() << " checktxtime = " << checktxtime << std::endl; + } +} + +void SendKeepAlivePackets() +{ + RenameThread("sockklv"); + while (true) { + // Run the notifier on an integer second in the steady clock. + auto now = std::chrono::steady_clock::now().time_since_epoch(); + auto nextFire = std::chrono::duration_cast( + now + std::chrono::seconds(10)); + std::this_thread::sleep_until( + std::chrono::time_point(nextFire)); + + boost::this_thread::interruption_point(); + + // Either new block, or updated transactions. Either way, + // send updated work to miners. + for (auto& subscription : subscriptions) { + bufferevent* bev = subscription.first; + + if (!bev) + continue; + evbuffer *output = bufferevent_get_output(bev); + if (!output) + continue; + evbuffer *input = bufferevent_get_input(bev); + if (!input) + continue; + + StratumClient& client = subscription.second; + + if (instance_of_cstratumparams.fstdErrDebugOutput) { + std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << std::endl << + "client.m_authorized = " << client.m_authorized << std::endl << + "client.m_aux_addr.size() = " << client.m_aux_addr.size() << std::endl << + "client.m_last_tip = " << strprintf("%p", client.m_last_tip) << std::endl << + (client.m_last_tip ? strprintf("client.m_last_tip->GetHeight() = %d", client.m_last_tip->GetHeight()) : "") << std::endl << + "chainActive.Tip()->GetHeight() = " << chainActive.Tip()->GetHeight() << std::endl << + "client.m_supports_extranonce = " << client.m_supports_extranonce << std::endl << + "client.m_send_work = " << client.m_send_work << std::endl << + std::endl; + } + + // Ignore clients that aren't authorized yet. + if (!client.m_authorized && client.m_aux_addr.empty()) { + continue; + } + + std::string data = "\r\n"; + // to see the socket / connection is alive, we will see bunch of + // JSON decode failed(1): '[' or '{' expected near end of file + // on client if will send "\r\n" every second + + assert(output); + if (evbuffer_add(output, data.data(), data.size())) { + LogPrint("stratum", "Sending stratum keepalive unit failed. (Reason: %d, '%s')\n", errno, evutil_socket_error_to_string(errno)); + } + + if ( (client.m_last_tip && client.m_last_tip->GetHeight() == chainActive.Tip()->GetHeight()) || (!client.m_last_tip) ) + { + LOCK(cs_stratum); + std::cerr << DateTimeStrPrecise() << "\033[31m" << client.m_from.ToString() << "\033[0m seems stucked (ccminer issue), need to emulate new block incoming to unstuck!" << std::endl; + mempool.AddTransactionsUpdated(1); + client.m_last_tip = (client.m_last_tip ? nullptr : chainActive.Tip()); + client.m_nextid++; + cvBlockChange.notify_all(); // change the state of all threads waiting on *this to ready + // cvBlockChange.notify_one(); // if there is a thread waiting on *this, change that thread state to ready + } + } + + } + +} + +/** Configure the Hush stratum server */ +bool InitStratumServer() +{ + LOCK(cs_stratum); + fprintf(stderr,"%s: Starting built-in stratum server\n",__func__); + + + if (!InitStratumAllowList(stratum_allow_subnets)) { + LogPrint("stratum", "Unable to bind stratum server to an endpoint.\n"); + return false; + } + + std::string strAllowed; + for(const CSubNet& subnet : stratum_allow_subnets) + strAllowed += subnet.ToString() + " "; + LogPrint("stratum", "Allowing Stratum connections from: %s\n", strAllowed); + + event_base* base = EventBase(); + if (!base) { + LogPrint("stratum", "No event_base object, cannot setup stratum server.\n"); + return false; + } + + if (!StratumBindAddresses(base)) { + LogPrintf("Unable to bind any endpoint for stratum server\n"); + } else { + LogPrint("stratum", "Initialized stratum server\n"); + } + + stratum_method_dispatch["mining.subscribe"] = stratum_mining_subscribe; + stratum_method_dispatch["mining.authorize"] = stratum_mining_authorize; + stratum_method_dispatch["mining.configure"] = stratum_mining_configure; + stratum_method_dispatch["mining.submit"] = stratum_mining_submit; + stratum_method_dispatch["mining.extranonce.subscribe"] = + stratum_mining_extranonce_subscribe; + stratum_method_dispatch["mining.multi_version"] = + stratum_mining_multi_version; + + + // Start thread to wait for block notifications and send updated + // work to miners. + block_watcher_thread = boost::thread(BlockWatcher); + // block_watcher_thread = boost::thread(SendKeepAlivePackets); + + return true; +} + +/** Interrupt the stratum server connections */ +void InterruptStratumServer() +{ + LOCK(cs_stratum); + // Stop listening for connections on stratum sockets + for (const auto& binding : bound_listeners) { + LogPrint("stratum", "Interrupting stratum service on %s\n", binding.second.ToString()); + evconnlistener_disable(binding.first); + } + // Tell the block watching thread to stop + g_shutdown = true; +} + +/** Cleanup stratum server network connections and free resources. */ +void StopStratumServer() +{ + LOCK(cs_stratum); + /* Tear-down active connections. */ + for (const auto& subscription : subscriptions) { + LogPrint("stratum", "Closing stratum server connection to %s due to process termination\n", subscription.second.GetPeer().ToString()); + bufferevent_free(subscription.first); + } + subscriptions.clear(); + /* Un-bind our listeners from their network interfaces. */ + for (const auto& binding : bound_listeners) { + LogPrint("stratum", "Removing stratum server binding on %s\n", binding.second.ToString()); + evconnlistener_free(binding.first); + } + bound_listeners.clear(); + /* Free any allocated block templates. */ + work_templates.clear(); +} + +/* RPC */ +UniValue rpc_stratum_updatework(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (fHelp || params.size() != 0) + throw std::runtime_error( + "stratum_updatework\n" + "Tries to immediatelly update work on all connected miners.\n" + "\nExamples:\n" + + HelpExampleCli("stratum_updatework", "") + + HelpExampleRpc("stratum_updatework", "") + ); + + UniValue obj(UniValue::VOBJ); + UniValue json_clients(UniValue::VARR); + uint64_t skipped = 0; + + // send updated work to miners + + // if (cs_stratum.try_lock()) + { + LOCK(cs_stratum); + for (auto& subscription : subscriptions) { + + bufferevent* bev = subscription.first; + + if (!bev) + continue; + evbuffer *output = bufferevent_get_output(bev); + if (!output) + continue; + evbuffer *input = bufferevent_get_input(bev); + if (!input) + continue; + + StratumClient& client = subscription.second; + + if (instance_of_cstratumparams.fstdErrDebugOutput) { + std::cerr << __func__ << ": " << __FILE__ << "," << __LINE__ << std::endl << + "client.m_authorized = " << client.m_authorized << std::endl << + "client.m_aux_addr.size() = " << client.m_aux_addr.size() << std::endl << + "client.m_last_tip = " << strprintf("%p", client.m_last_tip) << std::endl << + (client.m_last_tip ? strprintf("client.m_last_tip->GetHeight() = %d", client.m_last_tip->GetHeight()) : "") << std::endl << + "chainActive.Tip()->GetHeight() = " << chainActive.Tip()->GetHeight() << std::endl << + "client.m_supports_extranonce = " << client.m_supports_extranonce << std::endl << + "client.m_send_work = " << client.m_send_work << std::endl << + std::endl; + } + + // Ignore clients that aren't authorized yet. + if (!client.m_authorized && client.m_aux_addr.empty()) { + continue; + } + + if ( (client.m_last_tip && client.m_last_tip->GetHeight() == chainActive.Tip()->GetHeight()) || (!client.m_last_tip) ) + { + mempool.AddTransactionsUpdated(1); + client.m_last_tip = (client.m_last_tip ? nullptr : chainActive.Tip()); + cvBlockChange.notify_all(); + } + + std::string data = ""; + + try { + data = GetWorkUnit(client); + + UniValue json_client(UniValue::VOBJ); + json_client.push_back(Pair("addr", client.m_addr.ToString())); + json_client.push_back(Pair("service", client.m_from.ToString())); + + json_clients.push_back(json_client); + + } catch (const UniValue& objError) { + data = JSONRPCReply(NullUniValue, objError, NullUniValue); + skipped++; + } catch (const std::exception& e) { + // Some sort of error. Ignore. + std::string msg = strprintf("Error generating updated work for stratum client: %s", e.what()); + LogPrint("stratum", "%s\n", msg); + data = JSONRPCReply(NullUniValue, JSONRPCError(RPC_INTERNAL_ERROR, msg), NullUniValue); + skipped++; + } + + assert(output); + if (evbuffer_add(output, data.data(), data.size())) { + LogPrint("stratum", "Sending stratum work unit failed. (Reason: %d, '%s')\n", errno, evutil_socket_error_to_string(errno)); + } + } + } + // else { + // throw JSONRPCError(RPC_INTERNAL_ERROR, "Something went wrong, plz try again!"); + // } + + obj.push_back(Pair("clients", json_clients)); + obj.push_back(Pair("updated", json_clients.size())); + obj.push_back(Pair("skipped", skipped)); + obj.push_back(Pair("total", subscriptions.size())); + + return obj; +} + +UniValue rpc_stratum_getdifficulty (const UniValue& params, bool fHelp, const CPubKey& mypk) { + + if (fHelp || params.size() != 0) + throw std::runtime_error( + "stratum_getdifficulty\n" + "Show the current local diff of a stratum port.\n" + "\nExamples:\n" + + HelpExampleCli("stratum_getdifficulty", "") + + HelpExampleRpc("stratum_getdifficulty", "") + ); + + UniValue obj(UniValue::VOBJ); + + arith_uint256 aHashTarget = instance_of_cstratumparams.getTarget(); + std::string strTarget = aHashTarget.GetHex(); + + CBlockIndex tmp_index; + tmp_index.nBits = arith_uint256(strTarget).GetCompact(); + double kmd_diff = GetDifficulty(&tmp_index); + double ccminer_diff = ccminer::equi_stratum_target_to_diff(strTarget); + + obj.push_back(Pair("target", strTarget)); + obj.push_back(Pair("target_compact", strprintf("%08x",tmp_index.nBits))); + obj.push_back(Pair("kmd_diff_str", strprintf("%g",kmd_diff))); + obj.push_back(Pair("ccminer_diff_str", strprintf("%g", ccminer_diff))); + obj.push_back(Pair("kmd_diff", kmd_diff)); + obj.push_back(Pair("ccminer_diff", ccminer_diff)); + + return obj; +}; + +UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CPubKey& mypk) { + + /* + https://bitcoin.stackexchange.com/questions/30467/what-are-the-equations-to-convert-between-bits-and-difficulty + + There are 3 representations of the same thing (with varying degrees of precision) in Bitcoin: + + - bits - unsigned int 32-bit + - target - unsigned int 256-bit + - difficulty - double-precision float (64-bit) + + and 6 methods are necessary to convert between any two of these: + + - bits -> target (SetCompact() in bitcoin/src/arith_uint256.cpp) + - bits -> difficulty (GetDifficulty() in bitcoin/src/rpc/blockchain.cpp) + - target -> bits (GetCompact() in bitcoin/src/arith_uint256.cpp) + - target -> difficulty (same as target -> bits -> difficulty) + - difficulty -> bits (not done in bitcoin/src) -> we will use kmd_diff_to_target_equi for that + - difficulty -> target (same as difficulty -> bits -> target) + */ + if (fHelp || params.size() != 1) + throw std::runtime_error( + "stratum_setdifficulty\n" + "Set the diff on a stratum port.\n" + "\nExamples:\n" + + HelpExampleCli("stratum_setdifficulty", "") + + HelpExampleRpc("stratum_setdifficulty", "") + ); + + // diff can be accepted in two ways: as a hex target or as a kmd_diff, both variants assume + // passing a string with 32 bytes hex target or string (!) with a double value, or double + // value as a double + + double kmd_diff; // calculated value: diff_str -> kmd_diff + std::string diff_str = instance_of_cstratumparams.getTarget().ToString(); + + if (params[0].getType() == UniValue::VSTR) { + std::string param_str = params[0].get_str(); + if (IsHex(param_str) && param_str.size() == 64) { + // hex target passed + diff_str = param_str; + + } else { + if (ParseDouble(param_str, &kmd_diff)) { + // kmd diff as a str passed + + // difficulty = difficulty_1_target / current_target + arith_uint256 target; + ccminer::kmd_diff_to_target_equi((uint32_t *)&target, kmd_diff); + diff_str = target.ToString(); + + } else + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid difficulty (not hex target, not kmd_diff)"); + } + } else if (params[0].getType() == UniValue::VNUM) { + // kmd diff as a num passed + kmd_diff = params[0].get_real(); + + // difficulty = difficulty_1_target / current_target + arith_uint256 target; + ccminer::kmd_diff_to_target_equi((uint32_t *)&target, kmd_diff); + diff_str = target.ToString(); + + } else + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid difficulty"); + + instance_of_cstratumparams.setTarget(arith_uint256(diff_str)); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("target", diff_str)); + + CBlockIndex tmp_index; + tmp_index.nBits = arith_uint256(diff_str).GetCompact(); + + double new_kmd_diff = GetDifficulty(&tmp_index); + obj.push_back(Pair("kmd_diff_str", strprintf("%g",new_kmd_diff))); + obj.push_back(Pair("kmd_diff", new_kmd_diff)); + + return obj; +}; + +UniValue rpc_stratum_getclientscount (const UniValue& params, bool fHelp, const CPubKey& mypk) { + + if (fHelp || params.size() != 0) + throw std::runtime_error( + "stratum_getclientscount\n" + "Show the the number of stratum clients.\n" + "\nExamples:\n" + + HelpExampleCli("stratum_getclientscount", "") + + HelpExampleRpc("stratum_getclientscount", "") + ); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("total", subscriptions.size())); + + return obj; +}; + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "stratum", "stratum_updatework", &rpc_stratum_updatework, true }, + { "stratum", "stratum_getdifficulty", &rpc_stratum_getdifficulty, true }, + { "stratum", "stratum_setdifficulty", &rpc_stratum_setdifficulty, true }, + { "stratum", "stratum_getclientscount", &rpc_stratum_getclientscount, true }, +}; + +void RegisterStratumRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} + +// End of File diff --git a/src/stratum.h b/src/stratum.h new file mode 100644 index 000000000..56dc52056 --- /dev/null +++ b/src/stratum.h @@ -0,0 +1,21 @@ +// Copyright (c) 2021-2021 The Hush developers +// Copyright (c) 2020-2021 The Freicoin Developers +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#ifndef HUSH_STRATUM_H +#define HUSH_STRATUM_H + +/** Configure the stratum server. */ +bool InitStratumServer(); + +/** Interrupt the stratum server connections. */ +void InterruptStratumServer(); + +/** Cleanup stratum server network connections and free resources. */ +void StopStratumServer(); + +#endif // HUSH_STRATUM_H + +// End of File From 7b8209b2579f3d6e1c7b4fe613583862fb43bd13 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 23:35:38 -0400 Subject: [PATCH 002/115] . --- src/stratum.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/stratum.cpp b/src/stratum.cpp index 3619c9ea1..81042d2eb 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -670,7 +670,7 @@ std::string GetWorkUnit(StratumClient& client) } */ /* if (!Params().MineBlocksOnDemand() && g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) { - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Komodo is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Hush is not connected!"); } */ bool fvNodesEmpty; @@ -681,15 +681,15 @@ std::string GetWorkUnit(StratumClient& client) if (Params().MiningRequiresPeers() && fvNodesEmpty) { - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Komodo is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Hush is not connected!"); } if (IsInitialBlockDownload()) { - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Komodo is downloading blocks..."); + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Hush is downloading blocks..."); } if (!client.m_authorized && client.m_aux_addr.empty()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a Komodo address as the username."); + throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a Hush R.. address as the username."); } static CBlockIndex* tip = NULL; // pindexPrev @@ -798,7 +798,7 @@ std::string GetWorkUnit(StratumClient& client) /* // Targets Table Example: komodo diff and ccminer diff are different (!), - // Komodo diff = NiceHash diff, ccminer_diff = Yiimp diff. + // Hush diff = NiceHash diff, ccminer_diff = Yiimp diff. hashTarget.SetCompact(HUSH_MINDIFF_NBITS,&fNegative,&fOverflow); // blkhdr.nBits hashTarget = UintToArith256(uint256S("0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f")); @@ -1245,7 +1245,7 @@ UniValue stratum_mining_authorize(StratumClient& client, const UniValue& params) CBitcoinAddress addr(get_stripped_username(username)); if (!addr.IsValid()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid Komodo address: %s", username)); + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid Hush address: %s", username)); } client.m_addr = addr; From 60a34af810f4dfe91a17e980efe8872d5056d5df Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 23:41:44 -0400 Subject: [PATCH 003/115] The meta-revert of https://github.com/tradecraftio/tradecraft/commit/b0f2fa3399de8fc9b5a9dd5452570f53dace9848 --- src/stratum.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stratum.cpp b/src/stratum.cpp index 81042d2eb..97179303e 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -1111,6 +1111,8 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork //if (instance_of_cstratumparams.fstdErrDebugOutput) std::cerr << DateTimeStrPrecise() << "res[2] = " << res << std::endl; + // we haven't PreciousBlock, so we can't prioritize the block this way for now + /* if (res) { // LOCK(cs_main); if (!mapBlockIndex.count(hash)) { @@ -1119,7 +1121,6 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork { CBlockIndex* block_index = mapBlockIndex.at(hash); CValidationState state; - // we haven't PreciousBlock, so we can't prioritize the block this way for now // PreciousBlock(state, Params(), block_index); // if (!state.IsValid()) { @@ -1127,6 +1128,7 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork // } } } + */ } else { LogPrintf("NEW SHARE!!! by %s: %s\n", client.m_addr.ToString(), hash.ToString()); } From 38089e2d15bc6aba7697cb54b72a23b3113a1edf Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 02:30:05 -0400 Subject: [PATCH 004/115] Only build witness cache when needed --- src/wallet/wallet.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3bc3b99cd..233851d64 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2717,10 +2717,12 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; + bool involvesMe = false; ReadBlockFromDisk(block, pindex,1); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) { + involvesMe = true; ret++; } } @@ -2734,8 +2736,11 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) } } - // Build initial witness caches - BuildWitnessCache(pindex, true); + // Build initial witness caches for blocks involving one of our addresses + if (involvesMe) { + LogPrintf("%s: block has one of our transactions, building witness cache", __func__); + BuildWitnessCache(pindex, true); + } //Delete Transactions if (fTxDeleteEnabled) { From 62adec08d80faa66c21c9249e2f839828c1b0861 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 03:46:05 -0400 Subject: [PATCH 005/115] Overwinter has always been active for HUSH + all HSCs --- src/rpc/rawtransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 82fcfdf97..69e614f3b 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -651,7 +651,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp, const CPubKey& " ,...\n" " }\n" "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" - "4. expiryheight (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction (if Overwinter is active)\n" + "4. expiryheight (numeric, optional, default=" + strprintf("%d", DEFAULT_TX_EXPIRY_DELTA) + ") Expiry height of transaction\n" "\nResult:\n" "\"transaction\" (string) hex string of the transaction\n" From 2331ed0c56e8966afe9e33c0728087796c85c54b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 12:23:55 -0400 Subject: [PATCH 006/115] Default HSC is now HUSH3 and some doc fixes --- src/bitcoin-cli.cpp | 11 +++++++---- src/util.cpp | 11 +++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index dbf2e82e9..b804e26bc 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -28,7 +28,7 @@ #include #include #include "support/events.h" -uint16_t BITCOIND_RPCPORT = 7771; +uint16_t BITCOIND_RPCPORT = 18031; char SMART_CHAIN_SYMBOL[65]; #include @@ -43,13 +43,13 @@ std::string HelpMessageCli() std::string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); - strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "komodo.conf")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "HUSH3.conf")); strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); strUsage += HelpMessageOpt("-testnet", _("Use the test network")); strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be " "solved instantly. This is intended for regression testing tools and app development.")); strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), "127.0.0.1")); - strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 8232, 18232)); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u )"), 18030)); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); @@ -82,7 +82,10 @@ static int AppInitRPC(int argc, char* argv[]) // Parameters ParseParameters(argc, argv); std:string name; - name = GetArg("-ac_name",""); + + // default HSC is HUSH3 itself, which to the internals, is also an HSC + name = GetArg("-ac_name","HUSH3"); + if ( !name.empty() ) strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); diff --git a/src/util.cpp b/src/util.cpp index 71152f2bd..c32332b72 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -652,15 +652,10 @@ void ClearDatadirCache() boost::filesystem::path GetConfigFile() { char confname[512]; - if ( SMART_CHAIN_SYMBOL[0] != 0 ) + if ( SMART_CHAIN_SYMBOL[0] != 0 ) { sprintf(confname,"%s.conf",SMART_CHAIN_SYMBOL); - else - { -#ifdef __APPLE__ - strcpy(confname,"Komodo.conf"); -#else - strcpy(confname,"komodo.conf"); -#endif + } else { + strcpy(confname,"HUSH3.conf"); } boost::filesystem::path pathConfigFile(GetArg("-conf",confname)); if (!pathConfigFile.is_complete()) From fc52a00c37a2fb5eca6a3fb850bca4c7cb21db3d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 12:27:30 -0400 Subject: [PATCH 007/115] hush_init --- src/hush.h | 2 +- src/hush_bitcoind.h | 4 ++-- src/hush_globals.h | 4 ++-- src/hush_notary.h | 6 +++--- src/init.cpp | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hush.h b/src/hush.h index 14e8fd2f7..5ffdb5a71 100644 --- a/src/hush.h +++ b/src/hush.h @@ -818,7 +818,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) return(0); } memset(&zero,0,sizeof(zero)); - komodo_init(pindex->GetHeight()); + hush_init(pindex->GetHeight()); HUSH_INITDONE = (uint32_t)time(NULL); if ( (sp= hush_stateptr(symbol,dest)) == 0 ) { diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 4b6af7e53..5690b7968 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -699,7 +699,7 @@ void komodo_disconnect(CBlockIndex *pindex,CBlock& block) { char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; struct hush_state *sp; //fprintf(stderr,"disconnect ht.%d\n",pindex->GetHeight()); - komodo_init(pindex->GetHeight()); + hush_init(pindex->GetHeight()); if ( (sp= hush_stateptr(symbol,dest)) != 0 ) { //sp->rewinding = pindex->GetHeight(); @@ -754,7 +754,7 @@ int32_t hush_block2height(CBlock *block) } //printf(" <- coinbase.%d ht.%d\n",(int32_t)block->vtx[0].vin[0].scriptSig.size(),height); } - //komodo_init(height); + //hush_init(height); } if ( height != height2 ) { diff --git a/src/hush_globals.h b/src/hush_globals.h index 7bd1222b8..97415bd50 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -20,11 +20,11 @@ void hush_prefetch(FILE *fp); uint32_t hush_heightstamp(int32_t height); void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); -void komodo_init(int32_t height); +void hush_init(int32_t height); int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port); -void komodo_init(int32_t height); +void hush_init(int32_t height); int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_isrealtime(int32_t *kmdheightp); uint64_t komodo_paxtotal(); diff --git a/src/hush_notary.h b/src/hush_notary.h index 53a4c0a33..b94959766 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -216,7 +216,7 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui if ( height >= 250000 ) return(-1); if ( Pubkeys == 0 ) - komodo_init(0); + hush_init(0); htind = height / KOMODO_ELECTION_GAP; if ( htind >= HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP ) htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; @@ -434,11 +434,11 @@ void komodo_notarized_update(struct hush_state *sp,int32_t nHeight,int32_t notar portable_mutex_unlock(&komodo_mutex); } -void komodo_init(int32_t height) +void hush_init(int32_t height) { static int didinit; uint256 zero; int32_t k,n; uint8_t pubkeys[64][33]; if ( 0 && height != 0 ) - printf("komodo_init ht.%d didinit.%d\n",height,didinit); + printf("hush_init ht.%d didinit.%d\n",height,didinit); memset(&zero,0,sizeof(zero)); if ( didinit == 0 ) { diff --git a/src/init.cpp b/src/init.cpp index 01916ee76..163df8a39 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -94,7 +94,7 @@ extern bool hush_dailysnapshot(int32_t height); extern int32_t HUSH_LOADINGBLOCKS; extern char SMART_CHAIN_SYMBOL[]; extern int32_t HUSH_SNAPSHOT_INTERVAL; -extern void komodo_init(int32_t height); +extern void hush_init(int32_t height); #ifdef ENABLE_WALLET CWallet* pwalletMain = NULL; @@ -1840,7 +1840,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // (we're likely using a testnet datadir, or the other way around). if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); - komodo_init(1); + hush_init(1); // Initialize the block index (no-op if non-empty database was already loaded) if (!InitBlockIndex()) { strLoadError = _("Error initializing block database"); From dab4126a82b1574b498141199172be7e8de64420 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 12:30:34 -0400 Subject: [PATCH 008/115] hush_makeopret --- src/hush_bitcoind.h | 4 ++-- src/pow.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 5690b7968..60d1c0004 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -543,7 +543,7 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t return(retval); } -CScript komodo_makeopret(CBlock *pblock, bool fNew) +CScript hush_makeopret(CBlock *pblock, bool fNew) { std::vector vLeaves; vLeaves.push_back(pblock->hashPrevBlock); @@ -673,7 +673,7 @@ uint32_t komodo_txtime2(uint64_t *valuep,uint256 hash,int32_t n,char *destaddr) bool hush_checkopret(CBlock *pblock, CScript &merkleroot) { merkleroot = pblock->vtx.back().vout.back().scriptPubKey; - return(merkleroot.IsOpReturn() && merkleroot == komodo_makeopret(pblock, false)); + return(merkleroot.IsOpReturn() && merkleroot == hush_makeopret(pblock, false)); } diff --git a/src/pow.cpp b/src/pow.cpp index 703deb765..0838f6e2b 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -674,7 +674,7 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui int32_t hush_currentheight(); void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); bool hush_checkopret(CBlock *pblock, CScript &merkleroot); -CScript komodo_makeopret(CBlock *pblock, bool fNew); +CScript hush_makeopret(CBlock *pblock, bool fNew); extern int32_t HUSH_CHOSEN_ONE; extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; #define KOMODO_ELECTION_GAP 2000 From d7944252bb4c277acfbf156181a7d15bfde6f814 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 12:49:08 -0400 Subject: [PATCH 009/115] cleanup --- src/hush_bitcoind.h | 8 ++++---- src/hush_events.h | 4 ++-- src/hush_gateway.h | 2 +- src/hush_kv.h | 2 +- src/hush_nSPV.h | 2 +- src/hush_nSPV_fullnode.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 60d1c0004..663491e7f 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -453,19 +453,19 @@ int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len, return(-1); } -void komodo_reconsiderblock(uint256 blockhash) +void hush_reconsiderblock(uint256 blockhash) { char params[256],*jsonstr,*hexstr; sprintf(params,"[\"%s\"]",blockhash.ToString().c_str()); if ( (jsonstr= komodo_issuemethod(ASSETCHAINS_USERPASS,(char *)"reconsiderblock",params,ASSETCHAINS_RPCPORT)) != 0 ) { - //fprintf(stderr,"komodo_reconsiderblock.(%s) (%s %u) -> (%s)\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT,jsonstr); + //fprintf(stderr,"hush_reconsiderblock.(%s) (%s %u) -> (%s)\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT,jsonstr); free(jsonstr); } - //fprintf(stderr,"komodo_reconsiderblock.(%s) (%s %u) -> NULL\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT); + //fprintf(stderr,"hush_reconsiderblock.(%s) (%s %u) -> NULL\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT); } -int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) +int32_t hush_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) { char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; script = _script; diff --git a/src/hush_events.h b/src/hush_events.h index d3a0ffb21..b596760d3 100644 --- a/src/hush_events.h +++ b/src/hush_events.h @@ -43,8 +43,8 @@ struct hush_event *hush_eventadd(struct hush_state *sp,int32_t height,char *symb void hush_eventadd_notarized(struct hush_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight,uint256 MoM,int32_t MoMdepth) { static uint32_t counter; int32_t verified=0; char *coin; struct hush_event_notarized N; - coin = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"KMD" : SMART_CHAIN_SYMBOL; - if ( IS_HUSH_NOTARY != 0 && (verified= komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid)) < 0 ) + coin = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"HUSH3" : SMART_CHAIN_SYMBOL; + if ( IS_HUSH_NOTARY != 0 && (verified= hush_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid)) < 0 ) { if ( counter++ < 100 ) printf("[%s] error validating notarization ht.%d notarized_height.%d, if on a pruned %s node this can be ignored\n",SMART_CHAIN_SYMBOL,height,notarizedheight,dest); diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 9beabb6fb..c3f99de84 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -2228,7 +2228,7 @@ void hush_cbopretupdate(int32_t forceflag) if ( Queued_reconsiderblock != zeroid ) { fprintf(stderr,"Queued_reconsiderblock %s\n",Queued_reconsiderblock.GetHex().c_str()); - komodo_reconsiderblock(Queued_reconsiderblock); + hush_reconsiderblock(Queued_reconsiderblock); Queued_reconsiderblock = zeroid; } if ( forceflag != 0 && pending != 0 ) diff --git a/src/hush_kv.h b/src/hush_kv.h index 3fdde30ff..b64522f36 100644 --- a/src/hush_kv.h +++ b/src/hush_kv.h @@ -104,7 +104,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) { static uint256 zeroes; uint32_t flags; uint256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[DRAGON_MAXSCRIPTSIZE*8]; struct komodo_kv *ptr; char *transferpubstr,*tstr; uint64_t fee; - if ( SMART_CHAIN_SYMBOL[0] == 0 ) // disable KV for KMD + if ( SMART_CHAIN_SYMBOL[0] == 0 ) // disable KV return; dragon_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); dragon_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); diff --git a/src/hush_nSPV.h b/src/hush_nSPV.h index b2576f7ea..f8e1645d1 100644 --- a/src/hush_nSPV.h +++ b/src/hush_nSPV.h @@ -578,7 +578,7 @@ int32_t NSPV_notarizationextract(int32_t verifyntz,int32_t *ntzheightp,uint256 * int32_t numsigs=0; uint8_t elected[64][33]; char *symbol; std::vector opret; uint32_t nTime; if ( tx.vout.size() >= 2 ) { - symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"KMD" : SMART_CHAIN_SYMBOL; + symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"HUSH3" : SMART_CHAIN_SYMBOL; GetOpReturnData(tx.vout[1].scriptPubKey,opret); if ( opret.size() >= 32*2+4 ) { diff --git a/src/hush_nSPV_fullnode.h b/src/hush_nSPV_fullnode.h index 53770f430..a33013b6a 100644 --- a/src/hush_nSPV_fullnode.h +++ b/src/hush_nSPV_fullnode.h @@ -38,7 +38,7 @@ struct NSPV_ntzargs int32_t NSPV_notarization_find(struct NSPV_ntzargs *args,int32_t height,int32_t dir) { int32_t ntzheight = 0; uint256 hashBlock; CTransaction tx; Notarization nota; char *symbol; std::vector opret; - symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"KMD" : SMART_CHAIN_SYMBOL; + symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"HUSH3" : SMART_CHAIN_SYMBOL; memset(args,0,sizeof(*args)); if ( dir > 0 ) height += 10; From 91383d0bc591120dbd712fb8a1f61e42ef7f29cc Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 12:56:43 -0400 Subject: [PATCH 010/115] . --- src/hush_gateway.h | 6 +++--- src/main.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index c3f99de84..fb4372d21 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -1753,10 +1753,10 @@ CScript komodo_mineropret(int32_t nHeight) } /* - komodo_opretvalidate() is the entire price validation! + 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 komodo_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. + 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. */ @@ -1772,7 +1772,7 @@ void komodo_queuelocalprice(int32_t dir,int32_t height,uint32_t timestamp,uint25 ExtremePrice.pricebits = pricebits; } -int32_t komodo_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int32_t nHeight,CScript scriptPubKey) +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; diff --git a/src/main.cpp b/src/main.cpp index ec02f3a79..e33ec9065 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1201,7 +1201,7 @@ bool ContextualCheckCoinbaseTransaction(int32_t slowflag,const CBlock *block,CBl { if ( slowflag != 0 && ASSETCHAINS_CBOPRET != 0 && validateprices != 0 && nHeight > 0 && tx.vout.size() > 0 ) { - if ( komodo_opretvalidate(block,previndex,nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 ) + if ( hush_opretvalidate(block,previndex,nHeight,tx.vout[tx.vout.size()-1].scriptPubKey) < 0 ) return(false); } return(true); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4da6204e6..42589b38e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -683,7 +683,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) //for (i=0; i<32; i++) // printf("%02x",((uint8_t *)&sig)[i]); //printf(" sig for keylen.%d + valuesize.%d\n",keylen,refvaluesize); - ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "KMD" : SMART_CHAIN_SYMBOL))); + ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH3" : SMART_CHAIN_SYMBOL))); height = chainActive.LastTip()->GetHeight(); if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) ret.push_back(Pair("owner",refpubkey.GetHex())); From 5a3f5b4152843a68ec2a36bb9e8f3b93ad6efda4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 10 Jul 2021 14:05:20 -0400 Subject: [PATCH 011/115] . --- Makefile.am | 4 ++++ src/cc/CCutils.cpp | 16 +++++++-------- src/cc/channels.cpp | 16 +++++++-------- src/cc/gateways.cpp | 42 ++++++++++++++++++++-------------------- src/cc/import.cpp | 2 +- src/cc/importgateway.cpp | 32 +++++++++++++++--------------- src/hush_bitcoind.h | 6 +++--- src/hush_defs.h | 2 +- src/rpc/misc.cpp | 8 ++++---- 9 files changed, 66 insertions(+), 62 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7b4d44e2d..90085c5e2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,7 @@ +# Copyright 2016-2021 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 + ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src if ENABLE_MAN diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 9e9ccc765..e40698ac6 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -675,7 +675,7 @@ int32_t hush_get_current_height() else return chainActive.LastTip()->GetHeight(); } -bool komodo_txnotarizedconfirmed(uint256 txid) +bool hush_txnotarizedconfirmed(uint256 txid) { char str[65]; int32_t confirms,notarized=0,txheight=0,currentheight=0;; @@ -688,17 +688,17 @@ bool komodo_txnotarizedconfirmed(uint256 txid) { if ( NSPV_myGetTransaction(txid,tx,hashBlock,txheight,currentheight) == 0 ) { - fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str()); + fprintf(stderr,"hush_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str()); return(0); } else if (txheight<=0) { - fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d for txid %s\n",txheight,txid.ToString().c_str()); + fprintf(stderr,"hush_txnotarizedconfirmed no txheight.%d for txid %s\n",txheight,txid.ToString().c_str()); return(0); } else if (txheight>currentheight) { - fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,currentheight); + fprintf(stderr,"hush_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,currentheight); return(0); } confirms=1 + currentheight - txheight; @@ -707,22 +707,22 @@ bool komodo_txnotarizedconfirmed(uint256 txid) { if ( myGetTransaction(txid,tx,hashBlock) == 0 ) { - fprintf(stderr,"komodo_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str()); + fprintf(stderr,"hush_txnotarizedconfirmed cant find txid %s\n",txid.ToString().c_str()); return(0); } else if ( hashBlock == zeroid ) { - fprintf(stderr,"komodo_txnotarizedconfirmed no hashBlock for txid %s\n",txid.ToString().c_str()); + fprintf(stderr,"hush_txnotarizedconfirmed no hashBlock for txid %s\n",txid.ToString().c_str()); return(0); } else if ( (pindex= hush_blockindex(hashBlock)) == 0 || (txheight= pindex->GetHeight()) <= 0 ) { - fprintf(stderr,"komodo_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str()); + fprintf(stderr,"hush_txnotarizedconfirmed no txheight.%d %p for txid %s\n",txheight,pindex,txid.ToString().c_str()); return(0); } else if ( (pindex= chainActive.LastTip()) == 0 || pindex->GetHeight() < txheight ) { - fprintf(stderr,"komodo_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->GetHeight()); + fprintf(stderr,"hush_txnotarizedconfirmed backwards heights for txid %s hts.(%d %d)\n",txid.ToString().c_str(),txheight,(int32_t)pindex->GetHeight()); return(0); } confirms=1 + pindex->GetHeight() - txheight; diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 97728d1e7..135d0dc9d 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -249,7 +249,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("vout.1 is CC marker to srcpub or invalid amount for channelopen!"); else if ( ConstrainVout(channelOpenTx.vout[2],1,destmarker,CC_MARKER_VALUE)==0 ) return eval->Invalid("vout.2 is CC marker to destpub or invalid amount for channelopen!"); - else if (komodo_txnotarizedconfirmed(opentxid) == 0) + else if (hush_txnotarizedconfirmed(opentxid) == 0) return eval->Invalid("channelopen is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelpayment!"); @@ -310,7 +310,7 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("vout.1 is CC marker to srcpub or invalid amount for channelopen!"); else if ( ConstrainVout(channelOpenTx.vout[2],1,destmarker,CC_MARKER_VALUE)==0 ) return eval->Invalid("vout.2 is CC marker to destpub or invalid amount for channelopen!"); - else if (komodo_txnotarizedconfirmed(opentxid) == 0) + else if (hush_txnotarizedconfirmed(opentxid) == 0) return eval->Invalid("channelopen is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelclose!"); @@ -351,9 +351,9 @@ bool ChannelsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return eval->Invalid("vout.1 is CC marker to srcpub or invalid amount for channelopen!"); else if ( ConstrainVout(channelOpenTx.vout[2],1,destmarker,CC_MARKER_VALUE)==0 ) return eval->Invalid("vout.2 is CC marker to destpub or invalid amount for channelopen!"); - else if (komodo_txnotarizedconfirmed(opentxid) == 0) + else if (hush_txnotarizedconfirmed(opentxid) == 0) return eval->Invalid("channelopen is not yet confirmed(notarised)!"); - else if (komodo_txnotarizedconfirmed(param3) == 0) + else if (hush_txnotarizedconfirmed(param3) == 0) return eval->Invalid("channelClose is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for channelrefund!"); @@ -537,7 +537,7 @@ UniValue ChannelPayment(const CPubKey& pk, uint64_t txfee,uint256 opentxid,int64 } else CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx"); - if (komodo_txnotarizedconfirmed(opentxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsopen tx not yet confirmed/notarized"); + if (hush_txnotarizedconfirmed(opentxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsopen tx not yet confirmed/notarized"); if (AddNormalinputs(mtx,mypk,txfee+CC_MARKER_VALUE,3,pk.IsValid()) > 0) { if ((funds=AddChannelsInputs(cp,mtx,channelOpenTx,prevtxid,mypk)) !=0 && (change=funds-amount)>=0) @@ -612,7 +612,7 @@ UniValue ChannelClose(const CPubKey& pk, uint64_t txfee,uint256 opentxid) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open txid"); if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,tmp_txid,srcpub,destpub,numpayments,payment,hashchain)!='O') CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx"); - if (komodo_txnotarizedconfirmed(opentxid)==false) + if (hush_txnotarizedconfirmed(opentxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream <<"channelsopen tx not yet confirmed/notarized"); if (mypk != srcpub) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "cannot close, you are not channel owner"); @@ -650,13 +650,13 @@ UniValue ChannelRefund(const CPubKey& pk, uint64_t txfee,uint256 opentxid,uint25 CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel close txid"); if ((numvouts=channelCloseTx.vout.size()) < 1 || DecodeChannelsOpRet(channelCloseTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,param1,param2,param3)!='C') CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel close tx"); - if (komodo_txnotarizedconfirmed(closetxid)==false) + if (hush_txnotarizedconfirmed(closetxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsclose tx not yet confirmed/notarized"); if (txid!=opentxid) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "open and close txid are not from same channel"); if (myGetTransaction(opentxid,channelOpenTx,hashblock) == 0) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open txid"); - if (komodo_txnotarizedconfirmed(opentxid)==false) + if (hush_txnotarizedconfirmed(opentxid)==false) CCERR_RESULT("channelscc",CCLOG_INFO, stream << "channelsopen tx not yet confirmed/notarized"); if ((numvouts=channelOpenTx.vout.size()) < 1 || DecodeChannelsOpRet(channelOpenTx.vout[numvouts-1].scriptPubKey,tokenid,txid,srcpub,destpub,numpayments,payment,hashchain)!='O') CCERR_RESULT("channelscc",CCLOG_INFO, stream << "invalid channel open tx"); diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index fe70b4625..fdd304a05 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -612,7 +612,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & sprintf(validationError,"illegal format %s != Ihh\n",format.c_str()); return eval->Invalid(validationError); } - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if (myGetTransaction(deposittxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysdeposittxid!"); @@ -630,7 +630,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("bindtxid does not match to bindtxid from gatewaysdeposit"); else if (tmpamount>totalsupply) return eval->Invalid("deposit amount greater then bind total supply"); - else if (komodo_txnotarizedconfirmed(deposittxid) == false) + else if (hush_txnotarizedconfirmed(deposittxid) == false) return eval->Invalid("gatewaysdeposit tx is not yet confirmed(notarised)!"); else if (tx.vin.size()>0) { @@ -704,7 +704,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("invalid marker vout for gatewaysWithdraw!"); else if ( ConstrainVout(tmptx.vout[1],1,gatewaystokensaddr,amount)==0) return eval->Invalid("invalid tokens to gateways vout for gatewaysWithdraw!"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -714,7 +714,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("refcoin different than in bind tx"); else if (tmptokenid!=tokenid) return eval->Invalid("tokenid does not match tokenid from gatewaysbind"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if (IsCCInput(tx.vin[0].scriptSig) != 0) return eval->Invalid("vin.0 is normal for gatewayspartialsign!"); @@ -746,7 +746,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("invalid tokens to gateways vout for gatewaysWithdraw!"); else if (tmptx.vout[1].nValue!=amount) return eval->Invalid("amount in opret not matching tx tokens amount!"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -756,7 +756,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("refcoin different than in bind tx"); else if (tmptokenid!=tokenid) return eval->Invalid("tokenid does not match tokenid from gatewaysbind"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if (IsCCInput(tx.vin[0].scriptSig) != 0) return eval->Invalid("vin.0 is normal for gatewayscompletesigning!"); @@ -777,7 +777,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("invalid gatewayscompletesigning txid!"); else if ((numvouts=tmptx.vout.size()) > 0 && DecodeGatewaysCompleteSigningOpRet(tmptx.vout[numvouts-1].scriptPubKey,withdrawtxid,tmprefcoin,K,hex)!='S') return eval->Invalid("invalid gatewayscompletesigning OP_RETURN data!"); - else if (komodo_txnotarizedconfirmed(completetxid) == false) + else if (hush_txnotarizedconfirmed(completetxid) == false) return eval->Invalid("gatewayscompletesigning tx is not yet confirmed(notarised)!"); else if (myGetTransaction(withdrawtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid withdraw txid!"); @@ -785,7 +785,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("invalid gatewayswithdraw OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -795,7 +795,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction & return eval->Invalid("refcoin different than in bind tx"); else if (tmptokenid!=tokenid) return eval->Invalid("tokenid does not match tokenid from gatewaysbind"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for gatewaysmarkdone!"); @@ -946,7 +946,7 @@ UniValue GatewaysDeposit(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,int3 CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex()); if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin ) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin); - if (komodo_txnotarizedconfirmed(bindtxid)==false) + if (hush_txnotarizedconfirmed(bindtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized"); n = (int32_t)pubkeys.size(); merkleroot = zeroid; @@ -997,13 +997,13 @@ UniValue GatewaysClaim(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std::s CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex()); if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin ) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin); - if (komodo_txnotarizedconfirmed(bindtxid)==false) + if (hush_txnotarizedconfirmed(bindtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized"); if ( myGetTransaction(deposittxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 ) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find deposittxid " << bindtxid.GetHex()); if (DecodeGatewaysDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmptxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,tmpdestpub,tmpamount) != 'D' || coin != refcoin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - deposittxid " << bindtxid.GetHex() << " coin." << coin); - if (komodo_txnotarizedconfirmed(deposittxid)==false) + if (hush_txnotarizedconfirmed(deposittxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysdeposit tx not yet confirmed/notarized"); if (tmpdestpub!=destpub) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "different destination pubkey from desdeposit tx"); @@ -1038,7 +1038,7 @@ UniValue GatewaysWithdraw(const CPubKey& pk, uint64_t txfee,uint256 bindtxid,std CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cant find bindtxid " << bindtxid.GetHex()); if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin ) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid coin - bindtxid " << bindtxid.GetHex() << " coin." << coin); - if (komodo_txnotarizedconfirmed(bindtxid)==false) + if (hush_txnotarizedconfirmed(bindtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewaysbind tx not yet confirmed/notarized"); _GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk); SetCCunspents(unspentOutputs,coinaddr,true); @@ -1097,7 +1097,7 @@ UniValue GatewaysPartialSign(const CPubKey& pk, uint64_t txfee,uint256 lasttxid, withdrawtxid=lasttxid; if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << lasttxid.GetHex()); - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized"); else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex()); @@ -1114,7 +1114,7 @@ UniValue GatewaysPartialSign(const CPubKey& pk, uint64_t txfee,uint256 lasttxid, else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << withdrawtxid.GetHex()); - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized"); else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex()); @@ -1151,7 +1151,7 @@ UniValue GatewaysCompleteSigning(const CPubKey& pk, uint64_t txfee,uint256 lastt withdrawtxid=lasttxid; if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << lasttxid.GetHex()); - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized"); else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex()); @@ -1168,7 +1168,7 @@ UniValue GatewaysCompleteSigning(const CPubKey& pk, uint64_t txfee,uint256 lastt else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw tx " << withdrawtxid.GetHex()); - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayswithdraw tx not yet confirmed/notarized"); else if (myGetTransaction(bindtxid,tmptx,hashBlock)==0 || (numvouts=tmptx.vout.size())<=0) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "can't find bind tx " << bindtxid.GetHex()); @@ -1200,7 +1200,7 @@ UniValue GatewaysMarkDone(const CPubKey& pk, uint64_t txfee,uint256 completetxid CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid completesigning txid " << completetxid.GetHex()); else if (DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex)!='S' || refcoin!=coin) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "cannot decode completesigning tx opret " << completetxid.GetHex()); - if (komodo_txnotarizedconfirmed(completetxid)==false) + if (hush_txnotarizedconfirmed(completetxid)==false) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "gatewayscompletesigning tx not yet confirmed/notarized"); else if (myGetTransaction(withdrawtxid,tx,hashBlock)==0 || (numvouts= tx.vout.size())==0) CCERR_RESULT("gatewayscc",CCLOG_INFO, stream << "invalid withdraw txid " << withdrawtxid.GetHex()); @@ -1266,7 +1266,7 @@ UniValue GatewaysPendingDeposits(const CPubKey& pk, uint256 bindtxid,std::string pub=HexStr(destpub); obj.push_back(Pair("claim_pubkey",pub)); obj.push_back(Pair("amount",(double)amount/COIN)); - obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(txid))); + obj.push_back(Pair("confirmed_or_notarized",hush_txnotarizedconfirmed(txid))); pending.push_back(obj); } } @@ -1340,7 +1340,7 @@ UniValue GatewaysPendingWithdraws(const CPubKey& pk, uint256 bindtxid,std::strin obj.push_back(Pair("withdrawaddr",withaddr)); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); obj.push_back(Pair("amount",numstr)); - obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(tx.GetHash()))); + obj.push_back(Pair("confirmed_or_notarized",hush_txnotarizedconfirmed(tx.GetHash()))); if ( queueflag != 0 ) { obj.push_back(Pair("depositaddr",depositaddr)); @@ -1415,7 +1415,7 @@ UniValue GatewaysProcessedWithdraws(const CPubKey& pk, uint256 bindtxid,std::str obj.push_back(Pair("withdrawtxidaddr",txidaddr)); GetCustomscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG,taddr,prefix,prefix2); obj.push_back(Pair("withdrawaddr",withaddr)); - obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(txid))); + obj.push_back(Pair("confirmed_or_notarized",hush_txnotarizedconfirmed(txid))); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); obj.push_back(Pair("amount",numstr)); obj.push_back(Pair("hex",hex)); diff --git a/src/cc/import.cpp b/src/cc/import.cpp index 06fc75dff..61e901e84 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -395,7 +395,7 @@ int32_t CheckGATEWAYimport(CTransaction importTx,CTransaction burnTx,std::string LOGSTREAM("importgateway", CCLOG_INFO, stream << "CheckGATEWAYimport not enough pubkeys for given N " << std::endl); return(-1); } - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) { LOGSTREAM("importgateway", CCLOG_INFO, stream << "CheckGATEWAYimport bindtx not yet confirmed/notarized" << std::endl); return(-1); diff --git a/src/cc/importgateway.cpp b/src/cc/importgateway.cpp index b2cd169f7..499721909 100644 --- a/src/cc/importgateway.cpp +++ b/src/cc/importgateway.cpp @@ -362,7 +362,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid tokens to gateways vout for gatewaysWithdraw!"); else if (tmptx.vout[1].nValue!=amount) return eval->Invalid("amount in opret not matching tx tokens amount!"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -370,7 +370,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if (IsCCInput(tx.vin[0].scriptSig) != 0) return eval->Invalid("vin.0 is normal for gatewayspartialsign!"); @@ -404,7 +404,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid tokens to gateways vout for gatewaysWithdraw!"); else if (tmptx.vout[1].nValue!=amount) return eval->Invalid("amount in opret not matching tx tokens amount!"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -412,7 +412,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if (IsCCInput(tx.vin[0].scriptSig) != 0) return eval->Invalid("vin.0 is normal for gatewayscompletesigning!"); @@ -433,7 +433,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid gatewayscompletesigning txid!"); else if ((numvouts=tmptx.vout.size()) > 0 && DecodeImportGatewayCompleteSigningOpRet(tmptx.vout[numvouts-1].scriptPubKey,withdrawtxid,tmprefcoin,K,hex)!='S') return eval->Invalid("invalid gatewayscompletesigning OP_RETURN data!"); - else if (komodo_txnotarizedconfirmed(completetxid) == false) + else if (hush_txnotarizedconfirmed(completetxid) == false) return eval->Invalid("gatewayscompletesigning tx is not yet confirmed(notarised)!"); else if (myGetTransaction(withdrawtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid withdraw txid!"); @@ -441,7 +441,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid gatewayswithdraw OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); - else if (komodo_txnotarizedconfirmed(withdrawtxid) == false) + else if (hush_txnotarizedconfirmed(withdrawtxid) == false) return eval->Invalid("gatewayswithdraw tx is not yet confirmed(notarised)!"); else if (myGetTransaction(bindtxid,tmptx,hashblock) == 0) return eval->Invalid("invalid gatewaysbind txid!"); @@ -449,7 +449,7 @@ bool ImportGatewayValidate(struct CCcontract_info *cp,Eval *eval,const CTransact return eval->Invalid("invalid gatewaysbind OP_RETURN data!"); else if (tmprefcoin!=refcoin) return eval->Invalid("refcoin different than in bind tx"); - else if (komodo_txnotarizedconfirmed(bindtxid) == false) + else if (hush_txnotarizedconfirmed(bindtxid) == false) return eval->Invalid("gatewaysbind tx is not yet confirmed(notarised)!"); else if ( IsCCInput(tx.vin[0].scriptSig) != 0 ) return eval->Invalid("vin.0 is normal for gatewaysmarkdone!"); @@ -597,7 +597,7 @@ std::string ImportGatewayDeposit(uint64_t txfee,uint256 bindtxid,int32_t height, LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if (komodo_txnotarizedconfirmed(bindtxid)==false) + if (hush_txnotarizedconfirmed(bindtxid)==false) { CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -673,7 +673,7 @@ std::string ImportGatewayWithdraw(uint64_t txfee,uint256 bindtxid,std::string re LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if (komodo_txnotarizedconfirmed(bindtxid)==false) + if (hush_txnotarizedconfirmed(bindtxid)==false) { CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -754,7 +754,7 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) { CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -801,7 +801,7 @@ std::string ImportGatewayPartialSign(uint64_t txfee,uint256 lasttxid,std::string LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) { CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -872,7 +872,7 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) { CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -918,7 +918,7 @@ std::string ImportGatewayCompleteSigning(uint64_t txfee,uint256 lasttxid,std::st LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - else if (komodo_txnotarizedconfirmed(withdrawtxid)==false) + else if (hush_txnotarizedconfirmed(withdrawtxid)==false) { CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -972,7 +972,7 @@ std::string ImportGatewayMarkDone(uint64_t txfee,uint256 completetxid,std::strin LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); return(""); } - if (komodo_txnotarizedconfirmed(completetxid)==false) + if (hush_txnotarizedconfirmed(completetxid)==false) { CCerror = strprintf("gatewayscompletesigning tx not yet confirmed/notarized"); LOGSTREAM("importgateway",CCLOG_INFO, stream << CCerror << std::endl); @@ -1084,7 +1084,7 @@ UniValue ImportGatewayPendingWithdraws(uint256 bindtxid,std::string refcoin) obj.push_back(Pair("withdrawaddr",withaddr)); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); obj.push_back(Pair("amount",numstr)); - obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(tx.GetHash()))); + obj.push_back(Pair("confirmed_or_notarized",hush_txnotarizedconfirmed(tx.GetHash()))); if ( queueflag != 0 ) { obj.push_back(Pair("depositaddr",burnaddr)); @@ -1159,7 +1159,7 @@ UniValue ImportGatewayProcessedWithdraws(uint256 bindtxid,std::string refcoin) obj.push_back(Pair("withdrawtxidaddr",txidaddr)); GetCustomscriptaddress(withaddr,CScript() << ParseHex(HexStr(withdrawpub)) << OP_CHECKSIG,taddr,prefix,prefix2); obj.push_back(Pair("withdrawaddr",withaddr)); - obj.push_back(Pair("confirmed_or_notarized",komodo_txnotarizedconfirmed(txid))); + obj.push_back(Pair("confirmed_or_notarized",hush_txnotarizedconfirmed(txid))); sprintf(numstr,"%.8f",(double)tx.vout[1].nValue/COIN); obj.push_back(Pair("amount",numstr)); obj.push_back(Pair("hex",hex)); diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 663491e7f..26a3f8f74 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -384,11 +384,11 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) return(retstr2); } -int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp) +int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_heightp) { char *jsonstr,params[256],*userpass; uint16_t port; cJSON *json,*item; int32_t height = 0,txid_height = 0,txid_confirmations = 0; params[0] = 0; - *kmdnotarized_heightp = 0; + *hushnotarized_heightp = 0; if ( strcmp(dest,"HUSH3") == 0 ) { port = HUSH3_PORT; userpass = HUSHUSERPASS; @@ -409,7 +409,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heig if ( (item= jobj(json,(char *)"result")) != 0 ) { height = jint(item,(char *)"blocks"); - *kmdnotarized_heightp = strcmp(dest,"KMD") == 0 ? jint(item,(char *)"notarized") : height; + *hushnotarized_heightp = strcmp(dest,"KMD") == 0 ? jint(item,(char *)"notarized") : height; } free_json(json); } diff --git a/src/hush_defs.h b/src/hush_defs.h index f1ea61524..4c10acd3e 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -567,7 +567,7 @@ int32_t hush_nextheight(); CBlockIndex *hush_blockindex(uint256 hash); CBlockIndex *hush_chainactive(int32_t height); int32_t hush_blockheight(uint256 hash); -bool komodo_txnotarizedconfirmed(uint256 txid); +bool hush_txnotarizedconfirmed(uint256 txid); int32_t hush_blockload(CBlock& block, CBlockIndex *pindex); uint32_t hush_chainactive_timestamp(); uint32_t GetLatestTimestamp(int32_t height); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index d4f797b0e..fb1b3116c 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -59,7 +59,7 @@ using namespace std; int32_t hush_longestchain(); int32_t hush_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp); -bool komodo_txnotarizedconfirmed(uint256 txid); +bool hush_txnotarizedconfirmed(uint256 txid); uint32_t hush_chainactive_timestamp(); int32_t hush_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); extern int32_t HUSH_LASTMINED,HUSH_LONGESTCHAIN,IS_HUSH_NOTARY,HUSH_INSYNC; @@ -230,7 +230,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString())); if ( HUSH_NSPV_FULLNODE ) { - txid_height = notarizedtxid_height(SMART_CHAIN_SYMBOL[0] != 0 ? (char *)"HUSH" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&hushnotarized_height); + txid_height = notarizedtxid_height(SMART_CHAIN_SYMBOL[0] != 0 ? (char *)"HUSH3" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&hushnotarized_height); if ( txid_height > 0 ) obj.push_back(Pair("notarizedtxid_height", txid_height)); else obj.push_back(Pair("notarizedtxid_height", "mempool")); @@ -1463,7 +1463,7 @@ UniValue txnotarizedconfirmed(const UniValue& params, bool fHelp, const CPubKey& if (fHelp || params.size() < 1 || params.size() > 1) { string msg = "txnotarizedconfirmed txid\n" - "\nReturns true if transaction is notarized on chain that has dPoW or if confirmation number is greater than 60 on chain taht does not have dPoW.\n" + "\nReturns true if transaction is notarized on chain that has dPoW or if confirmation number is greater than 60 on chain that does not have dPoW.\n" "\nArguments:\n" "1. txid (string, required) Transaction id.\n" @@ -1476,7 +1476,7 @@ UniValue txnotarizedconfirmed(const UniValue& params, bool fHelp, const CPubKey& throw runtime_error(msg); } txid = uint256S((char *)params[0].get_str().c_str()); - notarizedconfirmed=komodo_txnotarizedconfirmed(txid); + notarizedconfirmed=hush_txnotarizedconfirmed(txid); UniValue result(UniValue::VOBJ); result.push_back(Pair("result", notarizedconfirmed)); return result; From d884626ac85b53f4956c68c1382314f99cb913b0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 17:29:59 -0400 Subject: [PATCH 012/115] Update default rpcworkqueue=512 --- src/cc/rogue/main.c | 12 +++--------- src/hush_utils.h | 10 ++++++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index 3052b72ee..a8587ad54 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -699,15 +699,9 @@ uint16_t komodo_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[HUSH_SMART_CHAIN_MAXLEN]; userpass[0] = 0; - if ( strcmp("KMD",symbol) == 0 ) - { -#ifdef __APPLE__ - sprintf(confname,"Komodo.conf"); -#else - sprintf(confname,"komodo.conf"); -#endif - } - else sprintf(confname,"%s.conf",symbol); + + sprintf(confname,"%s.conf",symbol); + //hush_statefname(fname,symbol,confname); if ( (fp= fopen(confname,"rb")) != 0 ) { diff --git a/src/hush_utils.h b/src/hush_utils.h index 439d85eab..e16e4d0d6 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1366,7 +1366,7 @@ void hush_statefname(char *fname,char *symbol,char *str) //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,SMART_CHAIN_SYMBOL,symbol,fname); } -void komodo_configfile(char *symbol,uint16_t rpcport) +void hush_configfile(char *symbol,uint16_t rpcport) { static char myusername[512],mypassword[8192]; FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i; @@ -1398,7 +1398,7 @@ void komodo_configfile(char *symbol,uint16_t rpcport) #ifndef FROM_CLI if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=256\nrpcallowip=127.0.0.1\nrpcbind=127.0.0.1\n",crc,password,rpcport); + fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=512\nrpcallowip=127.0.0.1\nrpcbind=127.0.0.1\n",crc,password,rpcport); fclose(fp); printf("Created (%s)\n",fname); } else printf("Couldnt create (%s)\n",fname); @@ -1432,7 +1432,9 @@ void komodo_configfile(char *symbol,uint16_t rpcport) sprintf(HUSHUSERPASS,"%s:%s",username,password); fclose(fp); //printf("HUSH.(%s) -> userpass.(%s)\n",fname,HUSHUSERPASS); - } //else printf("couldnt open.(%s)\n",fname); + } else { + printf("couldnt open.(%s)\n",fname); + } } uint16_t komodo_userpass(char *userpass,char *symbol) @@ -2344,7 +2346,7 @@ void hush_args(char *argv0) } if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,SMART_CHAIN_SYMBOL)) != 0 ) ASSETCHAINS_RPCPORT = port; - else komodo_configfile(SMART_CHAIN_SYMBOL,ASSETCHAINS_P2PPORT + 1); + else hush_configfile(SMART_CHAIN_SYMBOL,ASSETCHAINS_P2PPORT + 1); if (ASSETCHAINS_CBMATURITY != 0) COINBASE_MATURITY = ASSETCHAINS_CBMATURITY; From cfcc2f5288d8069fd3a55307c06dea6cf4e3a4a1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 17:30:44 -0400 Subject: [PATCH 013/115] hush_userpass --- src/cc/rogue/main.c | 8 ++++---- src/hush_utils.h | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index a8587ad54..f6201df19 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -620,7 +620,7 @@ char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char * return(chunk.memory); } -uint16_t _komodo_userpass(char *username, char *password, FILE *fp) +uint16_t _hush_userpass(char *username, char *password, FILE *fp) { char *rpcuser,*rpcpassword,*str,*ipaddress,line[8192]; uint16_t port = 0; rpcuser = rpcpassword = 0; @@ -695,7 +695,7 @@ uint16_t _komodo_userpass(char *username, char *password, FILE *fp) //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); }*/ -uint16_t komodo_userpass(char *userpass,char *symbol) +uint16_t hush_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[HUSH_SMART_CHAIN_MAXLEN]; userpass[0] = 0; @@ -705,7 +705,7 @@ uint16_t komodo_userpass(char *userpass,char *symbol) //hush_statefname(fname,symbol,confname); if ( (fp= fopen(confname,"rb")) != 0 ) { - port = _komodo_userpass(username,password,fp); + port = _hush_userpass(username,password,fp); sprintf(userpass,"%s:%s",username,password); if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 ) strcpy(USERPASS,userpass); @@ -1001,7 +1001,7 @@ int main(int argc, char **argv, char **envp) #endif #endif - ROGUE_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL); + ROGUE_PORT = hush_userpass(userpass,ASSETCHAINS_SYMBOL); if ( IPADDRESS[0] == 0 ) strcpy(IPADDRESS,"127.0.0.1"); printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s) IPADDRESS.%s \n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS,IPADDRESS); sleep(1); diff --git a/src/hush_utils.h b/src/hush_utils.h index e16e4d0d6..02f53a554 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1295,7 +1295,7 @@ void dragon_initQ(queue_t *Q,char *name) free(item); } -uint16_t _komodo_userpass(char *username,char *password,FILE *fp) +uint16_t _hush_userpass(char *username,char *password,FILE *fp) { char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0; rpcuser = rpcpassword = 0; @@ -1404,7 +1404,7 @@ void hush_configfile(char *symbol,uint16_t rpcport) } else printf("Couldnt create (%s)\n",fname); #endif } else { - _komodo_userpass(myusername,mypassword,fp); + _hush_userpass(myusername,mypassword,fp); mapArgs["-rpcpassword"] = mypassword; mapArgs["-rpcusername"] = myusername; //fprintf(stderr,"myusername.(%s)\n",myusername); @@ -1427,7 +1427,7 @@ void hush_configfile(char *symbol,uint16_t rpcport) #endif if ( (fp= fopen(fname,"rb")) != 0 ) { - if ( (kmdport= _komodo_userpass(username,password,fp)) != 0 ) + if ( (kmdport= _hush_userpass(username,password,fp)) != 0 ) HUSH3_PORT = kmdport; sprintf(HUSHUSERPASS,"%s:%s",username,password); fclose(fp); @@ -1437,7 +1437,7 @@ void hush_configfile(char *symbol,uint16_t rpcport) } } -uint16_t komodo_userpass(char *userpass,char *symbol) +uint16_t hush_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[HUSH_SMART_CHAIN_MAXLEN]; userpass[0] = 0; @@ -1453,7 +1453,7 @@ uint16_t komodo_userpass(char *userpass,char *symbol) hush_statefname(fname,symbol,confname); if ( (fp= fopen(fname,"rb")) != 0 ) { - port = _komodo_userpass(username,password,fp); + port = _hush_userpass(username,password,fp); sprintf(userpass,"%s:%s",username,password); if ( strcmp(symbol,SMART_CHAIN_SYMBOL) == 0 ) strcpy(ASSETCHAINS_USERPASS,userpass); @@ -2344,7 +2344,7 @@ void hush_args(char *argv0) { fprintf(stderr,"Oh hellz yezzz\n"); } - if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,SMART_CHAIN_SYMBOL)) != 0 ) + if ( (port= hush_userpass(ASSETCHAINS_USERPASS,SMART_CHAIN_SYMBOL)) != 0 ) ASSETCHAINS_RPCPORT = port; else hush_configfile(SMART_CHAIN_SYMBOL,ASSETCHAINS_P2PPORT + 1); @@ -2421,7 +2421,7 @@ void hush_args(char *argv0) #endif if ( (fp= fopen(fname,"rb")) != 0 ) { - _komodo_userpass(username,password,fp); + _hush_userpass(username,password,fp); sprintf(iter == 0 ? HUSHUSERPASS : BTCUSERPASS,"%s:%s",username,password); fclose(fp); //printf("HUSH.(%s) -> userpass.(%s)\n",fname,HUSHUSERPASS); From aa39fc4f4936b8991cd5bb3ca28b1a489fe12c8e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 17:32:06 -0400 Subject: [PATCH 014/115] hush_baseid --- src/hush_gateway.h | 18 +++++++++--------- src/hush_globals.h | 4 ++-- src/hush_pax.h | 10 +++++----- src/hush_utils.h | 12 ++++-------- src/miner.cpp | 6 +++--- 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index fb4372d21..764c59aaf 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -32,7 +32,7 @@ int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued, { int32_t baseid; struct hush_state *sp; int64_t netliability,maxallowed,maxval; *available = *deposited = *issued = *withdrawn = *approved = *redeemed = 0; - if ( (baseid= komodo_baseid(base)) >= 0 ) + if ( (baseid= hush_baseid(base)) >= 0 ) { if ( (sp= hush_stateptrget(base)) != 0 ) { @@ -241,7 +241,7 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t kmdheights[n] = p.height; otherheights[n] = p.otherheight; memcpy(&rmd160s[n * 20],p.rmd160,20); - baseids[n] = komodo_baseid(p.source); + baseids[n] = hush_baseid(p.source); if ( 0 ) { char coinaddr[64]; @@ -261,7 +261,7 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t } vouts[n] = opretbuf[len++]; vouts[n] = (opretbuf[len++] << 8) | vouts[n]; - baseids[n] = komodo_baseid(base); + baseids[n] = hush_baseid(base); if ( (pax= komodo_paxfinds(txids[n],vouts[n])) != 0 ) { values[n] = (strcmp("KMD",base) == 0) ? pax->komodoshis : pax->fiatoshis; @@ -483,7 +483,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to struct hush_state *kmdsp = hush_stateptrget((char *)"KMD"); sp = hush_stateptr(symbol,dest); strcpy(symbol,base); - if ( SMART_CHAIN_SYMBOL[0] != 0 && komodo_baseid(SMART_CHAIN_SYMBOL) < 0 ) + if ( SMART_CHAIN_SYMBOL[0] != 0 && hush_baseid(SMART_CHAIN_SYMBOL) < 0 ) return(0); PENDING_HUSH_TX = 0; for (i=0; i<3; i++) @@ -556,7 +556,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to { if ( kmdsp != 0 ) { - if ( (baseid= komodo_baseid(pax->symbol)) < 0 || ((1LL << baseid) & sp->RTmask) == 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<= 38 ) { - if ( komodo_baseid((char *)&opretbuf[opretlen-4]) >= 0 && strcmp(SMART_CHAIN_SYMBOL,(char *)&opretbuf[opretlen-4]) == 0 ) + if ( hush_baseid((char *)&opretbuf[opretlen-4]) >= 0 && strcmp(SMART_CHAIN_SYMBOL,(char *)&opretbuf[opretlen-4]) == 0 ) { for (i=0; isymbol); + baseids[i] = hush_baseid(pax->symbol); printf("override neg1 with (%s)\n",pax->symbol); } if ( baseids[i] < 0 ) @@ -1444,7 +1444,7 @@ void hush_passport_iteration() limit = 10000000; } else { limit = 10000000; - refid = komodo_baseid(SMART_CHAIN_SYMBOL)+1; // illegal base -> baseid.-1 -> 0 + refid = hush_baseid(SMART_CHAIN_SYMBOL)+1; // illegal base -> baseid.-1 -> 0 if ( refid == 0 ) { HUSH_PASSPORT_INITDONE = 1; diff --git a/src/hush_globals.h b/src/hush_globals.h index 97415bd50..0da48075a 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -111,7 +111,7 @@ char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", "KMD" }; -int32_t komodo_baseid(char *origbase) +int32_t hush_baseid(char *origbase) { int32_t i; char base[64]; for (i=0; origbase[i]!=0&&i= 0 && baseid < 32 ) + //if ( (baseid = hush_baseid(SMART_CHAIN_SYMBOL)) >= 0 && baseid < 32 ) // cur_money = ASSETCHAINS_GENESISTXVAL + ASSETCHAINS_SUPPLY + nHeight * ASSETCHAINS_REWARD[0] / SATOSHIDEN; //else { diff --git a/src/hush_pax.h b/src/hush_pax.h index 0290749d4..54bef872a 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -502,7 +502,7 @@ uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,cha int32_t baseid=-1,relid=-1,i; uint32_t *ptr,*pvals; if ( height > 10 ) height -= 10; - if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) + if ( (baseid= hush_baseid(base)) >= 0 && (relid= hush_baseid(rel)) >= 0 ) { //portable_mutex_lock(&komodo_mutex); for (i=NUM_PRICES-1; i>=0; i--) @@ -607,7 +607,7 @@ uint64_t _komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uin uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) { - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base); + uint64_t baseusd,basekmd,usdkmd; int32_t baseid = hush_baseid(base); if ( height >= 236000 && strcmp(rel,"kmd") == 0 ) { usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN); @@ -623,7 +623,7 @@ uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint /*uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) { - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = komodo_baseid(base); + uint64_t baseusd,basekmd,usdkmd; int32_t baseid = hush_baseid(base); //if ( strcmp(rel,"KMD") != 0 || baseid < 0 || MINDENOMS[baseid] == MINDENOMS[USD] ) // return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); //else @@ -692,7 +692,7 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel) { int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr; - if ( (baseid= komodo_baseid(base)) >= 0 && (relid= komodo_baseid(rel)) >= 0 ) + if ( (baseid= hush_baseid(base)) >= 0 && (relid= hush_baseid(rel)) >= 0 ) { for (i=NUM_PRICES-1; i>=0; i--) { @@ -726,7 +726,7 @@ uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pu { uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; int64_t komodoshis = 0; *seedp = komodo_seed(height); - if ( (baseid= komodo_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES ) + if ( (baseid= hush_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES ) { if ( 0 && origbase[0] != 0 ) printf("[%s] PAX_fiatdest illegal base.(%s)\n",SMART_CHAIN_SYMBOL,origbase); diff --git a/src/hush_utils.h b/src/hush_utils.h index 02f53a554..fbdc59493 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -811,7 +811,7 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160, int32_t komodo_is_issuer() { - if ( SMART_CHAIN_SYMBOL[0] != 0 && komodo_baseid(SMART_CHAIN_SYMBOL) >= 0 ) + if ( SMART_CHAIN_SYMBOL[0] != 0 && hush_baseid(SMART_CHAIN_SYMBOL) >= 0 ) return(1); else return(0); } @@ -2304,7 +2304,7 @@ void hush_args(char *argv0) MAX_MONEY = hush_max_money(); - if ( (baseid = komodo_baseid(SMART_CHAIN_SYMBOL)) >= 0 && baseid < 32 ) + if ( (baseid = hush_baseid(SMART_CHAIN_SYMBOL)) >= 0 && baseid < 32 ) { //komodo_maxallowed(baseid); if(fDebug) @@ -2338,12 +2338,8 @@ void hush_args(char *argv0) //fprintf(stderr,"Got datadir.(%s)\n",dirname); if ( SMART_CHAIN_SYMBOL[0] != 0 ) { - int32_t komodo_baseid(char *origbase); + int32_t hush_baseid(char *origbase); extern int COINBASE_MATURITY; - if ( strcmp(SMART_CHAIN_SYMBOL,"KMD") == 0 ) - { - fprintf(stderr,"Oh hellz yezzz\n"); - } if ( (port= hush_userpass(ASSETCHAINS_USERPASS,SMART_CHAIN_SYMBOL)) != 0 ) ASSETCHAINS_RPCPORT = port; else hush_configfile(SMART_CHAIN_SYMBOL,ASSETCHAINS_P2PPORT + 1); @@ -2465,7 +2461,7 @@ struct hush_state *hush_stateptrget(char *base) int32_t baseid; if ( base == 0 || base[0] == 0 || strcmp(base,(char *)"KYCSELLOUTS") == 0 ) return(&HUSH_STATES[33]); - else if ( (baseid= komodo_baseid(base)) >= 0 ) + else if ( (baseid= hush_baseid(base)) >= 0 ) return(&HUSH_STATES[baseid+1]); else return(&HUSH_STATES[0]); } diff --git a/src/miner.cpp b/src/miner.cpp index 7ce7cf404..93f019d7f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -138,7 +138,7 @@ uint32_t Mining_start,Mining_height; int32_t My_notaryid = -1; int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize); -int32_t komodo_baseid(char *origbase); +int32_t hush_baseid(char *origbase); int32_t hush_longestchain(); int64_t hush_block_unlocktime(uint32_t nHeight); uint64_t the_commission(const CBlock *block,int32_t height); @@ -955,7 +955,7 @@ static bool ProcessBlockFound(CBlock* pblock) return true; } -int32_t komodo_baseid(char *origbase); +int32_t hush_baseid(char *origbase); int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height); arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); int32_t FOUND_BLOCK,HUSH_MAYBEMINED; @@ -1055,7 +1055,7 @@ void static BitcoinMiner() while ( (ASSETCHAIN_INIT == 0 || HUSH_INITDONE == 0) ) { sleep(1); - if ( komodo_baseid(SMART_CHAIN_SYMBOL) < 0 ) + if ( hush_baseid(SMART_CHAIN_SYMBOL) < 0 ) break; } if ( SMART_CHAIN_SYMBOL[0] == 0 ) From bddd4c5cd3775d824fec7b1ebca724fc54463c73 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 18:03:22 -0400 Subject: [PATCH 015/115] Migrate to ~/.hush/HUSH3 for new installs, fallback to ~/.komodo/HUSH3 if that exists --- src/hush_utils.h | 18 ++++++---------- src/util.cpp | 55 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index fbdc59493..63b2d7710 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1369,7 +1369,7 @@ void hush_statefname(char *fname,char *symbol,char *str) void hush_configfile(char *symbol,uint16_t rpcport) { static char myusername[512],mypassword[8192]; - FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i; + FILE *fp; uint16_t hushport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i; if ( symbol != 0 && rpcport != 0 ) { r = (uint32_t)time(NULL); @@ -1427,8 +1427,8 @@ void hush_configfile(char *symbol,uint16_t rpcport) #endif if ( (fp= fopen(fname,"rb")) != 0 ) { - if ( (kmdport= _hush_userpass(username,password,fp)) != 0 ) - HUSH3_PORT = kmdport; + if ( (hushport= _hush_userpass(username,password,fp)) != 0 ) + HUSH3_PORT = hushport; sprintf(HUSHUSERPASS,"%s:%s",username,password); fclose(fp); //printf("HUSH.(%s) -> userpass.(%s)\n",fname,HUSHUSERPASS); @@ -1441,15 +1441,9 @@ uint16_t hush_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[HUSH_SMART_CHAIN_MAXLEN]; userpass[0] = 0; - if ( strcmp("SPECIAL",symbol) == 0 ) - { -#ifdef __APPLE__ - sprintf(confname,"Something.conf"); -#else - sprintf(confname,"Something.conf"); -#endif - } - else sprintf(confname,"%s.conf",symbol); + + sprintf(confname,"%s.conf",symbol); + hush_statefname(fname,symbol,confname); if ( (fp= fopen(fname,"rb")) != 0 ) { diff --git a/src/util.cpp b/src/util.cpp index c32332b72..7834630ba 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -497,15 +497,30 @@ boost::filesystem::path GetDefaultDataDir() if ( SMART_CHAIN_SYMBOL[0] != 0 ) strcpy(symbol,SMART_CHAIN_SYMBOL); else symbol[0] = 0; + // OLD NAMES: // Windows < Vista: C:\Documents and Settings\Username\Application Data\Komodo // Windows >= Vista: C:\Users\Username\AppData\Roaming\Komodo // Mac: ~/Library/Application Support/Komodo // Unix: ~/.komodo + + // NEW NAMES: + // Windows < Vista: C:\Documents and Settings\Username\Application Data\Hush + // Windows >= Vista: C:\Users\Username\AppData\Roaming\Hush + // Mac: ~/Library/Application Support/Hush + // Unix: ~/.hush + + // ~/.hush was actually used by the original 1.x version of Hush, but we will + // only make subdirectories inside of it, so we won't be able to overwrite + // an old wallet.dat from the Ice Ages :) #ifdef _WIN32 // Windows - if ( symbol[0] == 0 ) - return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo"; - else return GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol; + pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol; + if(fs::is_directory(pathRet)) { + // legacy directory, use that + } else { + pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol; + } + return pathRet; #else fs::path pathRet; char* pszHome = getenv("HOME"); @@ -517,19 +532,31 @@ boost::filesystem::path GetDefaultDataDir() // Mac pathRet /= "Library/Application Support"; TryCreateDirectory(pathRet); - if ( symbol[0] == 0 ) - return pathRet / "Komodo"; - else - { - pathRet /= "Komodo"; - TryCreateDirectory(pathRet); - return pathRet / symbol; + fs::path tmppath; + tmppath = pathRet; + tmppath /= "Komodo"; + if(fs::is_directory(pathRet)) { + //legacy directory, use that + TryCreateDirectory(tmppath); + return tmppath / symbol; + } else { + // New directory :) + tmppath = pathRet; + tmppath /= "Hush"; + TryCreateDirectory(tmppath); + return tmppath / symbol; } #else // Unix - if ( symbol[0] == 0 ) - return pathRet / ".komodo"; - else return pathRet / ".komodo" / symbol; + fs::path tmppath = pathRet / ".komodo" / symbol; + if(fs::is_directory(tmppath)) { + // legacy directory, use that for backward compat + return tmppath; + } else { + // New directory :) + tmppath = pathRet / ".hush" / symbol; + return tmppath; + } #endif #endif } @@ -638,8 +665,6 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) path /= BaseParams().DataDir(); fs::create_directories(path); - //std::string assetpath = path + "/assets"; - //boost::filesystem::create_directory(assetpath); return path; } From 20a4933eb2b164ffc1533b7aef418b57d89adf19 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 18:12:48 -0400 Subject: [PATCH 016/115] . --- src/hush_utils.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 63b2d7710..72ed9bbba 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1415,14 +1415,14 @@ void hush_configfile(char *symbol,uint16_t rpcport) #ifdef _WIN32 while ( fname[strlen(fname)-1] != '\\' ) fname[strlen(fname)-1] = 0; - strcat(fname,"komodo.conf"); + strcat(fname,"HUSH3.conf"); #else while ( fname[strlen(fname)-1] != '/' ) fname[strlen(fname)-1] = 0; #ifdef __APPLE__ - strcat(fname,"Komodo.conf"); + strcat(fname,"HUSH3.conf"); #else - strcat(fname,"komodo.conf"); + strcat(fname,"HUSH3.conf"); #endif #endif if ( (fp= fopen(fname,"rb")) != 0 ) @@ -1433,7 +1433,7 @@ void hush_configfile(char *symbol,uint16_t rpcport) fclose(fp); //printf("HUSH.(%s) -> userpass.(%s)\n",fname,HUSHUSERPASS); } else { - printf("couldnt open.(%s)\n",fname); + printf("could not open.(%s)\n",fname); } } From 64d1d052150de9172cf83a3b0417d9d8ef4e81f3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 18:25:32 -0400 Subject: [PATCH 017/115] cleanup --- src/hush_utils.h | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 72ed9bbba..355ef3bc1 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1735,7 +1735,7 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k) * EhBasicSolve * EhOptimisedSolve * EhIsValidSolution - * Alternatively change ASSETCHAINS_N and ASSETCHAINS_K in komodo_nk.h for fast testing. + * Alternatively change ASSETCHAINS_N and ASSETCHAINS_K in hush_nk.h for fast testing. */ if ( k == 9 && (n == 200 || n == 210) ) return(0); @@ -1746,8 +1746,6 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k) return(-1); } -char *dragonfmtstr = (char *)"curl --url \"http://127.0.0.1:7776\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":-1,\\\"VALIDATE\\\":0,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"dragon\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\",\\\"sapling\\\":1,\\\"notarypay\\\":%i}\""; - void hush_args(char *argv0) { std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0; @@ -2357,21 +2355,7 @@ void hush_args(char *argv0) for (i=0; i<4; i++) sprintf(&magicstr[i<<1],"%02x",magic[i]); magicstr[8] = 0; -#ifndef FROM_CLI - /* - sprintf(fname,"%s_7776",SMART_CHAIN_SYMBOL); - // TODO: why are we doing this again? Most users do not need this - if ( (fp= fopen(fname,"wb")) != 0 ) - { - int8_t notarypay = 0; - if ( ASSETCHAINS_NOTARY_PAY[0] != 0 ) - notarypay = 1; - fprintf(fp,dragonfmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,"78.47.196.146",notarypay); - fclose(fp); - //printf("created (%s)\n",fname); - } else printf("error creating (%s)\n",fname); - */ -#endif + if ( ASSETCHAINS_CC < 2 ) { if ( HUSH_CCACTIVATE != 0 ) @@ -2394,18 +2378,18 @@ void hush_args(char *argv0) while ( fname[strlen(fname)-1] != '\\' ) fname[strlen(fname)-1] = 0; if ( iter == 0 ) - strcat(fname,"Komodo\\komodo.conf"); + strcat(fname,"Hush\\HUSH3\\HUSH3.conf"); else strcat(fname,"Bitcoin\\bitcoin.conf"); #else while ( fname[strlen(fname)-1] != '/' ) fname[strlen(fname)-1] = 0; #ifdef __APPLE__ if ( iter == 0 ) - strcat(fname,"Komodo/Komodo.conf"); + strcat(fname,"Hush/HUSH3/HUSH3.conf"); else strcat(fname,"Bitcoin/Bitcoin.conf"); #else if ( iter == 0 ) - strcat(fname,".komodo/komodo.conf"); + strcat(fname,".hush/HUSH3/HUSH3.conf"); else strcat(fname,".bitcoin/bitcoin.conf"); #endif #endif From 02d50b12e4cd10ab2eb1327a377e6d3fa5427011 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 18:25:59 -0400 Subject: [PATCH 018/115] -ac_cc now defaults to 2, which is what HUSH3 uses --- 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 355ef3bc1..de616fdb5 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1813,7 +1813,7 @@ void hush_args(char *argv0) HUSH_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; - ASSETCHAINS_CC = GetArg("-ac_cc",0); + ASSETCHAINS_CC = GetArg("-ac_cc",2); HUSH_CCACTIVATE = GetArg("-ac_ccactivate",0); ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60); ASSETCHAINS_PUBLIC = 0; From d62d38312f2a84180892a9a0f321648babe09d73 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:03:02 -0400 Subject: [PATCH 019/115] Cleanup and make all custom hushd settings defaults for HUSH3 mainnet --- src/hush_utils.h | 28 +++++++++++++++++++--------- src/init.cpp | 8 ++++---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index de616fdb5..09c0e0e8a 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1761,12 +1761,6 @@ void hush_args(char *argv0) { HUSH_MININGTHREADS = GetArg("-genproclimit",-1); } - if ( (GetBoolArg("-exchange", false)) != 0 ) { - printf("The KMD-only feature -exchange is not supported by HUSH!\n"); - printf("jl777 uses this \"feature\" to steal from his own users!\n"); - printf("Learn more at https://duke.hush.is :)\n"); - StartShutdown(); - } DONATION_PUBKEY = GetArg("-donation", ""); NOTARY_PUBKEY = GetArg("-pubkey", ""); HUSH_DEALERNODE = GetArg("-dealer",0); @@ -1813,7 +1807,7 @@ void hush_args(char *argv0) HUSH_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; - ASSETCHAINS_CC = GetArg("-ac_cc",2); + ASSETCHAINS_CC = GetArg("-ac_cc",0); HUSH_CCACTIVATE = GetArg("-ac_ccactivate",0); ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60); ASSETCHAINS_PUBLIC = 0; @@ -1908,6 +1902,20 @@ void hush_args(char *argv0) if(ishush3) { fprintf(stderr,"%s: Setting custom HUSH3 reward,halving,subsidy chain values...\n",__func__); + // Migrated from hushd script + ASSETCHAINS_CC = 2; + ASSETCHAINS_BLOCKTIME = 75; + ASSETCHAINS_LASTERA = 3; + ASSETCHAINS_COMMISSION = 11111111; + // 6250000 - (Sprout pool at block 500,000) + ASSETCHAINS_SUPPLY = 6178674; + ASSETCHAINS_FOUNDERS = 1; + // this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn + ASSETCHAINS_SCRIPTPUB = "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac"; + + Split("128,340000,5422111" , sizeof(ASSETCHAINS_ENDSUBSIDY)/sizeof(*ASSETCHAINS_ENDSUBSIDY), ASSETCHAINS_ENDSUBSIDY, 0); + Split("129,340000,840000", sizeof(ASSETCHAINS_HALVING)/sizeof(*ASSETCHAINS_HALVING), ASSETCHAINS_HALVING, 0); + Split("0,1125000000,562500000" , sizeof(ASSETCHAINS_REWARD)/sizeof(*ASSETCHAINS_REWARD), ASSETCHAINS_REWARD, 0); // Over-ride HUSH3 values from CLI params. Changing our blocktime to 75s changes things ASSETCHAINS_REWARD[0] = 0; ASSETCHAINS_REWARD[1] = 1125000000; @@ -1992,8 +2000,10 @@ void hush_args(char *argv0) if ( ASSETCHAINS_CC != 0 ) { uint8_t prevCCi = 0; - ASSETCHAINS_CCLIB = GetArg("-ac_cclib",""); - Split(GetArg("-ac_ccenable",""), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0); + ASSETCHAINS_CCLIB = GetArg("-ac_cclib","hush3"); + + // these are the enabled CCs on HUSH3 mainnet + Split(GetArg("-ac_ccenable","228,234,235,236,241"), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0); for (i=nonz=0; i<0x100; i++) { if ( ccenables[i] != prevCCi && ccenables[i] != 0 ) diff --git a/src/init.cpp b/src/init.cpp index 163df8a39..3e699a7cf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -412,7 +412,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-zindex", strprintf(_("Maintain extra statistics about shielded transactions and payments (default: %u)"), 0)); strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); - strUsage += HelpMessageOpt("-asmap=", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME)); + strUsage += HelpMessageOpt("-asmap=", strprintf("Specify ASN mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME)); strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400)); strUsage += HelpMessageOpt("-bind=", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6")); @@ -1092,8 +1092,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); } - // Read asmap file if configured - if (mapArgs.count("-asmap")) { + // Read asmap file by default for HUSH3 and all Hush Smart Chains + if (GetArg("-asmap",1)) { fs::path asmap_path = fs::path(GetArg("-asmap", "")); char cwd[1024]; @@ -1577,7 +1577,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt)); uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)); } - strSubVersion = FormatSubVersion(GetArg("-clientname","jl777sRemorse"), CLIENT_VERSION, uacomments); + strSubVersion = FormatSubVersion(GetArg("-clientname","GoldenSandrout"), CLIENT_VERSION, uacomments); if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.", strSubVersion.size(), MAX_SUBVERSION_LENGTH)); From 23369152d3fdbfe8c306c0ffc7b08dc6e753dac5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:06:34 -0400 Subject: [PATCH 020/115] . --- src/hush_utils.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 09c0e0e8a..ef6918ea3 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1763,7 +1763,7 @@ void hush_args(char *argv0) } DONATION_PUBKEY = GetArg("-donation", ""); NOTARY_PUBKEY = GetArg("-pubkey", ""); - HUSH_DEALERNODE = GetArg("-dealer",0); + HUSH_DEALERNODE = GetArg("-dealer",0); HUSH_TESTNODE = GetArg("-testnode",0); if ( strlen(NOTARY_PUBKEY.c_str()) == 66 ) @@ -1789,7 +1789,7 @@ void hush_args(char *argv0) } } - name = GetArg("-ac_name",""); + name = GetArg("-ac_name","HUSH3"); if ( argv0 != 0 ) { len = (int32_t)strlen(argv0); @@ -1810,6 +1810,7 @@ void hush_args(char *argv0) ASSETCHAINS_CC = GetArg("-ac_cc",0); HUSH_CCACTIVATE = GetArg("-ac_ccactivate",0); ASSETCHAINS_BLOCKTIME = GetArg("-ac_blocktime",60); + // We do not support ac_public=1 chains, Hush is a platform for privacy ASSETCHAINS_PUBLIC = 0; ASSETCHAINS_PRIVATE = GetArg("-ac_private",0); HUSH_SNAPSHOT_INTERVAL = GetArg("-ac_snapshot",0); From 13e16cc2ef9f1b2beb16f6cae3146335eff84795 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:11:29 -0400 Subject: [PATCH 021/115] Add default seed nodes --- src/hush_utils.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hush_utils.h b/src/hush_utils.h index ef6918ea3..3fe869432 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1804,6 +1804,10 @@ void hush_args(char *argv0) } } } + vector HUSH_nodes= {"node1.hush.is","node2.hush.is","node3.hush.is", + "node4.hush.is","node5.hush.is","node6.hush.is", + "node7.hush.is","node8.hush.is"}; + mapMultiArgs["-addnode"] = HUSH_nodes; HUSH_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; From 50ee752c3f6e0b076085c4c7152309a137507cb7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:15:47 -0400 Subject: [PATCH 022/115] hushd, hush-cli and hush-tx are real binaries now No more bash scripts or .bat files needed as wrappers! --- .gitignore | 8 ++++ configure.ac | 14 +++---- src/Makefile.am | 64 ++++++++++++++++---------------- src/hush-cli | 23 ------------ src/hush-tx | 11 ------ src/hushd | 99 ------------------------------------------------- 6 files changed, 47 insertions(+), 172 deletions(-) delete mode 100755 src/hush-cli delete mode 100755 src/hush-tx delete mode 100755 src/hushd diff --git a/.gitignore b/.gitignore index 03f81cc82..a3f474a14 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,14 @@ src/komodo-cli.exe src/komodod.exe src/komodo-tx.exe +src/hush-cli +src/hushd +src/hush-tx +src/hush-test +src/hush-cli.exe +src/hushd.exe +src/hush-tx.exe + #output during builds, symbol tables? *.dSYM diff --git a/configure.ac b/configure.ac index 35da30d2a..4f369aebd 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 8) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 1) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) @@ -14,9 +14,9 @@ AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) -BITCOIN_DAEMON_NAME=komodod -BITCOIN_CLI_NAME=komodo-cli -BITCOIN_TX_NAME=komodo-tx +BITCOIN_DAEMON_NAME=hushd +BITCOIN_CLI_NAME=hush-cli +BITCOIN_TX_NAME=hush-tx dnl Unless the user specified ARFLAGS, force it to be cr AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) @@ -231,7 +231,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" AC_ARG_WITH([utils], [AS_HELP_STRING([--with-utils], - [build komodo-cli komodo-tx wallet-utility (default=yes)])], + [build hush-cli hush-tx wallet-utility (default=yes)])], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) @@ -766,11 +766,11 @@ AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS - LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lwolfssl -lsodium $RUST_LIBS" -AC_MSG_CHECKING([whether to build komodod]) +AC_MSG_CHECKING([whether to build hushd]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) -AC_MSG_CHECKING([whether to build utils (komodo-cli komodo-tx wallet-utility)]) +AC_MSG_CHECKING([whether to build utils (hush-cli hush-tx wallet-utility)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) diff --git a/src/Makefile.am b/src/Makefile.am index 0711b52cc..027a0232e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -98,11 +98,11 @@ noinst_PROGRAMS = TESTS = #if BUILD_BITCOIND - bin_PROGRAMS += komodod + bin_PROGRAMS += hushd #endif if BUILD_BITCOIN_UTILS - bin_PROGRAMS += komodo-cli komodo-tx + bin_PROGRAMS += hush-cli hush-tx endif if ENABLE_WALLET bin_PROGRAMS += wallet-utility @@ -333,7 +333,7 @@ libbitcoin_zmq_a_SOURCES = \ zmq/zmqpublishnotifier.cpp endif -# wallet: komodod, but only linked when wallet enabled +# wallet: hushd, but only linked when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ @@ -481,17 +481,17 @@ libbitcoin_cli_a_SOURCES = \ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # -# komodod binary # -komodod_SOURCES = bitcoind.cpp -komodod_CPPFLAGS = -fPIC $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -komodod_CXXFLAGS = -fPIC $(AM_CXXFLAGS) $(PIE_FLAGS) -komodod_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# hushd binary # +hushd_SOURCES = bitcoind.cpp +hushd_CPPFLAGS = -fPIC $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +hushd_CXXFLAGS = -fPIC $(AM_CXXFLAGS) $(PIE_FLAGS) +hushd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS -komodod_SOURCES += bitcoind-res.rc +hushd_SOURCES += bitcoind-res.rc endif -komodod_LDADD = \ +hushd_LDADD = \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ @@ -506,10 +506,10 @@ komodod_LDADD = \ $(LIBCRYPTOCONDITIONS) if ENABLE_WALLET -komodod_LDADD += $(LIBBITCOIN_WALLET) +hushd_LDADD += $(LIBBITCOIN_WALLET) endif -komodod_LDADD += \ +hushd_LDADD += \ $(BOOST_LIBS) \ $(BDB_LIBS) \ $(SSL_LIBS) \ @@ -521,27 +521,27 @@ komodod_LDADD += \ $(LIBZCASH_LIBS) if TARGET_DARWIN -komodod_LDADD += libcc.dylib $(LIBSECP256K1) +hushd_LDADD += libcc.dylib $(LIBSECP256K1) endif if TARGET_WINDOWS -komodod_LDADD += libcc.dll $(LIBSECP256K1) +hushd_LDADD += libcc.dll $(LIBSECP256K1) endif if TARGET_LINUX -komodod_LDADD += libcc.so $(LIBSECP256K1) +hushd_LDADD += libcc.so $(LIBSECP256K1) endif # [+] Decker: use static linking for libstdc++.6.dylib, libgomp.1.dylib, libgcc_s.1.dylib if TARGET_DARWIN -komodod_LDFLAGS += -static-libgcc +hushd_LDFLAGS += -static-libgcc endif -# komodo-cli binary # -komodo_cli_SOURCES = bitcoin-cli.cpp -komodo_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) -komodo_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -komodo_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# hush-cli binary # +hush_cli_SOURCES = bitcoin-cli.cpp +hush_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +hush_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +hush_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_DARWIN -komodo_cli_LDFLAGS += -static-libgcc +hush_cli_LDFLAGS += -static-libgcc endif # wallet-utility binary # @@ -553,10 +553,10 @@ wallet_utility_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) endif if TARGET_WINDOWS -komodo_cli_SOURCES += bitcoin-cli-res.rc +hush_cli_SOURCES += bitcoin-cli-res.rc endif -komodo_cli_LDADD = \ +hush_cli_LDADD = \ $(LIBBITCOIN_CLI) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ @@ -584,17 +584,17 @@ wallet_utility_LDADD = \ $(LIBCRYPTOCONDITIONS) endif -# komodo-tx binary # -komodo_tx_SOURCES = komodo-tx.cpp -komodo_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -komodo_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -komodo_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +# hush-tx binary # +hush_tx_SOURCES = hush-tx.cpp +hush_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +hush_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +hush_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS -komodo_tx_SOURCES += bitcoin-tx-res.rc +hush_tx_SOURCES += bitcoin-tx-res.rc endif -komodo_tx_LDADD = \ +hush_tx_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ @@ -605,7 +605,7 @@ komodo_tx_LDADD = \ $(LIBZCASH_LIBS) \ $(LIBCRYPTOCONDITIONS) -komodo_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) +hush_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # Zcash Protocol Primitives libzcash_a_SOURCES = \ diff --git a/src/hush-cli b/src/hush-cli deleted file mode 100755 index ecd45bd74..000000000 --- a/src/hush-cli +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Copyright (c) 2016-2021 The Hush developers -# Released under the GPLv3 - -# set working directory to the location of this script -# readlink -f does not always exist -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $DIR -DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" -cd $DIR - -NAME=HUSH3 - -CLI=${KOMODOCLI:-./komodo-cli} -if [ -f $CLI ]; then - $CLI -ac_name=$NAME "$@" -else - # We prefix our binary when installed - # system wide on Debain systems, to prevent clashes, - # because we are classy like that. Fuck jl777, The KYC Traitor. - CLI=hush-komodo-cli - $CLI -ac_name=$NAME "$@" -fi diff --git a/src/hush-tx b/src/hush-tx deleted file mode 100755 index cbad82fc7..000000000 --- a/src/hush-tx +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Copyright (c) 2016-2021 The Hush developers -# Released under the GPLv3 - -# set working directory to the location of this script -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $DIR - -NAME=HUSHT - -./komodo-tx -ac_name=$NAME "$@" diff --git a/src/hushd b/src/hushd deleted file mode 100755 index 7aa99aeb0..000000000 --- a/src/hushd +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/bash -# Copyright (c) 2016-2021 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 - -# set working directory to the location of this script -# readlink -f does not always exist -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $DIR -DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" -cd $DIR - -# Chain parameters -NAME=HUSH3 - -# this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn -SCRIPT=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac - -# Hush was and will always be: -# The First Pure Sapling Zcash Protocol chain! -SAPLING=1 - -# We use 3 "eras" of different supply curves -ERAS=3 - -# These values are historical and over-ridden by internals! -# Do not change these values, change internals. -BLOCKTIME=150 # Hush goes to 75s blocktime at Block 340K -REWARD=0,1125000000,562500000 -HALVING=129,340000,840000 -PERC=11111111 -END=128,340000,5422111 - -# 6250000 - (Sprout pool at block 500,000) -SUPPLY=6178674 -FOUNDERS=1 -CLIENTNAME=GoldenSandtrout -NODE1=node1.hush.is -NODE2=node2.hush.is -NODE3=node3.hush.is -NODE4=node4.hush.is -NODE5=node5.hush.is -NODE6=node6.hush.is -NODE7=node7.hush.is -NODE8=node8.hush.is -CCLIB=hush3 - -# CryptoConditions/Custom Consensus params -# CCs will effectively be turned off at Block 340K -# since transparent outputs will not be allowed, except -# for mining and dpow. CCs can be used on Hush Smart -# Chains that do not define ac_private=1 -FAUCET=228 -HEIR=234 -CHANNEL=235 -ORACLE=236 -GATEWAY=241 -CCENABLE=$FAUCET,$HEIR,$CHANNEL,$ORACLE,$GATEWAY - -KMD=${KOMODOD:-./komodod} -if [ -f $KMD ]; then - HUSH="TheFuture" - # echo "Found binary: $KMD" -else - KMD=hush-komodod - if [ -f $KMD ]; then - echo "Found binary: $KMD" - else - echo "ERROR: Could not find Komodo binary!!!" - exit 1 - fi -fi - -# jl777 dishonored his village and so Duke The Elder journeys on -# with the True Extreme Privacy Cypherpunks -$KMD -ac_name=$NAME \ - -ac_sapling=$SAPLING \ - -ac_reward=$REWARD \ - -ac_halving=$HALVING \ - -ac_end=$END \ - -ac_eras=$ERAS \ - -ac_blocktime=$BLOCKTIME \ - -ac_cc=2 \ - -ac_ccenable=$CCENABLE \ - -ac_founders=$FOUNDERS \ - -ac_supply=$SUPPLY \ - -ac_perc=$PERC \ - -clientname=$CLIENTNAME \ - -asmap \ - -addnode=$NODE1 \ - -addnode=$NODE2 \ - -addnode=$NODE3 \ - -addnode=$NODE4 \ - -addnode=$NODE5 \ - -addnode=$NODE6 \ - -addnode=$NODE7 \ - -addnode=$NODE8 \ - -ac_cclib=$CCLIB \ - -ac_script=$SCRIPT "$@" From 1569b0974ca988885b4444221560f8598a000640 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:21:44 -0400 Subject: [PATCH 023/115] Remove unnecessary batch files and such --- src/hush-cli.bat | 14 -------------- src/hush-smart-chain | 18 ++++-------------- src/hush-tx.bat | 14 -------------- src/hushd.bat | 10 ---------- 4 files changed, 4 insertions(+), 52 deletions(-) delete mode 100644 src/hush-cli.bat delete mode 100644 src/hush-tx.bat delete mode 100644 src/hushd.bat diff --git a/src/hush-cli.bat b/src/hush-cli.bat deleted file mode 100644 index 802315b44..000000000 --- a/src/hush-cli.bat +++ /dev/null @@ -1,14 +0,0 @@ -@call :GET_CURRENT_DIR -@cd %THIS_DIR% -komodo-cli.exe -ac_name=HUSH3 %1 %2 %3 %4 %5 %6 %7 %8 %9 -@goto :EOF - -:GET_CURRENT_DIR -@pushd %~dp0 -@set THIS_DIR=%CD% -@popd -@goto :EOF - - - - diff --git a/src/hush-smart-chain b/src/hush-smart-chain index 537fdc9a3..c5543b221 100755 --- a/src/hush-smart-chain +++ b/src/hush-smart-chain @@ -7,18 +7,8 @@ cd $DIR DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" cd $DIR -NAME=HUSH3 -CLIENTNAME="GoldenSandtrout" -DEFAULTS="-ac_sapling=1 -clientname=$CLIENTNAME" +DEFAULTS="" -# This is a Hush-flavored KMD that allows us to pass in arbitary CLI -# flags, since hushd is specific to Hush mainnet -KMD=${KOMODOD:-./komodod} -if [ -f $KMD ]; then - $KMD $DEFAULTS "$@" -else - # We prefix our binary when installed - # system wide on Debain system, to prevent clashes - KMD=hush-komodod - $KMD $DEFAULTS "$@" -fi +# People should just use hushd going forward +HUSH="./hushd" +$HUSH $DEFAULTS "$@" diff --git a/src/hush-tx.bat b/src/hush-tx.bat deleted file mode 100644 index f3e24881d..000000000 --- a/src/hush-tx.bat +++ /dev/null @@ -1,14 +0,0 @@ -@call :GET_CURRENT_DIR -@cd %THIS_DIR% -komodo-tx.exe -ac_name=HUSH3 %1 %2 %3 %4 %5 %6 %7 %8 %9 -@goto :EOF - -:GET_CURRENT_DIR -@pushd %~dp0 -@set THIS_DIR=%CD% -@popd -@goto :EOF - - - - diff --git a/src/hushd.bat b/src/hushd.bat deleted file mode 100644 index 5f578d6b6..000000000 --- a/src/hushd.bat +++ /dev/null @@ -1,10 +0,0 @@ -@call :GET_CURRENT_DIR -@cd %THIS_DIR% -komodod.exe -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -asmap -addnode=node1.hush.is -addnode=node2.hush.is -addnode=node3.hush.is -addnode=node4.hush.is -addnode=node5.hush.is -addnode=node6.hush.is -addnode=node7.hush.is -addnode=node8.hush.is -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac -daemon %1 %2 %3 %4 %5 %6 %7 %8 %9 -@goto :EOF - -:GET_CURRENT_DIR -@pushd %~dp0 -@set THIS_DIR=%CD% -@popd -@goto :EOF From 821d5a9b61efc5da2debeb67ba4ba2625ebc6238 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:34:24 -0400 Subject: [PATCH 024/115] hush-tx --- src/{komodo-tx.cpp => hush-tx.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{komodo-tx.cpp => hush-tx.cpp} (100%) diff --git a/src/komodo-tx.cpp b/src/hush-tx.cpp similarity index 100% rename from src/komodo-tx.cpp rename to src/hush-tx.cpp From 5320e1521f1a40c66a96b2118027ddd68ca8bf34 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 19:40:56 -0400 Subject: [PATCH 025/115] Default HUSH3 and all HSC's to use sapling activation at height 1 --- src/hush_utils.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 3fe869432..8e501647b 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1915,6 +1915,7 @@ void hush_args(char *argv0) // 6250000 - (Sprout pool at block 500,000) ASSETCHAINS_SUPPLY = 6178674; ASSETCHAINS_FOUNDERS = 1; + ASSETCHAINS_SAPLING = 1; // this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn ASSETCHAINS_SCRIPTPUB = "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac"; @@ -2089,7 +2090,7 @@ void hush_args(char *argv0) } // HUSH will always be The First Pure Sapling Coin, no Sprout JoinSplits in our history! ;) - ASSETCHAINS_SAPLING = GetArg("-ac_sapling", -1); + ASSETCHAINS_SAPLING = GetArg("-ac_sapling", 1); if (ASSETCHAINS_SAPLING == -1) { ASSETCHAINS_OVERWINTER = GetArg("-ac_overwinter", -1); From 01e30ed2d980f0f53d68eaf05a8b11be631e792e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 20:55:55 -0400 Subject: [PATCH 026/115] order is important --- src/hush_utils.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 8e501647b..9281d284e 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1903,10 +1903,19 @@ void hush_args(char *argv0) Split(GetArg("-ac_halving",""), sizeof(ASSETCHAINS_HALVING)/sizeof(*ASSETCHAINS_HALVING), ASSETCHAINS_HALVING, 0); Split(GetArg("-ac_reward",""), sizeof(ASSETCHAINS_REWARD)/sizeof(*ASSETCHAINS_REWARD), ASSETCHAINS_REWARD, 0); + MAX_BLOCK_SIGOPS = 60000; + ASSETCHAINS_TXPOW = GetArg("-ac_txpow",0) & 3; + ASSETCHAINS_FOUNDERS = GetArg("-ac_founders",0);// & 1; + ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_founders_reward",0); + ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); + ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0); + ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey",""); + ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); + bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + fprintf(stderr,"%s: Setting custom %s reward HUSH3=%d reward,halving,subsidy chain values...\n",__func__, SMART_CHAIN_SYMBOL, ishush3); if(ishush3) { - fprintf(stderr,"%s: Setting custom HUSH3 reward,halving,subsidy chain values...\n",__func__); // Migrated from hushd script ASSETCHAINS_CC = 2; ASSETCHAINS_BLOCKTIME = 75; @@ -1918,7 +1927,6 @@ void hush_args(char *argv0) ASSETCHAINS_SAPLING = 1; // this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn ASSETCHAINS_SCRIPTPUB = "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac"; - Split("128,340000,5422111" , sizeof(ASSETCHAINS_ENDSUBSIDY)/sizeof(*ASSETCHAINS_ENDSUBSIDY), ASSETCHAINS_ENDSUBSIDY, 0); Split("129,340000,840000", sizeof(ASSETCHAINS_HALVING)/sizeof(*ASSETCHAINS_HALVING), ASSETCHAINS_HALVING, 0); Split("0,1125000000,562500000" , sizeof(ASSETCHAINS_REWARD)/sizeof(*ASSETCHAINS_REWARD), ASSETCHAINS_REWARD, 0); @@ -1952,11 +1960,6 @@ void hush_args(char *argv0) } } - MAX_BLOCK_SIGOPS = 60000; - ASSETCHAINS_TXPOW = GetArg("-ac_txpow",0) & 3; - ASSETCHAINS_FOUNDERS = GetArg("-ac_founders",0);// & 1; - ASSETCHAINS_FOUNDERS_REWARD = GetArg("-ac_founders_reward",0); - ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10); if ( ASSETCHAINS_SUPPLY > (uint64_t)90*1000*1000000 ) { fprintf(stderr,"-ac_supply must be less than 90 billion, derpz\n"); @@ -1965,9 +1968,6 @@ void hush_args(char *argv0) if(fDebug) fprintf(stderr,"ASSETCHAINS_SUPPLY %llu\n",(long long)ASSETCHAINS_SUPPLY); - ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0); - ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey",""); - ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); ASSETCHAINS_BEAMPORT = GetArg("-ac_beam",0); ASSETCHAINS_CODAPORT = GetArg("-ac_coda",0); ASSETCHAINS_CBOPRET = GetArg("-ac_cbopret",0); @@ -2330,6 +2330,9 @@ void hush_args(char *argv0) if ( GetArg("-port",0) != 0 ) { ASSETCHAINS_P2PPORT = GetArg("-port",0); + if(ishush3) { + ASSETCHAINS_P2PPORT = 18030; + } if(fDebug) fprintf(stderr,"set p2pport.%u\n",ASSETCHAINS_P2PPORT); } else ASSETCHAINS_P2PPORT = tmpport; From b57d902438f14011f8b8a314eadcacd01fd22b13 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 21:11:15 -0400 Subject: [PATCH 027/115] Set symbol earlier --- src/hush_utils.h | 3 ++- src/net.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 9281d284e..fb655bef5 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1912,6 +1912,8 @@ void hush_args(char *argv0) ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey",""); ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); + // Set our symobl from -ac_name value + strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; fprintf(stderr,"%s: Setting custom %s reward HUSH3=%d reward,halving,subsidy chain values...\n",__func__, SMART_CHAIN_SYMBOL, ishush3); @@ -2308,7 +2310,6 @@ void hush_args(char *argv0) if ( strlen(addn.c_str()) > 0 ) ASSETCHAINS_SEED = 1; - strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); MAX_MONEY = hush_max_money(); diff --git a/src/net.cpp b/src/net.cpp index d7833b4a0..def0145ab 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2283,7 +2283,7 @@ bool CAddrDB::Read(CAddrMan& addr) // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - return error("%s: Invalid network magic number", __func__); + return error("%s: Invalid network magic number in %s", __func__, pathAddr.string()); // de-serialize address data into one CAddrMan object ssPeers >> addr; From 0c5d2805b9a4260c6f4ef85737dee89fa2b3d68d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 21:35:11 -0400 Subject: [PATCH 028/115] . --- src/bitcoind.cpp | 3 --- src/chainparams.cpp | 8 ++++++-- src/hush_utils.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 91e4cef56..b9dd4723b 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -109,10 +109,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) } } -////////////////////////////////////////////////////////////////////////////// -// // Start -// extern int32_t IS_HUSH_NOTARY,USE_EXTERNAL_PUBKEY; extern uint32_t ASSETCHAIN_INIT; extern std::string NOTARY_PUBKEY; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 36ff0c26b..a26f8955c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -521,11 +521,15 @@ void hush_setactivation(int32_t height) void *chainparams_commandline() { CChainParams::CCheckpointData checkpointData; - if(fDebug) { + //if(fDebug) { fprintf(stderr,"chainparams_commandline called with port=%u\n", ASSETCHAINS_P2PPORT); - } + //} if ( SMART_CHAIN_SYMBOL[0] != 0 ) { + if (strcmp(SMART_CHAIN_SYMBOL,"HUSH3") == 0) { + ASSETCHAINS_P2PPORT = 18030; + } + if ( ASSETCHAINS_BLOCKTIME != 60 ) { pCurrentParams->consensus.nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; // 7 blocks diff --git a/src/hush_utils.h b/src/hush_utils.h index fb655bef5..61e83b0c1 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -2310,7 +2310,6 @@ void hush_args(char *argv0) if ( strlen(addn.c_str()) > 0 ) ASSETCHAINS_SEED = 1; - MAX_MONEY = hush_max_money(); if ( (baseid = hush_baseid(SMART_CHAIN_SYMBOL)) >= 0 && baseid < 32 ) @@ -2332,6 +2331,7 @@ void hush_args(char *argv0) { ASSETCHAINS_P2PPORT = GetArg("-port",0); if(ishush3) { + fprintf(stderr,"set HUSH3 p2pport.%u\n",ASSETCHAINS_P2PPORT); ASSETCHAINS_P2PPORT = 18030; } if(fDebug) From ba6e2aea014541d0aad9ff21fcaaa0a4de054dc7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 22:06:51 -0400 Subject: [PATCH 029/115] set ac_eras correctly --- src/hush_utils.h | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 61e83b0c1..711d1a3d3 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1490,13 +1490,9 @@ uint16_t hush_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extrap { if(fDebug) fprintf(stderr,"%s: extralen=%d\n",__func__,extralen); - if ( strcmp("SPECIAL",symbol) == 0 ) - { - *magicp = 0xdeadbeef; - return(6969); - } + *magicp = hush_smartmagic(symbol,supply,extraptr,extralen); - if(fDebug) + //if(fDebug) fprintf(stderr,"%s: extralen=%d, supply=%lu\n",__func__,extralen, supply); return(hush_smartport(*magicp,extralen)); @@ -1879,7 +1875,14 @@ void hush_args(char *argv0) printf("ASSETCHAINS_ALGO, %s not supported. using equihash\n", selectedAlgo.c_str()); } + // Set our symobl from -ac_name value + strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); + bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + ASSETCHAINS_LASTERA = GetArg("-ac_eras", 1); + if(ishush3) { + ASSETCHAINS_LASTERA = 3; + } if ( ASSETCHAINS_LASTERA < 1 || ASSETCHAINS_LASTERA > ASSETCHAINS_MAX_ERAS ) { ASSETCHAINS_LASTERA = 1; @@ -1912,16 +1915,12 @@ void hush_args(char *argv0) ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey",""); ASSETCHAINS_SCRIPTPUB = GetArg("-ac_script",""); - // Set our symobl from -ac_name value - strncpy(SMART_CHAIN_SYMBOL,name.c_str(),sizeof(SMART_CHAIN_SYMBOL)-1); - bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; fprintf(stderr,"%s: Setting custom %s reward HUSH3=%d reward,halving,subsidy chain values...\n",__func__, SMART_CHAIN_SYMBOL, ishush3); if(ishush3) { // Migrated from hushd script ASSETCHAINS_CC = 2; - ASSETCHAINS_BLOCKTIME = 75; - ASSETCHAINS_LASTERA = 3; + ASSETCHAINS_BLOCKTIME = 150; // this will change to 75 at the correct block ASSETCHAINS_COMMISSION = 11111111; // 6250000 - (Sprout pool at block 500,000) ASSETCHAINS_SUPPLY = 6178674; @@ -1929,9 +1928,7 @@ void hush_args(char *argv0) ASSETCHAINS_SAPLING = 1; // this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn ASSETCHAINS_SCRIPTPUB = "76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac"; - Split("128,340000,5422111" , sizeof(ASSETCHAINS_ENDSUBSIDY)/sizeof(*ASSETCHAINS_ENDSUBSIDY), ASSETCHAINS_ENDSUBSIDY, 0); - Split("129,340000,840000", sizeof(ASSETCHAINS_HALVING)/sizeof(*ASSETCHAINS_HALVING), ASSETCHAINS_HALVING, 0); - Split("0,1125000000,562500000" , sizeof(ASSETCHAINS_REWARD)/sizeof(*ASSETCHAINS_REWARD), ASSETCHAINS_REWARD, 0); + // Over-ride HUSH3 values from CLI params. Changing our blocktime to 75s changes things ASSETCHAINS_REWARD[0] = 0; ASSETCHAINS_REWARD[1] = 1125000000; From 644f4bf850a4163f3514b52c4812501d41255dd2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 11 Jul 2021 22:20:07 -0400 Subject: [PATCH 030/115] Deep nasal dragons, beware --- src/hush_utils.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 711d1a3d3..2ac1ef9bb 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1473,7 +1473,14 @@ uint32_t hush_smartmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t fprintf(stderr,"%02x",extraptr[i]); fprintf(stderr," extralen=%d crc0=%x\n",extralen,crc0); } - return(calc_crc32(crc0,buf,len)); + + //TODO: why is this needed? + bool ishush3 = strncmp(symbol, "HUSH3",5) == 0 ? true : false; + if(ishush3) { + return HUSH_MAGIC; + } else { + return(calc_crc32(crc0,buf,len)); + } } uint16_t hush_smartport(uint32_t magic,int32_t extralen) From 7764d05261fa1ca575a1a78c407095e35d54acfa Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 12 Jul 2021 01:49:04 -0400 Subject: [PATCH 031/115] . --- src/cc/dapps/dappstd.c | 8 ++--- src/cc/games/prices.c | 4 +-- src/cc/games/tetris.c | 2 +- src/cc/rogue/main.c | 10 +++--- src/hush.h | 20 +++--------- src/hush_bitcoind.h | 71 ++++++++++++------------------------------ src/hush_defs.h | 2 +- src/hush_events.h | 8 ++--- src/hush_gateway.h | 22 ++++++------- src/hush_globals.h | 6 ++-- src/hush_notary.h | 45 +++++++++----------------- src/hush_pax.h | 14 ++++----- src/txmempool.cpp | 14 --------- 13 files changed, 78 insertions(+), 148 deletions(-) diff --git a/src/cc/dapps/dappstd.c b/src/cc/dapps/dappstd.c index 98475c4f5..286aea5f6 100644 --- a/src/cc/dapps/dappstd.c +++ b/src/cc/dapps/dappstd.c @@ -669,7 +669,7 @@ uint16_t hush_userpass(char *userpass,char *symbol) #define is_cJSON_True(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_True) -char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) +char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port) { //static void *cHandle; char url[512],*retstr=0,*retstr2=0,postdata[8192]; @@ -691,7 +691,7 @@ int32_t games_sendrawtransaction(char *rawtx) char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1; params = (char *)malloc(strlen(rawtx) + 16); sprintf(params,"[\"%s\"]",rawtx); - if ( (retstr= komodo_issuemethod(USERPASS,(char *)"sendrawtransaction",params,GAMES_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,(char *)"sendrawtransaction",params,GAMES_PORT)) != 0 ) { if ( 0 ) // causes 4th level crash { @@ -768,7 +768,7 @@ int32_t games_progress(struct games_state *rs,int32_t waitflag,uint64_t seed,gam if ( fp == 0 ) fp = fopen("keystrokes.log","a"); sprintf(params,"[\"keystrokes\",\"17\",\"[%%22%s%%22,%%22%s%%22]\"]",Gametxidstr,hexstr); - if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( fp != 0 ) { @@ -978,7 +978,7 @@ int32_t games_setplayerdata(struct games_state *rs,char *gametxidstr) else { sprintf(params,"[\"gameinfo\",\"17\",\"[%%22%s%%22]\"]",gametxidstr); - filestr = komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT); + filestr = hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT); } if ( filestr != 0 ) { diff --git a/src/cc/games/prices.c b/src/cc/games/prices.c index f23a4ccea..dc046d667 100644 --- a/src/cc/games/prices.c +++ b/src/cc/games/prices.c @@ -206,7 +206,7 @@ int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eve sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); else if ( sizeof(c) == 8 ) sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -237,7 +237,7 @@ int32_t issue_bet(struct games_state *rs,int64_t x,int64_t betsize) x >>= 8; } sprintf(params,"[\"bet\",\"17\",\"[%.8f,%%22%s%%22]\"]",dstr(betsize),hexstr); - if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { diff --git a/src/cc/games/tetris.c b/src/cc/games/tetris.c index c0a3633f2..848e9aacc 100644 --- a/src/cc/games/tetris.c +++ b/src/cc/games/tetris.c @@ -822,7 +822,7 @@ int32_t issue_games_events(struct games_state *rs,char *gametxidstr,uint32_t eve sprintf(params,"[\"events\",\"17\",\"[%%22%08x%%22,%%22%s%%22,%u]\"]",(uint32_t)c&0xffffffff,gametxidstr,eventid); else if ( sizeof(c) == 8 ) sprintf(params,"[\"events\",\"17\",\"[%%22%016llx%%22,%%22%s%%22,%u]\"]",(long long)c,gametxidstr,eventid); - if ( (retstr= komodo_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,(char *)"cclib",params,GAMES_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index f6201df19..d738712d3 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -716,7 +716,7 @@ uint16_t hush_userpass(char *userpass,char *symbol) #define is_cJSON_True(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_True) -char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) +char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port) { //static void *cHandle; char url[512],*retstr=0,*retstr2=0,postdata[8192]; @@ -740,7 +740,7 @@ int32_t rogue_sendrawtransaction(char *rawtx) char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1; params = (char *)malloc(strlen(rawtx) + 16); sprintf(params,"[\"%s\"]",rawtx); - if ( (retstr= komodo_issuemethod(USERPASS,"sendrawtransaction",params,ROGUE_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,"sendrawtransaction",params,ROGUE_PORT)) != 0 ) { if ( 0 ) // causes 4th level crash { @@ -805,7 +805,7 @@ int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,cha if ( 0 && (pastkeys= rogue_keystrokesload(&numpastkeys,seed,1)) != 0 ) { sprintf(params,"[\"extract\",\"17\",\"[%%22%s%%22]\"]",Gametxidstr); - if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -847,7 +847,7 @@ int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,cha if ( fp == 0 ) fp = fopen("keystrokes.log","a"); sprintf(params,"[\"keystrokes\",\"17\",\"[%%22%s%%22,%%22%s%%22]\"]",Gametxidstr,hexstr); - if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 ) + if ( (retstr= hush_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 ) { if ( fp != 0 ) { @@ -905,7 +905,7 @@ int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr) else { sprintf(params,"[\"gameinfo\",\"17\",\"[%%22%s%%22]\"]",gametxidstr); - filestr = komodo_issuemethod(USERPASS,"cclib",params,ROGUE_PORT); + filestr = hush_issuemethod(USERPASS,"cclib",params,ROGUE_PORT); } if ( filestr != 0 ) { diff --git a/src/hush.h b/src/hush.h index 5ffdb5a71..f4a871947 100644 --- a/src/hush.h +++ b/src/hush.h @@ -510,7 +510,7 @@ void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotarie } } -int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) +int32_t hush_validate_chain(uint256 srchash,int32_t notarized_height) { static int32_t last_rewind; int32_t rewindtarget; CBlockIndex *pindex; struct hush_state *sp; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; if ( (sp= hush_stateptr(symbol,dest)) == 0 ) @@ -535,7 +535,7 @@ int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height) } else return(1); } -int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp) +int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp) { static uint256 zero; static FILE *signedfp; int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto555[33]; struct hush_state *sp; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; @@ -598,11 +598,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar matched = 0; if ( SMART_CHAIN_SYMBOL[0] == 0 ) { - if ( strcmp("KMD",(char *)&scriptbuf[len+32 * 2 + 4]) == 0 ) - matched = 1; - } - else - { + } else { if ( scriptbuf[len] == 'K' ) { //fprintf(stderr,"i.%d j.%d KV OPRET len.%d %.8f\n",i,j,opretlen,dstr(value)); @@ -631,7 +627,7 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar if ( matched != 0 ) len += dragon_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); if ( matched != 0 ) - validated = komodo_validate_chain(srchash,*notarizedheightp); + validated = hush_validate_chain(srchash,*notarizedheightp); else validated = 1; // Any notarization that is matched and has a decodable op_return is enough to pay notaries. Otherwise bugs! if ( fJustCheck && matched != 0 ) @@ -775,12 +771,6 @@ int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notar return(notaryid); } -/*int32_t komodo_isratify(int32_t isspecial,int32_t numvalid) -{ - if ( isspecial != 0 && numvalid >= HUSH_MINRATIFY ) - return(1); - else return(0); -}*/ // Special tx have vout[0] -> CRYPTO555 address // with more than HUSH_MINRATIFY pay2pubkey outputs -> ratify @@ -938,7 +928,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) { memcpy(scriptbuf,(uint8_t *)&block.vtx[i].vout[j].scriptPubKey[0],len); - notaryid = komodo_voutupdate(fJustCheck,&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,¬arizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime()); + notaryid = hush_voutupdate(fJustCheck,&isratification,notaryid,scriptbuf,len,height,txhash,i,j,&voutmask,&specialtx,¬arizedheight,(uint64_t)block.vtx[i].vout[j].nValue,notarized,signedmask,(uint32_t)chainActive.LastTip()->GetBlockTime()); if ( fJustCheck && notaryid == -2 ) { // We see a valid notarisation here, save its location. diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 26a3f8f74..b41d3b85a 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -25,8 +25,8 @@ #include "sietch.h" int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); -int32_t komodo_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp); +int32_t hush_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); +int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp); bool EnsureWalletIsAvailable(bool avoidException); extern bool fRequestShutdown; extern CScript HUSH_EARLYTXID_SCRIPTPUB; @@ -367,9 +367,8 @@ char *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char * return(chunk.memory); } -char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port) +char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port) { - //static void *cHandle; char url[512],*retstr=0,*retstr2=0,postdata[8192]; if ( params == 0 || params[0] == 0 ) params = (char *)"[]"; @@ -401,7 +400,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_hei } if ( userpass[0] != 0 ) { - if ( (jsonstr= komodo_issuemethod(userpass,(char *)"getinfo",params,port)) != 0 ) + if ( (jsonstr= hush_issuemethod(userpass,(char *)"getinfo",params,port)) != 0 ) { //printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) @@ -416,7 +415,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_hei free(jsonstr); } sprintf(params,"[\"%s\", 1]",txidstr); - if ( (jsonstr= komodo_issuemethod(userpass,(char *)"getrawtransaction",params,port)) != 0 ) + if ( (jsonstr= hush_issuemethod(userpass,(char *)"getrawtransaction",params,port)) != 0 ) { //printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) @@ -437,7 +436,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_hei return(txid_height); } -int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len,uint256 NOTARIZED_HASH) +int32_t hush_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len,uint256 NOTARIZED_HASH) { int32_t i; uint256 hash; char params[256]; for (i=0; i<32; i++) @@ -457,7 +456,7 @@ void hush_reconsiderblock(uint256 blockhash) { char params[256],*jsonstr,*hexstr; sprintf(params,"[\"%s\"]",blockhash.ToString().c_str()); - if ( (jsonstr= komodo_issuemethod(ASSETCHAINS_USERPASS,(char *)"reconsiderblock",params,ASSETCHAINS_RPCPORT)) != 0 ) + if ( (jsonstr= hush_issuemethod(ASSETCHAINS_USERPASS,(char *)"reconsiderblock",params,ASSETCHAINS_RPCPORT)) != 0 ) { //fprintf(stderr,"hush_reconsiderblock.(%s) (%s %u) -> (%s)\n",params,ASSETCHAINS_USERPASS,ASSETCHAINS_RPCPORT,jsonstr); free(jsonstr); @@ -475,34 +474,30 @@ int32_t hush_verifynotarization(char *symbol,char *dest,int32_t height,int32_t N sprintf(¶ms[i*2 + 2],"%02x",((uint8_t *)&NOTARIZED_DESTTXID)[31-i]); strcat(params,"\", 1]");*/ sprintf(params,"[\"%s\", 1]",NOTARIZED_DESTTXID.ToString().c_str()); - if ( strcmp(symbol,SMART_CHAIN_SYMBOL[0]==0?(char *)"KMD":SMART_CHAIN_SYMBOL) != 0 ) + if ( strcmp(symbol,SMART_CHAIN_SYMBOL[0]==0?(char *)"HUSH3":SMART_CHAIN_SYMBOL) != 0 ) return(0); if ( 0 && SMART_CHAIN_SYMBOL[0] != 0 ) printf("[%s] src.%s dest.%s params.[%s] ht.%d notarized.%d\n",SMART_CHAIN_SYMBOL,symbol,dest,params,height,NOTARIZED_HEIGHT); - if ( strcmp(dest,"KMD") == 0 ) + if ( strcmp(dest,"HUSH3") == 0 ) { if ( HUSHUSERPASS[0] != 0 ) { if ( SMART_CHAIN_SYMBOL[0] != 0 ) { - jsonstr = komodo_issuemethod(HUSHUSERPASS,(char *)"getrawtransaction",params,HUSH3_PORT); + jsonstr = hush_issuemethod(HUSHUSERPASS,(char *)"getrawtransaction",params,HUSH3_PORT); //printf("userpass.(%s) got (%s)\n",HUSHUSERPASS,jsonstr); } }//else jsonstr = _dex_getrawtransaction(); else return(0); // need universal way to issue DEX* API, since notaries mine most blocks, this ok - } - else if ( strcmp(dest,"BTC") == 0 ) - { + } else if ( strcmp(dest,"BTC") == 0 ) { if ( BTCUSERPASS[0] != 0 ) { //printf("BTCUSERPASS.(%s)\n",BTCUSERPASS); - jsonstr = komodo_issuemethod(BTCUSERPASS,(char *)"getrawtransaction",params,8332); + jsonstr = hush_issuemethod(BTCUSERPASS,(char *)"getrawtransaction",params,8332); } //else jsonstr = _dex_getrawtransaction(); else return(0); - } - else - { + } else { printf("[%s] verifynotarization error unexpected dest.(%s)\n",SMART_CHAIN_SYMBOL,dest); return(-1); } @@ -532,7 +527,7 @@ int32_t hush_verifynotarization(char *symbol,char *dest,int32_t height,int32_t N script += 2; len -= 2; } - retval = komodo_verifynotarizedscript(height,script,len,NOTARIZED_HASH); + retval = hush_verifynotarizedscript(height,script,len,NOTARIZED_HASH); } } } @@ -560,7 +555,7 @@ CScript hush_makeopret(CBlock *pblock, bool fNew) uint256 hash; char params[128],*hexstr,*jsonstr; cJSON *result; int32_t i; uint8_t revbuf[32]; memset(&hash,0,sizeof(hash)); sprintf(params,"[%d]",height); - if ( (jsonstr= komodo_issuemethod(HUSHUSERPASS,(char *)"getblockhash",params,BITCOIND_RPCPORT)) != 0 ) + if ( (jsonstr= hush_issuemethod(HUSHUSERPASS,(char *)"getblockhash",params,BITCOIND_RPCPORT)) != 0 ) { if ( (result= cJSON_Parse(jsonstr)) != 0 ) { @@ -613,7 +608,7 @@ uint64_t komodo_seed(int32_t height) return(seed); } -uint32_t komodo_txtime(CScript &opret,uint64_t *valuep,uint256 hash, int32_t n, char *destaddr) +uint32_t hush_txtime(CScript &opret,uint64_t *valuep,uint256 hash, int32_t n, char *destaddr) { CTxDestination address; CTransaction tx; uint256 hashBlock; int32_t numvouts; *valuep = 0; @@ -644,32 +639,6 @@ CBlockIndex *hush_getblockindex(uint256 hash) return((it != mapBlockIndex.end()) ? it->second : NULL); } -uint32_t komodo_txtime2(uint64_t *valuep,uint256 hash,int32_t n,char *destaddr) -{ - CTxDestination address; CBlockIndex *pindex; CTransaction tx; uint256 hashBlock; uint32_t txtime = 0; - *valuep = 0; - if (!GetTransaction(hash, tx, -#ifndef HUSH_ZCASH - Params().GetConsensus(), -#endif - hashBlock, true)) - { - //fprintf(stderr,"ERROR: %s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime); - return(0); - } - if ( (pindex= hush_getblockindex(hashBlock)) != 0 ) - txtime = pindex->nTime; - else txtime = tx.nLockTime; - //fprintf(stderr,"%s/v%d locktime.%u\n",hash.ToString().c_str(),n,(uint32_t)tx.nLockTime); - if ( n < tx.vout.size() ) - { - *valuep = tx.vout[n].nValue; - if (ExtractDestination(tx.vout[n].scriptPubKey, address)) - strcpy(destaddr,CBitcoinAddress(address).ToString().c_str()); - } - return(txtime); -} - bool hush_checkopret(CBlock *pblock, CScript &merkleroot) { merkleroot = pblock->vtx.back().vout.back().scriptPubKey; @@ -913,7 +882,7 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) } } fprintf(stderr,"komodo_minerid height.%d null pindex\n",height); - return(komodo_electednotary(&numnotaries,pubkey33,height,timestamp)); + return(hush_electednotary(&numnotaries,pubkey33,height,timestamp)); }*/ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height) @@ -1029,7 +998,7 @@ int32_t hush_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash) int32_t notarized_height,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; CBlockIndex *notary,*pindex; if ( (pindex= chainActive.LastTip()) == 0 ) return(-1); - notarized_height = komodo_notarizeddata(pindex->GetHeight(),¬arized_hash,¬arized_desttxid); + notarized_height = hush_notarizeddata(pindex->GetHeight(),¬arized_hash,¬arized_desttxid); *notarized_heightp = notarized_height; BlockMap::const_iterator it; if ( notarized_height >= 0 && notarized_height <= pindex->GetHeight() && (it = mapBlockIndex.find(notarized_hash)) != mapBlockIndex.end() && (notary = it->second) != NULL ) @@ -1282,7 +1251,7 @@ int8_t hush_segid(int32_t nocache,int32_t height) { txid = block.vtx[txn_count-1].vin[0].prevout.hash; vout = block.vtx[txn_count-1].vin[0].prevout.n; - txtime = komodo_txtime(opret,&value,txid,vout,destaddr); + txtime = hush_txtime(opret,&value,txid,vout,destaddr); if ( ExtractDestination(block.vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) ) { strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str()); @@ -1493,7 +1462,7 @@ int32_t hush_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *scri if ( len >= sizeof(uint32_t) && len <= sizeof(scriptbuf) ) { memcpy(scriptbuf,script,len); - if ( komodo_voutupdate(true,&isratification,0,scriptbuf,len,height,uint256(),1,1,&voutmask,&specialtx,¬arizedheight,0,1,0,timestamp) != -2 ) + if ( hush_voutupdate(true,&isratification,0,scriptbuf,len,height,uint256(),1,1,&voutmask,&specialtx,¬arizedheight,0,1,0,timestamp) != -2 ) { fprintf(stderr, "<<<<<len = len; ep->height = height; @@ -35,7 +35,7 @@ struct hush_event *hush_eventadd(struct hush_state *sp,int32_t height,char *symb memcpy(ep->space,data,datalen); sp->Hush_events = (struct hush_event **)realloc(sp->Hush_events,(1 + sp->Hush_numeventss) * sizeof(*sp->Hush_events)); sp->Hush_events[sp->Hush_numeventss++] = ep; - portable_mutex_unlock(&komodo_mutex); + portable_mutex_unlock(&hush_mutex); } return(ep); } @@ -62,7 +62,7 @@ void hush_eventadd_notarized(struct hush_state *sp,char *symbol,int32_t height,c strncpy(N.dest,dest,sizeof(N.dest)-1); hush_eventadd(sp,height,symbol,HUSH_EVENT_NOTARIZED,(uint8_t *)&N,sizeof(N)); if ( sp != 0 ) - komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid,MoM,MoMdepth); + hush_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid,MoM,MoMdepth); } } @@ -75,7 +75,7 @@ void hush_eventadd_pubkeys(struct hush_state *sp,char *symbol,int32_t height,uin memcpy(P.pubkeys,pubkeys,33 * num); hush_eventadd(sp,height,symbol,HUSH_EVENT_RATIFY,(uint8_t *)&P,(int32_t)(sizeof(P.num) + 33 * num)); if ( sp != 0 ) - komodo_notarysinit(height,pubkeys,num); + hush_notarysinit(height,pubkeys,num); } void hush_eventadd_pricefeed(struct hush_state *sp,char *symbol,int32_t height,uint32_t *prices,uint8_t num) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 764c59aaf..8b28c9b8c 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -65,10 +65,10 @@ void pax_keyset(uint8_t *buf,uint256 txid,uint16_t vout,uint8_t type) struct pax_transaction *komodo_paxfind(uint256 txid,uint16_t vout,uint8_t type) { struct pax_transaction *pax; uint8_t buf[35]; - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); pax_keyset(buf,txid,vout,type); HASH_FIND(hh,PAX,buf,sizeof(buf),pax); - pthread_mutex_unlock(&komodo_mutex); + pthread_mutex_unlock(&hush_mutex); return(pax); } @@ -84,7 +84,7 @@ struct pax_transaction *komodo_paxfinds(uint256 txid,uint16_t vout) struct pax_transaction *komodo_paxmark(int32_t height,uint256 txid,uint16_t vout,uint8_t type,int32_t mark) { struct pax_transaction *pax; uint8_t buf[35]; - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); pax_keyset(buf,txid,vout,type); HASH_FIND(hh,PAX,buf,sizeof(buf),pax); if ( pax == 0 ) @@ -104,16 +104,16 @@ struct pax_transaction *komodo_paxmark(int32_t height,uint256 txid,uint16_t vout // printf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->komodoshis),dstr(pax->fiatoshis)); } - pthread_mutex_unlock(&komodo_mutex); + pthread_mutex_unlock(&hush_mutex); return(pax); } void komodo_paxdelete(struct pax_transaction *pax) { return; // breaks when out of order - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); HASH_DELETE(hh,PAX,pax); - pthread_mutex_unlock(&komodo_mutex); + pthread_mutex_unlock(&hush_mutex); } void komodo_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 @@ -124,7 +124,7 @@ void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t //if ( strcmp(symbol,SMART_CHAIN_SYMBOL) != 0 ) // return; sp = hush_stateptr(str,dest); - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); pax_keyset(buf,txid,vout,type); HASH_FIND(hh,PAX,buf,sizeof(buf),pax); if ( pax == 0 ) @@ -143,7 +143,7 @@ void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t 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(&komodo_mutex); + pthread_mutex_unlock(&hush_mutex); if ( coinaddr != 0 ) { strcpy(pax->coinaddr,coinaddr); @@ -791,12 +791,12 @@ int32_t hush_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime) else if ( height > 814000 ) { script = (uint8_t *)&block.vtx[0].vout[0].scriptPubKey[0]; - //int32_t notary = komodo_electednotary(&num,script+1,height,0); - //if ( (-1 * (komodo_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)) < 0 ) + //int32_t notary = hush_electednotary(&num,script+1,height,0); + //if ( (-1 * (hush_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)) < 0 ) // fprintf(stderr, ">>>>>>> FAILED BLOCK.%d notary.%d insync.%d\n",height,notary,HUSH_INSYNC); //else // fprintf(stderr, "<<<<<<< VALID BLOCK.%d notary.%d insync.%d\n",height,notary,HUSH_INSYNC); - return(-1 * (komodo_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)); + return(-1 * (hush_electednotary(&num,script+1,height,0) >= 0) * (height > 1000000)); } } else diff --git a/src/hush_globals.h b/src/hush_globals.h index 0da48075a..295f848b1 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -22,8 +22,8 @@ uint32_t hush_heightstamp(int32_t height); void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void hush_init(int32_t height); int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); -int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); -char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port); +int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); +char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port); void hush_init(int32_t height); int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_isrealtime(int32_t *kmdheightp); @@ -32,7 +32,7 @@ int32_t hush_longestchain(); uint64_t komodo_maxallowed(int32_t baseid); int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); int32_t hush_checkvout(int32_t vout,int32_t k,int32_t indallvouts); -pthread_mutex_t komodo_mutex,staked_mutex; +pthread_mutex_t hush_mutex; #define KOMODO_ELECTION_GAP 2000 //((SMART_CHAIN_SYMBOL[0] == 0) ? 2000 : 100) #define HUSH_SMART_CHAIN_MAXLEN 65 diff --git a/src/hush_notary.h b/src/hush_notary.h index b94959766..311ed782e 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -120,7 +120,7 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) return(-1); } -int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp) +int32_t hush_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp) { int32_t i,n; uint8_t pubkeys[64][33]; n = hush_notaries(pubkeys,height,timestamp); @@ -133,22 +133,7 @@ int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t hei return(-1); } -int32_t komodo_ratify_threshold(int32_t height,uint64_t signedmask) -{ - int32_t htind,numnotaries,i,wt = 0; - htind = height / KOMODO_ELECTION_GAP; - if ( htind >= HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - numnotaries = Pubkeys[htind].numnotaries; - for (i=0; i (numnotaries >> 1) || (wt > 7 && (signedmask & 1) != 0) ) - return(1); - else return(0); -} - -void komodo_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) +void hush_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) { static int32_t hwmheight; int32_t k,i,htind,height; struct knotary_entry *kp; struct knotaries_entry N; @@ -165,7 +150,7 @@ void komodo_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; //printf("htind.%d activation %d from %d vs %d | hwmheight.%d %s\n",htind,height,origheight,(((origheight+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,hwmheight,SMART_CHAIN_SYMBOL); } else htind = 0; - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); for (k=0; k hwmheight ) hwmheight = origheight; } @@ -207,7 +192,7 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui } if ( height >= HUSH_NOTARIES_HARDCODED || SMART_CHAIN_SYMBOL[0] != 0 ) { - if ( (*notaryidp= komodo_electednotary(&numnotaries,pubkey33,height,timestamp)) >= 0 && numnotaries != 0 ) + if ( (*notaryidp= hush_electednotary(&numnotaries,pubkey33,height,timestamp)) >= 0 && numnotaries != 0 ) { modval = ((height % numnotaries) == *notaryidp); return(modval); @@ -220,9 +205,9 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui htind = height / KOMODO_ELECTION_GAP; if ( htind >= HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP ) htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - pthread_mutex_lock(&komodo_mutex); + pthread_mutex_lock(&hush_mutex); HASH_FIND(hh,Pubkeys[htind].Notaries,pubkey33,33,kp); - pthread_mutex_unlock(&komodo_mutex); + pthread_mutex_unlock(&hush_mutex); if ( kp != 0 ) { if ( (numnotaries= Pubkeys[htind].numnotaries) > 0 ) @@ -355,7 +340,7 @@ int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int3 return(0); } -int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp) +int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp) { struct notarized_checkpoint *np = 0; int32_t i=0,flag = 0; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; struct hush_state *sp; if ( (sp= hush_stateptr(symbol,dest)) != 0 ) @@ -411,17 +396,17 @@ int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *n return(0); } -void komodo_notarized_update(struct hush_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid,uint256 MoM,int32_t MoMdepth) +void hush_notarized_update(struct hush_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid,uint256 MoM,int32_t MoMdepth) { struct notarized_checkpoint *np; if ( notarized_height >= nHeight ) { - fprintf(stderr,"komodo_notarized_update REJECT notarized_height %d > %d nHeight\n",notarized_height,nHeight); + fprintf(stderr,"hush_notarized_update REJECT notarized_height %d > %d nHeight\n",notarized_height,nHeight); return; } if ( 0 && SMART_CHAIN_SYMBOL[0] != 0 ) - fprintf(stderr,"[%s] komodo_notarized_update nHeight.%d notarized_height.%d\n",SMART_CHAIN_SYMBOL,nHeight,notarized_height); - portable_mutex_lock(&komodo_mutex); + fprintf(stderr,"[%s] hush_notarized_update nHeight.%d notarized_height.%d\n",SMART_CHAIN_SYMBOL,nHeight,notarized_height); + portable_mutex_lock(&hush_mutex); sp->NPOINTS = (struct notarized_checkpoint *)realloc(sp->NPOINTS,(sp->NUM_NPOINTS+1) * sizeof(*sp->NPOINTS)); np = &sp->NPOINTS[sp->NUM_NPOINTS++]; memset(np,0,sizeof(*np)); @@ -431,7 +416,7 @@ void komodo_notarized_update(struct hush_state *sp,int32_t nHeight,int32_t notar sp->NOTARIZED_DESTTXID = np->notarized_desttxid = notarized_desttxid; sp->MoM = np->MoM = MoM; sp->MoMdepth = np->MoMdepth = MoMdepth; - portable_mutex_unlock(&komodo_mutex); + portable_mutex_unlock(&hush_mutex); } void hush_init(int32_t height) @@ -442,7 +427,7 @@ void hush_init(int32_t height) memset(&zero,0,sizeof(zero)); if ( didinit == 0 ) { - pthread_mutex_init(&komodo_mutex,NULL); + pthread_mutex_init(&hush_mutex,NULL); decode_hex(NOTARY_PUBKEY33,33,(char *)NOTARY_PUBKEY.c_str()); if ( height >= 0 ) { @@ -453,7 +438,7 @@ void hush_init(int32_t height) break; decode_hex(pubkeys[k],33,(char *)Notaries_genesis[k][1]); } - komodo_notarysinit(0,pubkeys,k); + hush_notarysinit(0,pubkeys,k); } //for (i=0; i= 0 && (relid= hush_baseid(rel)) >= 0 ) { - //portable_mutex_lock(&komodo_mutex); + //portable_mutex_lock(&hush_mutex); for (i=NUM_PRICES-1; i>=0; i--) { ptr = &PVALS[36 * i]; @@ -516,13 +516,13 @@ uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,cha *kmdbtcp = pvals[MAX_CURRENCIES] / 539; *btcusdp = pvals[MAX_CURRENCIES + 1] / 539; } - //portable_mutex_unlock(&komodo_mutex); + //portable_mutex_unlock(&hush_mutex); if ( kmdbtc != 0 && btcusd != 0 ) return(komodo_paxcalc(height,pvals,baseid,relid,basevolume,kmdbtc,btcusd)); else return(0); } } - //portable_mutex_unlock(&komodo_mutex); + //portable_mutex_unlock(&hush_mutex); } //else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid); return(0); } @@ -651,7 +651,7 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin return(0); } *seedp = komodo_seed(height); - portable_mutex_lock(&komodo_mutex); + portable_mutex_lock(&hush_mutex); for (i=0; i<17; i++) { if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 ) @@ -682,7 +682,7 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin if ( height < 165000 || height > 236000 ) break; } - portable_mutex_unlock(&komodo_mutex); + portable_mutex_unlock(&hush_mutex); if ( nonz != 0 ) sum /= nonz; //printf("-> %lld %s/%s i.%d ht.%d\n",(long long)sum,base,rel,i,height); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index b780d15d6..4c30fdfcb 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -487,21 +487,7 @@ std::vector CTxMemPool::removeExpired(unsigned int nBlockHeight) // Remove expired txs from the mempool LOCK(cs); list transactionsToRemove; - for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) - { - const CTransaction& tx = it->GetTx(); - tipindex = chainActive.LastTip(); - /* - bool fInterestNotValidated = SMART_CHAIN_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(tx,tipindex->GetHeight()+1,tipindex->GetMedianTimePast() + 777,0) < 0; - if (IsExpiredTx(tx, nBlockHeight) || fInterestNotValidated) - { - if (fInterestNotValidated && tipindex != 0) - LogPrintf("Removing interest violate txid.%s nHeight.%d nTime.%u vs locktime.%u\n",tx.GetHash().ToString(),tipindex->GetHeight()+1,tipindex->GetMedianTimePast() + 777,tx.nLockTime); - transactionsToRemove.push_back(tx); - } - */ - } std::vector ids; for (const CTransaction& tx : transactionsToRemove) { list removed; From f90afcc15b4bd96dc53e9b4adcd51d7e90fafcf0 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 12 Jul 2021 18:20:02 -0400 Subject: [PATCH 032/115] stratum doesn't appear, so trying to add stratumRPCCommands as seen elsewhere --- src/rpc/register.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rpc/register.h b/src/rpc/register.h index 2493e447b..8d0f8b6aa 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -37,6 +37,8 @@ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); /** Register test transaction RPC commands */ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); +/** Register stratum RPC commands */ +void RegisterStratumRPCCommands(CRPCTable &tableRPC); static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) @@ -49,6 +51,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) #ifdef TESTMODE RegisterTesttransactionsRPCCommands(tableRPC); #endif + RegisterStratumRPCCommands(tableRPC); } #endif From bfa19ab292ac81a17ddce03e28a5b93b64c2a131 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 18 Jul 2021 18:30:27 -0400 Subject: [PATCH 033/115] cc updates --- src/cc/musig.cpp | 28 ++++++++++++++-------------- src/cc/rogue/main.c | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/cc/musig.cpp b/src/cc/musig.cpp index 4019f2962..363cca280 100644 --- a/src/cc/musig.cpp +++ b/src/cc/musig.cpp @@ -18,7 +18,7 @@ /* first make a combined pk: -./komodo-cli -ac_name=MUSIG cclib combine 18 '["02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28","0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4"]' +./hush-cli -ac_name=MUSIG cclib combine 18 '["02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28","0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4"]' { "pkhash": "5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b", "combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b", @@ -28,7 +28,7 @@ the combined_pk and pkhash will be needed for various other rpc calls second, send 1 coin to the combined_pk - ./komodo-cli -ac_name=MUSIG cclib send 18 '["03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",1]' + ./hush-cli -ac_name=MUSIG cclib send 18 '["03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b",1]' { "hex": "0400008085202f8901a980664dffc810725a79ffb89ac48be4c7b6bade9b789732fcf871acf8e81a2e010000006a47304402207e52763661ecd2c34a65d6623950be11794825db71576dc11894c606ddc317800220028fef46dc20630d0fdf22647b5d4ff0f1c47cf75f48702d0a91d5589eff99d001210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ffffffff031008f60500000000302ea22c8020c71ddb3aac7f9b9e4bdacf032aaa8b8e4433c4ff9f8a43cebb9c1f5da96928a48103120c008203000401cce09aa4350000000023210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac0000000000000000266a2412782103f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b00000000920500000000000000000000000000", "txid": "5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c", @@ -36,7 +36,7 @@ } sendrawtransaction of the above hex. - ./komodo-cli -ac_name=MUSIG getrawtransaction 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c 1 + ./hush-cli -ac_name=MUSIG getrawtransaction 5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c 1 "vout": [ { "value": 1.00010000, @@ -72,7 +72,7 @@ get the msg we need to sign: - ./komodo-cli -ac_name=MUSIG cclib calcmsg 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac"]' + ./hush-cli -ac_name=MUSIG cclib calcmsg 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac"]' { "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", @@ -85,7 +85,7 @@ the "msg" is what needs to be signed to create a valid spend 5 args: ind, numsigners, combined_pk, pkhash, message to be signed on node with pubkey: 02fb6aa0b96cad24d46b5da93eba3864c45ce07a73bba12da530ae841e140fcf28 - ./komodo-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' + ./hush-cli -ac_name=MUSIG cclib session 18 '[0,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' { "myind": 0, "numsigners": 2, @@ -94,7 +94,7 @@ the "msg" is what needs to be signed to create a valid spend } on node with pubkey: 0255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4 - ./komodo-cli -ac_name=MUSIG cclib session 18 '[1,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' + ./hush-cli -ac_name=MUSIG cclib session 18 '[1,2,"03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75"]' { "myind": 1, "numsigners": 2, @@ -103,7 +103,7 @@ the "msg" is what needs to be signed to create a valid spend } now we need to get the commitment from each node to the other one. the session already put the commitment for each node into the global struct. Keep in mind there is a single global struct with session unique to each cclib session call. that means no restarting any deamon in the middle of the process on any of the nodes and only call cclib session a single time. this is an artificial restriction just to simplify the initial implementation of musig - ./komodo-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851"]' + ./hush-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","c2291acb747a75b1a40014d8eb0cc90a1360f74d413f65f78e20a7de45eda851"]' { "added_index": 1, "myind": 0, @@ -111,7 +111,7 @@ the "msg" is what needs to be signed to create a valid spend "result": "success" } - ./komodo-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"d242cff13fa8c9b83248e4219fda459ada146b885f2171481f1b0f66c66d94ad"]' + ./hush-cli -ac_name=MUSIG cclib commit 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"d242cff13fa8c9b83248e4219fda459ada146b885f2171481f1b0f66c66d94ad"]' { "added_index": 0, "myind": 1, @@ -120,7 +120,7 @@ the "msg" is what needs to be signed to create a valid spend } Now exchange the revealed nonces to each node: - ./komodo-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c"]' + ./hush-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","039365deaaaea089d509ba4c9f846de2baf4aa04cf6b26fa2c1cd818553e47f80c"]' { "added_index": 1, "myind": 0, @@ -128,7 +128,7 @@ the "msg" is what needs to be signed to create a valid spend "result": "success" } -./komodo-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b"]' +./hush-cli -ac_name=MUSIG cclib nonce 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"02fec7a9310c959a0a97b86bc3f8c30d392d1fb51793915898c568f73f1f70476b"]' { "added_index": 0, "myind": 1, @@ -137,14 +137,14 @@ the "msg" is what needs to be signed to create a valid spend } Almost there! final step is to exchange the partial sigs between signers - ./komodo-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e"]' + ./hush-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b","1","4a3795e6801b355102c617390cf5a462061e082e35dc2ed8f8b1fab54cc0769e"]' { "added_index": 1, "result": "success", "combinedsig": "a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9" } - ./komodo-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b"]' + ./hush-cli -ac_name=MUSIG cclib partialsig 18 '["5cb5a225064ca6ffc1438cb2a6ac2ac65fe2d5055dc7f6c7ebffb9a231f8912b",0,"1d65c09cd9bffe4f0604227e66cd7cd221480bbb08262fe885563a9df7cf8f5b"]' { "added_index": 0, "result": "success", @@ -155,7 +155,7 @@ the "msg" is what needs to be signed to create a valid spend Now for a sanity test, we can use the verify call to make sure this sig will work with the msg needed for the spend: - ./komodo-cli -ac_name=MUSIG cclib verify 18 '["f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75","03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' + ./hush-cli -ac_name=MUSIG cclib verify 18 '["f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75","03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' { "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", "combined_pk": "03f016c348437c7422eed92d865aa9789614f75327cada463eefc566126b54785b", @@ -165,7 +165,7 @@ the "msg" is what needs to be signed to create a valid spend and finally the spend: sendtxid, scriptPubKey, musig - ./komodo-cli -ac_name=MUSIG cclib spend 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' + ./hush-cli -ac_name=MUSIG cclib spend 18 '["5ce74037a153ee210413b48d4e88638b99825a2de1a1f1aa0d36ebf93019824c","210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac","a76f2790747ed2436a281f2660bdbee21bad9ee130b9cab6e542fa618fba1512679d568359db33a008ca39b773c32134276613e93e025ec17e083553449005f9"]' { "scriptpubkey": "210255c46dbce584e3751081b39d7fc054fc807100557e73fc444481618b5706afb4ac", "msg": "f7fb85d1412814e3c2f98b990802af6ee33dad368c6ba05c2050e9e5506fcd75", diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index d738712d3..e627f751f 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -837,7 +837,7 @@ int32_t rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,cha hexstr[i<<1] = 0; if ( 0 ) { - sprintf(cmd,"./komodo-cli -ac_name=ROGUE cclib keystrokes 17 \\\"[%%22%s%%22,%%22%s%%22]\\\" >> keystrokes.log",Gametxidstr,hexstr); + sprintf(cmd,"./hush-cli -ac_name=ROGUE cclib keystrokes 17 \\\"[%%22%s%%22,%%22%s%%22]\\\" >> keystrokes.log",Gametxidstr,hexstr); if ( system(cmd) != 0 ) fprintf(stderr,"error issuing (%s)\n",cmd); } @@ -897,7 +897,7 @@ int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr) if ( 0 ) { sprintf(fname,"%s.gameinfo",gametxidstr); - sprintf(cmd,"./komodo-cli -ac_name=ROGUE cclib gameinfo 17 \\\"[%%22%s%%22]\\\" > %s",gametxidstr,fname); + sprintf(cmd,"./hush-cli -ac_name=ROGUE cclib gameinfo 17 \\\"[%%22%s%%22]\\\" > %s",gametxidstr,fname); if ( system(cmd) != 0 ) fprintf(stderr,"error issuing (%s)\n",cmd); else filestr = (char *)OS_fileptr(&allocsize,fname); @@ -1029,7 +1029,7 @@ int main(int argc, char **argv, char **envp) fclose(fp); if ( ROGUE_PORT == 0 ) { - printf("you must copy ROGUE.conf from ~/.komodo/ROGUE/ROGUE.conf (or equivalent location) to current dir\n"); + printf("you must copy ROGUE.conf from ~/.hush/ROGUE/ROGUE.conf (or equivalent location) to current dir\n"); return(-1); } return(rogue(argc,argv,envp)); From 4517d614ccd1d9521e4d46a244065a40f925577b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 19 Jul 2021 11:37:13 -0400 Subject: [PATCH 034/115] increase default rpc work queue --- 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 2ac1ef9bb..d7f56ea87 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1398,7 +1398,7 @@ void hush_configfile(char *symbol,uint16_t rpcport) #ifndef FROM_CLI if ( (fp= fopen(fname,"wb")) != 0 ) { - fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=512\nrpcallowip=127.0.0.1\nrpcbind=127.0.0.1\n",crc,password,rpcport); + fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=4096\nrpcallowip=127.0.0.1\nrpcbind=127.0.0.1\n",crc,password,rpcport); fclose(fp); printf("Created (%s)\n",fname); } else printf("Couldnt create (%s)\n",fname); From 5fb4eafd1aebfd5659d853df8adaae8b16fdccef Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 19 Jul 2021 22:02:44 -0400 Subject: [PATCH 035/115] Prefer ~/.hush/HUSH3 to ~/.komodo/HUSH3 if both exist, unix edition --- src/util.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 7834630ba..a470448bb 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -548,13 +548,21 @@ boost::filesystem::path GetDefaultDataDir() } #else // Unix - fs::path tmppath = pathRet / ".komodo" / symbol; + // New directory :) + fs::path tmppath = pathRet / ".hush" / symbol; + // Always use .hush/HUSH3, if it exists (even if .komodo/HUSH3 exists) if(fs::is_directory(tmppath)) { - // legacy directory, use that for backward compat return tmppath; } else { - // New directory :) - tmppath = pathRet / ".hush" / symbol; + // This is the legacy location + tmppath = pathRet / ".komodo" / symbol; + if(fs::is_directory(tmppath)) { + // existing legacy directory, use that for backward compat + return tmppath; + } else { + // For new clones, use .hush/HUSH3 + tmppath = pathRet / ".hush" / symbol; + } return tmppath; } #endif From 992c2d269fd4747aafdd308127566f3245bf866e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 20 Jul 2021 23:54:30 -0400 Subject: [PATCH 036/115] Add asmap.dat to . for convenience --- asmap.dat | Bin 0 -> 932630 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 asmap.dat diff --git a/asmap.dat b/asmap.dat new file mode 100644 index 0000000000000000000000000000000000000000..aaf3fdadae7f9b73a4f124373a1047844f9fb8f9 GIT binary patch literal 932630 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⁢P%5m)_$!5Yj|^ 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

  • wJ_0Za;hj?JZD$hFAS2}_gS7Vwi%E;0%`7S5vX49wg9_^mUbs54X;_}`Em z#bR44v3qy^KH&cdS%0F|0B%ed&_uO)9$l%4T3BOM2j+ zTXlag{l&v;$*FcD?%wFx)1(J=BxAC~eK*6macDL~U>E1$-m}u%+xWRQ<)FZX=Y?x2 z*iTPnYy16qpjWL~Aoqj|QTj}8Mn0zewi-#gSmU^cYUdDb^B<5JN9sZjGF!QYkAU7a zWPO-BBa zFt{Nm{o-*a6_rKO{1QgFU(A(YO;hy~csK?U>qLz`>;oPktxw)|0^0;@GbIdy4elTV zI_H59kf}13_-pE9_3CdZlZ7z&8Ib-tSpz!;3%v&MSL$~%5tNV@`E*BHb+}in4ans* z7Lcu+}Q%NtxHkTXpXR@Mk4|AbR{cfBmRj zX*tX>ptIv;>JlZBDCh@;kx&07q`S1M6f4;yw;>kZ4%nqXg-R{%@=n7;l*44z4LpAp zUW!7Ft}8{FZ3ZItT06inRxe)X!9snDU3-vLFKR%MaYMe#=u2i}#f^V1qbkNytYFn<`OS1|zxR z)!st*;h@w0Zj|aGUP$b12chemq{?ZsXf>)CZICqyM*Ybg}2 zf@!?Crt;$2m8d^J6qc>dF>^>*o7%CgtA}+2$>Vu9)>)|JvcDSc%*q zPI_&?WKd7q*>zcmCnqPI>_z?fmzOn?DAjAzP^HgR~D;7eQe8a3f#PI;buPm z*0Vid29x!tr(~e==-w9rQ}Uwj5@G*sFs2Ag&T}9l6$|P=(!U_a@RMscBO;R_>e)PP z@V#D-wN}Ci{TD~8`iZuanTX9(&9(s4t8kV;n=(Y?Nb$U}g}t$bA{&>FmAG^@3m`Gj z`E`YlrCUI7y)J;FZD9DpuMIwtw7TJ+L{b(DP_;v?U%R>t(Ltw~h}Vyy9B`iWw{F(> z8aQBmM{MUFt3^Ks4JsIwsU3kZ@nXEv;vwAByCSOrt$X=I`cR&E!BtKK-)SOu@9p`Atq*rfVk^y{i7TjTx2@$^k6H2`@sT_j zw)3}ss?4OW>|h!%w$M^bodwMv*O34vsAQRO;Zu)MCp8ZHsca#v)n=Rco`MOJ{Wdk` zUsudO+ih~kfq(J;sQ$I_y;2?4Szl@U{4N~#_$pEC`sgM3zg|ISmJ9I`nY;o%X#o&X zg1`n%UH#Q~vTGZI5>|7S#B%#m2ExKF|7~d!Ju{ zs=@g+69-`m8QBPk~)Isu*~9%2WkM1yuk1h$Xg;)Y*uPhBwCG zUrSOK@hpNq7DKX9Xb>!8vUu`$A?K_Dw%7VCP#xHFeVG#-S@IV_oidg5(U%}M&2+=D zeLQ0}Wx!D7_UI=$O@C$KWQBM-Lo5JHeM_1IP5qp9yr4l|)*?fMukJzcbXg=M{OvFK zE4pNdEm~2Gxl?BS9TT*@4v_a*wFItw61x6wJFOJdZL#motN>D#PVKhM&?gq7Wt{8- zU+vRgzK9aW+aN})wVp2`LoAFew_W$#7#ROUI4i6k9=&~xAzfwUM6P=}qVl>iFN#31QYJO{!%jI1KLZpx#ckrarF#}b3L9S%edp_(XARUV;yP~>q4!6#q z>jy!g^i<~m0n3u1V3r@r$a~aLeap26a|fd2MF)K3+{&icgufn$Uf%Fvj_<)7)cy7J zRp&3EtLoq13{Y`KCrPVdN{4zPEMQo#Pb|HMhQFFXHtwKFfka!YbOL8ALL5Pn2haLJ zwaAZ=q3xXn!xzj^Oy@sB;sR~ArL0NxGbxc*c!1BbF-%Wz zUQ)$wYR#gEUGp%DFA&nu=wxCR`5ZL?oze5RR1j06)AoVKm6g;iT6`Lxes&Bo|IA z%<}huRiUGphXnU8a@s&3YE~isZN-g`b_=nRR@}dw;{#Buakq58LnU9186Wr!Icfdf zNXk5BX|sk*`pA0iHbHj)t%JHU#fd6!B!A9tW{pJ)qUZdJP_iH=9Ybz-bfeMG3Lu~y z94uU5YEM5$Zus_B9-SoY{kgPB=6q`v+dh2a+ZfLa7Pc{27q-fuLJJN=8-5eKo~wX; zPM8}tLdhW;4e751KUoQzb{KDRvbpB)gNFZ=9_mvnz?j#6gwNjxG`AY~{D--2{iGEV zj6Rqro5z%foK_lwsy+i~RoSu6Rz-UpCrHi1ee5m^sqwu%(>5ROn=|EGCH?s+WAa|G zE%Nb6{SyV5y_Zhj=g%0omK~V3mj4nlI(k2B2MHpZz*bsfMig%{1+hF3{&2xZF#UF> zBBS}oKB#92_O{utha=a0!eU65_0JSsrn1D6nCb-0xH_`Yhi3ePQ?{4?&ivoMjcz(_ z+VBsWlq+3Q4bYQLd|B(m@u*}=nCN~UN6GN;3siCfmsEyVFjxosg@@UP_Qz(`Bv*rUqy9P;0G#p=US1V z(?MDE>eJS+S5v^L_W?ng2RGH!sq<}q3RnFZi|Tc;y`j4zz-u%7gH&33;*PMRKc4`= z;3+izjP??b+pz#oQTKYl2QqkL_L1SGmnlq-Ols@P+$_lIOq>&!I|Ql8SG2T9fw{gT z=QJ==^L#MF;yN^x2hkQa*3-fIP?>RAI)d{bLoh8{WcuqXq_@D-Zgz9bEn$x9V#u)< zwMvih;XV90ozIIHb>?Ja2l;PPYoz*)x6GQkZ-jwlQGUFF@O(r%*qnYz0yS}~Z^*_Q zblLH}+q$-`&7dQKY@E#1@kV~i1F;d*G!3RzG3mg5r4!SBJ(if;pD0F#h|NZJkAqFD zFO_Sj{2y;j-=BZyl{>F*?Sy7rkX=2Q7(FqOKFRoU@}!70bX)NtYVvC;$iyS1vid!J zCei4JUoUG*E($BK`#$qpYlWri{R6N11aJh zc9oqAnm$(xpi<{Y5(B0A2-q872&Rc<)8c{J;~Q9nxROx_F`BU_oj?m6LD_Xm_L`?m zhC)dve0ixVZ`&LFPU#J|fbU(@IFT0pJ1D#C{&nDdC-lTp>Yiq=I6`jreXjf0rJe>) zkmV?A3wsVggml15PXHc@tC$8H&UpOSUlwpBW+c^)LI^nOpXc@zEPE-=G+2g8Bm|%4 z(+y7x$5)Guhw6!AE`;f4-^AM~ z`14+A86*8i95=T8LZ7DK`E-3e1^GsWg#~sjjaoW@J@m8Wgw6X@JIX=lSJNU2uB62# zv5sn|_S1Ls`!_Fw0yE}K-cWDeoDQzs->@ejSu@wX-o?DmEy%hV>=PH@$k^sI2#&`HjVsQh>jgrxcl3nXzgFC}%2Rw?g z3O-3<#31iH2%;%<36wV5Q%UbO#BE#aL7o3;854B~SfbTuvPL1Z^X;Mf z`$s~Vi z0sFO|E`@8}ofih37fM^#-%`WLFhqH0NXYpd+N-kiI>YTYY?tgtf7@T^iU$gDOagjC z5W*4qyrbernONe7aq0p2{qebD#^yJ1GSE#9OuWoM;u0Uxq;`KRbvD=|U`XWRt6q3X zlHjgZG%l-wDI4>WvA+AjM3(682YL}Y_y?3tbuQ#?ij2u}Z?q3zxfLE_5Vbx`+x7UX zUFO`dGo41nXP(3H#(2)ogb(9a$5nV#h6$*fe_AOKdAd?LlpJ*%OzmR}$S8^nH>!Mw zRQMk+B}l4c;wIf}L*mcmpiqH`my=0E*Pt(yUJbR)+STp#WO1FGmT}Lm7C1gzYI+l_ zd5h;-i4fJ_kgUH!8Pc#vXw2AR&~f!P5xJ)2Ml!3otSb6$QZoY?ahgnQxnIPqXGUg6 zBdSq{ETT0U5#Jfq?fK?vH9taZzVif=-$}}Eo-o{W{}Xk^@@OIIcEbq?g|3n;W((%H z_^0-|I$$U0G*-TCzn!f;>z9`$*6@zH;oV-Z_EQ2ljzb7C1~1uZLWQOGjfzHnIlF*)A(3A{)%N+AE<&naYgwr>dI$ zqp8mQaCuG46V!&WDMY_~q7&G9Y(23J;lvy+ryLyXf96WosHz_j-7xv3qxYSjV;$V4 z;EBD(%H6@u0eT}?Mh=&$cV&G0Cq&b-#eByeVm(HdCwqpR4|#}c4h~3yCj^5h!h$Dy z2#IRqbdHRji;dVk*Sy(0hcr``H2-({r`KsGFXu>2rbjE}?|*$(LPTn_9T%<8lpft$ zzTXiS-I~?;WhFW~gu0o=@s&Xd2Fp>mxq%bS2$f|$PfUdNSv{gqTW-EzxoN;nzR%vIiwp;uBky&1g ztT|5f@qb3!Djp?k=2xh5FrVHse+%|`!jdOAv@d$oCY<%r40eV6N)2R@!&&af(IaM& z({)?EB0*J8f$am^g?wa1XGSylfg z*xsFZS)azCod}Hb6YN1Q5~p(`SLnExNXrt%&clA#v#)7WHpapUQ`^28j8Hr6#QrkA zv$IrR&^iO}Adc(c&n1M!u|;rnd$bGV>TPN#0#ciQ+qw^NkypMxd-QC}Zx^8V!Y(*X z9zN-u2#lBg?rlf0+4SZEQyM-pd8z4`IgZizVH>R0>(++ZEmhF5kT2?&SHD;mlDk6_ z==0?KLX@=@w{>x!^{&d07v*easY9`7+{v7`Qo8T_hi#ywHac#KC`n*e%a>x%Q#fAPS6@&|=D3WpzN_{dW<&b`8rk|C?>112$ zWZT~=9#Dyl>6sIsODUQ$y}PX$ud?=}h%%VwHFcCVuWOG1%|oAe!Rs2Dk`=qdEp~>V zT^4SyL{DnY0~ravGB7`9T4N!#3o zDCAn{o>sYsR8lF0DBX3x{a^q8|9L!*CvD&FdpYO4pYu8AJ*TWhg{ElM9>!ly%es)2 zH42r=;#spH4}l zV9gB)r+Vq&MwK-HJfxWu_6+G>pNr5ap|L(xI`4n9khEt=ZOysJp8>s1o4&YWR@^~DNtv7NnyYOYDczSU)B?<`H6s1t-PPJyln^HETN{I!C2K2kW;D-!P#Ab z0g(vF4*Q6j^k!xCg~BfmtP34aZo3|@wl-(QDboYqNjB~u<7*_Pt;jZtiA2nz0(?~5 zFGx*Urc(&bOFmV@&3#x>X8WCO8$A)fU#R?k@xk%;3-mRq!vTcWB}8IpSeL!eKTA#?o1y2 zdOYVI6Vxwt>;gZC4%xCb<$KsYQ?-V+n{OQHTTCiwt=pJ+_QHSe(yNz^uK&^8|21sE zB2u~oa?&Zj9m!J$WsYptOMMXrOOc)@LHM zxHa0e)gnr2bHnG*_Q#uY&t5la$w2k6OxjILBllhb*?YCuSFx#S?Vqu$JtsnZ!6g_M zWWZ3OO4&R?5O1)2GvdvEbYq7=rj(e} z7X5hz-qL$xforqJZ-yu1(XW5@Dh`9;7Vl1Mr8y+A1L>_6OQ*xR+QtF(y@}r z_Z9EAJ(~M7*RbcL?1K4vzemC`f>VvriYk}ea>8DZ>ae)4i#T_-Zv2W!4zeq5|JRon z7da{VMVD&5dq&=LQ1QzI(;?f4`_|)N@?<^PWTDE=YiW0t&P`rOTXXR9NI{|ccfsnB z0{poMohXZk+#~*7l%!+0{wGT(4qYC(wnJrbmxtaxVQ{}|(tB+Gll9;s$6AZOwaoGy8?c(rZY{+l_W7fTw}^#J6_{d#zG_;g7D8V`YYTFN z6rr!(h;`*->!Ps>fARIPSEtUe4AX9m-#KSh&ae=-Ju)BFedylt(DQ+Iv%af8gOl&4 z7HmUHJ&4;@Cg^ruGK}jSRaz4C)I3#-_m&V-j$bm&MDG^2F>V@ImaF>K)CDr^4%XTE zF-&>&MkdVw)%eyp`qs?w+N5&=vjtxnlO@Iq(pg!jYy}L5f@x|L_^nDOvoSwD_^lWai2>>wlN0 z)osenDHJl)u+0ayH*Q4zI$=UGH>4+1rIG-Ki~BR5=`{312F zzF3apii4i}|Ciitn)EAwd3*+H)~1Nr{_FRld@Gm4u(zdYAjlktd)OeZ!r_5ZPYdQf+-FK|Bi&u11>JlCYQe|yTsx2ctvZU^7rRs4FtZ>&&sQuP}9 z`xeW9&)nf(6cT6u{)O@NTTgFy-fO_wB6W$8e0^+tGFKx6#ilN7_;{=S0iD9m;L-0$ zV(Hn2B-Pd|bXgRhlsI87JMzIwLSyO6kjxL@h8_Dbu9k(UytKmbSpMU{XR_9H!P$kF zEsXBX^lm#^Doc`@UWi#dL|XhDI%DgW>MNQ5lS*tn{z4aYnwE-;rTqVA@}M8aPk4Yv z;^&>MWG`yZgZ54%oR?Lx$0(D>PO%qVP0wFWoYbdwoT7DsALmsPx1{VLQfaOxKhJ~n zX#j1N%;?rCJMX3}v@t)@R$uL&?~Z*l^!eyWJN2jDoRz%R|BW$db=F1Vz+XETb4XeN z4AK%EQ=XIm_~#o<@7GywJWMFx?%sAQ)9+lzDZg`Be&-0B#WM}Z1Y_^kwE8&@zVi?x83Jjj_llX#&VY2^EM;X-d%xF)2`ae zKZr2v*3#vgohteI#WiIIL--I9Y=AseRIom!kZ^+4zRGp_NXU8w>Cf6&1W6Omcu09}pEYrd!>SaYi6Jp1l!<_)tjnpryq#%~Ec;}b3MZ4*kGdUx)-bp|K3i^cC$D=!@-Bb4~!0lxeU(gyVRBE2QM zG{7U5MEWTq%Bx(nkmA)zOV3}CwO%7ve$0+Mzh&*{kw50C``0Wwe3E{%hz@6N*T#*J zU30Ba|E{Y3>|V5a-9b9zd6H^IuPdmSr1T4ed!d0~5o2<)tZBVQITM)6MdAHnj3@{1 zByrfuWir={@?Rs*EbVFs#iC5*<0tUQ)c}D2tvaXJzgQ>?C z7*Am??oxg0k`Y;Sa66rmhck=qq3xI((l7XTDBC6yl&H?eJj%A^EjF_&-7G`&EP5H+ zd`m+sLDkeHBTEyLpsJ4~e&?ytH;fEz zndtQW2>ymK@OlJwT*N8QR*`|xz zoqhjm{rcc?@UTr$o~=~zC9qH8Yg9`c7NRQtl`h5ocTMPrh8Cm^Sn){|+UTKC{tU)< z#|;K}47$Ipa{l+9{<2vxk~%CQLlER2CKekN)0g&_Nspeklh-xRf8u3-nNpNrs+4Nk zXVkiA3WG>c?aN%IJXcJg=)ZnDIxK=U(Hr$ZDrMM@>yH`3Fa!i?~XRc*lnO}xi^(#$J3MvVpu zT|{lyjM2>e!588Egi=*I@ZTddm_ynLsw&Gf+=`HP{hqx>QR3`YHSVRw9 z04i4rHo)j^qssMRQfen#xCw0Z6o#UYtDts1GU6>J@dOT0Y0*+Dt7U$3E>SzzvW%Vv zS&SuV8MmvzKHm=+`c4zFC^r)I$P5c|KC*hNCOQ8Ov}i@dVoJnf+!Q7NtQY?-_->vU zH%eu(Sm5Q#PDS))q$LyVPWSvjcNWuM_YN;4>Yhojy#w>EL5$`Pq7kigL3|+r&e!#;ZqaT%2PN@x(K0ty^xC23)8Nkc*8*vqGQsiY zf?f=vUnyC&A<|$tzY2wJb3g>3i$Sm3a`d4`Hx(C8>sf_i-yV$hy2^ z?A>;fnrd)Y<#wAC@i{|aA7O@35<3(kWbchE$g;AG;d_o}?uPV_rJ-^g>P`Z5gZ5kkBVNl<%kO#?T8c18SrMubM~ z6pEkfrmf>j!rX!dX?1oAfmUIoF6$+-^N46>_gvq4Pz-M1-84mwz%K6tsnyFk}-m#c!*EF5Q)PnUUK^g7%3A zvRB;rGVT?Us@!D}{|Uhbb@LaQUkn6k0Iheb+!v?itRKaLc5&z7A-cHrcxC<2d&m8n z-<*=WI2$)ULMkdE#fHPTSgWtU(idpTcAWqyFz@R@_SLjspfeXIlKf1S9W%`@wa+~C z^ixEn>VO*K=(5T-zYnR<4;#Lhsz{d&Q?)=Lth50Bvj|m!zt4m0CvB~>h>Pooq*&|q zDk@phGzqs1L`T1A#=PtxADP!s^3KXI{phOEJqv zPwC`|_J~_`IC1O6@CY0S(x2QHbL}1><5a4S5U3};HE}=vmJy*n1chR+M%x(b+hmsX zI-%nqo$GfTz3<_pP;kW!Yn8h$2tf+QmxU&XX0 z*sJcNbX2e^SnDl!hVmU%J>}Zu^3`<8xZtk7Cp?HUyT8y=$6Z0%mMsNAlzXgUlhgSK z)(<*Gx9q(xsr3L)f=ryzhqj-2|K*Lv*Vu10Nf+%NcTNJxLr@3?3SDlVA~sI^GW5)U zC~)AZ5=5lm9_hRQ9G9_yqrQ<(gaqzs8}vFSXAz_&Tx)qdvXc#utV0aiieor<(CTJ6 zLR1@e(g!Hfv&^wDF2e-eES~mYF+mZ1QPcuS7P@vskIO)DgmF4OY~PSGVqL%z;LSqz zA^s@9j;J?@(oTH+LMy-5_duH2hsATl86?n_BOshnNnA2WUz$9n>R04MROLRwko{jX z-p(NAb3H|Q(qBB>x^VG8R-_P3a1PHyHZ~~{IQZZ$tu#^$1J)=m#ojw^*yRNa9Y4Jo z`@873cBMaP_k&AmL^tKDt``rabHw1jW9uT(232(Zuwa8@Dp>JN<#H9#$KQB|i+SuV zMs!AmMxN*rT)=?KOagM9_#?l;0G9@xD>^mVmSw}b2HLv!9)vpA)u8Xsn?lh-D-v!K z9~-HP9anCLBscocAWs@V3Oi@S%SQCa5=yYG`EtbN#@44W0Tj4ED|83;04t0Wu2ks? zV)u5L1|_U_0fKx`3X!CSzQ{GdQXtg; z12-pq&sW_ima3w^qXu3|flgQ}Pzk*D#_ zLf1&JK42)T5jcCMr?-W+x2VQ?5&NXLWU>6B&S zu5pS&p^_;jES9AXOHIn!j<`l}XzPi?`_TK|^d)QX-Ex1yx#mC{QY_ zmQ9O}?bgGR65r8jHY~Veh!S0i#p8e}wA(7XtipbIOR?zqXL#)9DYtLcZr=odhjg7n z4hY#JdM%rTXp#o`APSlxIHxVTh$dk?)A3w}ex>Z;*CXpd@ila?UIxfF4~G3(Me!PB zVh<6*d0`g)AVR#A)tvq4Dk_EN*09Lyfx+DCHm{+ zePxT`Nk!#|Vyzkh--RK_GwXDgvBj-Tw`}jv_p+6Gt|yoy}$-`5n-lQTdd?L<|8_cRcs7(}qYylarZ0l8I9q$Yft~XN8o}hhnv!FSWrR ziUqd;K^A~0T^hy-+COfdD*VA1bw?(;-(rpBKSFjwndzHAyF9c!FX?RSuMJpLPisxj z+r%TIN3S*6l$37x_QC4NFYrSkUlpO3E@#0H(dy7p=% z;(`(=rOyHmF&`!R=p}yu&NDFwe|e$jVkZU4!~E1vIantCCv@nRPMXc~w1rvl!ib8z z#oYAsitBi8$2kFX&wRAj9Y0=eWruje6T<_%^hG4R3_%ilLCq>CLheF}zx{K(|26Eu z1sW!1Dd-t1_@H^jbip|^(|)@VH(e(p-H1ffl>Kh?=OdZU8K^{aXb>E*jg)as@{MnF zN`_4D)aMLE-L{T%pS)m~8aO{)(MiD99oRYZYrMR9?%+tqvl*v-#ghW5_$LTbn@LRh z2aep~oh#^C)rV9-40s-Y&sMmYdU|l=4OJ@WwXSKbL-1dv4cMuLJl+zjA-?T_|8Y~- z>F=stdd!d&N7l`6<{?~Q6FdgKU5S3AK}JSFvvoOy@~;A^CwJl&kX6gjYKRCi1shg5 z53GxrR3(Hv5q+SA6MO_fv>$gF=;-B6c!4BTb6Xs zLi{Jav{Y2r&8?I-8JE;9FEDB809Qv|yx@HbV}xW>zO~9fgs{&YI>7%K;stl^iv?3D zbFq{B+uMBAaj=FKmgB*&Dq7c_-a3U;!#ZF^kL*0S9T@Q^cc}b+>8d>H7;s ztF-gHb1FB{?SWl;MUdI`V(x^}i?5Ur_gKh>Ot(8SIIj9p$9f5z$mffO;#E9n3vSeBtxoXR~J&t_}nRVDE^v!xHy zdEI7jHSiKF38Kp4L8lBem{Y?PqIC&=W1W-z;GEX5_YS)-Os7OF!7cE-=Ab|cWPZZX zme^|D&)$eUTh~XcK`g$RwF_L7jD}n+=!eKO{LKKOXa87mRf?Us4U|s*BKooQb8_BNm~>aJ9va?5D8DZq zxPz5UL^Ga+oUR3)T}e3OmD2Ps0MN9_^ruiXqsILUkPh!sT`uDUVTo+u7NOh(#a7N) zy<2Cy&tN<-KkCg`{4g=`9kAkr2tcqxPl#Ho14CGRWH`eOX6|p#y(w6#HV{#uy5SbUS>XcdcNaX3_BmsM&+nMCTpgu4Kt37x z)ZxCGr)&F%|E8H0&biYftA;wD!I73!L-MywslvP5*_40Txk{~EnLiN#M8t8xsNlg@ zb#nNdA%P|Jy=3%!*&8b=_9Cv&5y0c{Ldb2o2P;$w!hjAxGx7@pgxMY6>7O#;@iIO1KO{x=MUtD zZcJY1ZL$7OCHt-SBGf$d7PRaEa@X67QmlaPABQXEU(ADY{Az5AIbW7UsA6^Lw^#AJ zpo-n9qH%z^8#1NB)e>xI!U6GRPtNo@#8c{C@{re3XAf4$G?cT?%nEeI6ST`6z=?qC z!c;u_*`WF8{LY;_l9Nb}A~hBdbprU%3WT_-@|g*jQ44!+`T?B&r*y`9%C2F@69uN8 z*Va!Rrp)AK?KmKAt%WU5ioBy+0@4-H`kwD|qIXR=9Q2Hs%$E8=vhGflYBnr}BdE&a zE_^MpIF%RWK_>w03y}FC@!by{&&7g_%EZ&R=8V&df~r6LpmQ%fALP*~jwcTy&jQY+kj@} zNA9gBLO~R;E8T?fg4%e%QAOUSti7w1M%zI-$~!%}Z@BpU0XDL%T6qK3%*4h9Ed1-9 zpulQlI)i;8erylo)P%4F0&;LGO=5A-v=vBDUnl3;1^^|%V6@8%+;iuL}({XfyyiNYw9oW0{3*H`L3+#p~UlVdUbFu=fF)5vSHHmXxK00(p+o0 zfD)0eq5RyyJSMt71=!#uAR0NHs7aaMD=Z$%=XL{BmLx>CIU>(rS=e$W=5=$t@`Y(x z*>?P~1*F@Jh|0g**`2q6;JLiOWj-W7z@+ zB~MNdZxK4?CMfjq3pbP~9w^P=b=cuco*;e(LM3)-vH7j>YgP}bg?)Q=umIF)s*Wh% ztb>mN?ppet2;gU=pH1gg=%y)rN{$~9FDCVo@Md@t^)#V8&$s3B1Y%;nf$kQ(kA?SB zdh7OfBqp}8Ym^1HgX15hetMnwZYy(twFn=^iNk@mw#68c%Y7q z6pH%t(Eeh0jsbr-3(qajq$mLhCmQcnv^WPLQcuq!c$X<;^*m9-Wy6fhLAg;{-LdEg zwD66NYHX^DGYeWb^bU8@=L=FX+N>h)m-%xEZ$p*?ZoQ6GsNBT znv%}*HY81%@E=8}fkVx{g*|O$!-|Zfa~Dy|-&CowO zD25h_zc)}GLRIe61@uYvJXt1MwiMJOsL2>1w-Qy6z!gz;uoJ+4nThp$|SE17$FC%n#{;{_q#S88A0Nh(0U{USIr!KJ=VQClVpwr-G^|wXVzA(-JAk_4{p0 z0MY%`x)$~d>@uZ|d+`P0#oUf)MUESIn?2`EM*$J4^9lI?X2OcYI~jOB3#|^$-t^|z zNu9z)_q4C+CMZt_6*~OA90j%Kw_iqYZKy9>GjgX}FrhN=iuqa~sM}#|muBb-7H9UM zpfXGPVHbYy0#fVqHNpw`-{;hbBMYHTJPr5S-PT7S>gfeQJ=oUJDh}{MWI6@k;R+02 z2eNWAF0Dv?i0$4|1dcClD2s(x$_7}&I1E~N#(YQr6GTNJw6M8Rm)miO<1*_kiP%AP z1a57c%pn(1;j3`%0dZF>sTz&f4xCP{cGbimUC8aw zCZzflRCna=0eIfAhvOpe-Cn(60&HdXwhrCO z`q82K(s=@703oSYR3!Aq6v_0Ho}VA}+X@Y$x^7jkj= zrp;%L$ABkR(kT)R@;GS-b5|!%Rw3dnf{Ge}7u9hZCPX1R+l)xnIQ;tE#jg*PzESI6 zA-MSEfh9>HK&+Nw*SmZM9AQoCFHY7P#1$(3+*;859GZE6;-c7^zBR-M6uNk+g0%ee z2|zt8A!ma|mBysBk$sVfXZl0V$W69gtOX9~JTARvF`GTJ%;)tMq17sAoCu+Q^L6YA zJ09ekq>+XMWjO@$P^ZF`g;`Ah^yIt1vtD7C>_5GzLc8oMfK6JW8&n0VLWZ5Dq$>o# z&oPlPRXw@7Eipa!$-vmG=u+4#1lQU7EZ^hLwL$U-rNM*@9(U>O-7=Tf^oBRh+21M5fdMV#tOd17S1=%wd3#YN1-|E zrrAV@vINkR>mbS_6oZyHh9Q_K9iveZd_0cH*F9cfgmBi1Z9ymM`3CC1JqsL^#a3OP zA!nA{gMwW89ADIiH9trj+1TCz!2AaW9M{kr23{Li(yGRQM^3>nln7l@s_cCmFsHbJ z_ah;7;pvrjps5_*L55KA+*W`F!S!Q2r6N<$e*qAd&ZSUq+ycgIfP=HnN86*zj)A-y zF-(eJnBjH#7T<2&liW9QjF}G>l+h&vTg_lE`1gLX)K#Ir5tPby%;-N@TDNKU8Ge5t{+BrgTrJZ(~|bc z=z2PKVzdh$tt&C|JpWJ9xM0OClFKcUA&Gin7J*ptiIJ5U01{Q?OLmM0Ur#^>7Y6b0 zCeMzo*kAF5k$k9rAR5S0XEL5+#5H@T{JdHw1W+u=d!lvVmPOijjx*qb2XB(*T75Et zT)~`lb)Zi@OrE?Gw2~&r6bf^&_#cGU=R@%sya!A2S);RH(-9&|j@WPy%v`sAWX22fTmt#;(KJ-JxJjGEz3AYH#7eS`-GoxS=4U(l#xEZ0GR$qXvn0V=M*=+Onmc#b6)J z56<;4TlEaN6$p4Z1TnOaZ#)6cQFWFD+u# zO+m zJ&i4zL5S*96rz&P|1tM_w|jj^3=kw-{?~A^q5DK_P#DN3aQ44`Phl6ScKwL>>wa@o zmofxq9|yg5Q!pEdyGo(%*Z2kZK7c5X6#>9FWzjyst-SC7ltV@M&?hU~c)6uA-kEPM z7!9KVuT9#<(c8HUfG#uE6df|_W$vx#uYV z#z)58<8@nS3IA$LwKBwX>J7*IT7a*?*A>ARD<|bjtEYbV@dP z{2vhZMk;<%pQOWMH5X5N9jmiWrN8n>%3v>a2rpj%wv%!c9xg{qZOs(SWp=Q9E=h9Y zVa{%#j}#qPZ#7suoEJ~*<|v9hLh*@2h;^YpuCZz9<-y~vuKP?<5?A;e+J&qHs|t)* z{4S|w(;B_i6Aozid!zxUJ;6!{TKvx!7TKh@#3Sv^6@pCFE@gZJa8UepTY_2^P`qHhtGxk$!0M7)&SLRZ zyb4@l`@47sY?~@}>*Ltgp&x7D0<)z|pSK`f`V$@r5Q;{f{S|X}F8=XeYL0N+Arxg8 zqyX-RVf?Apn!u{A%jjS8XTkoCezQ|xeId>k`|C*NJX7Jn0m1?0kC4_BMcO$i6ne6n z7vM!fNkY-?6H#q$^}v4cG;mYFgBFRdKwh8nD-tF^o9g zzeX=+f|g75Dmk9`D`O%UIL2RIsa$mMC+#o&dVFm8nDWztcBCR0)?2jA@=54V`|%>~!1@Wa14ch%a_C0kM$bn2K1=@Lr%huER|KY-x?A@K~Q8s7o@y%Y3Lu zdb?|{Q|9W4JrL*G4ihWZR1jb|E;xLANar@u1_way08znom#5j`tDYW7Z0=hNj_}76 zvGD2?km+;~t7r8#Qbd|$-6K%-D3knOMSjZReFzW#;kQpo zUycBrk>4)LLKBj>9cRvUVW-hekF^B@k@de#BMJWGAggy<2CjsaqveTU;8<*?Eo_ftlndpX9iZ1=l~EFEf;p2c(ne&Gyz!k4hsBwUpvUoaz?T~!ZdS=r2mu^ zz-D=;4zus+5DKB zSkn?nzD&UcRqor2-T<+w1M^!*^WP20!Fsg-hX=?A5`o~(={wvG>Y!yUO() zPJ>(`6dqWz;v^_54eK?D8p>B4#a!yg;&rgD#IBa$x zsMKT0cSbG%ffTXn@JUD-1GKx3qaF+>*gCj10a>~yr_Ioe)0)@<;_cB96$1jeQhy%6$woLAo#$(0~Jr#afi@l$xaGvFi37- zmVhfXP9j?X15@(UUjWLv0U9`e=W0*vuhAa$>$?Ht>VhBM*Vqs09718vhir|(=l6I*|~ zE^Z=QTDgtyA*-3f;tkRly2MLspuO)-0P?Zojsg`^F*<)1_(Gd370hFWWru)v1iite z31XD&(s}1VLf7OEL$im_l5-np2*y=KSbQ&@)I!DY$C46U_clxb=BOK$kSWbEC-1qh z>&e>Z)SvgCEu+M4m3|MQ!bX~+u z7ZX5TtPS4Ie=7i$XwIBBViSjZbv&?|43Y{%;Dm?QW;3q&RGV)b3CNf*ihKIkG2s0iC&t zs8nI1DpgSH>#23X3QRu*l_o+;E;(jPqmRrI$g6Zca3OI*5z@wjRRZRjGQeDnZo9g~ zG?u?hJ+ZpAo8>10Y=~f${0M^3Lic6@XzO*_g`K&7`wCNXfWXw zic02wipfLBs@lp|$20O1+@}A@4cL@BNO64b)&h_#*>~#51=^qml5oO<|1$=k^dN7( zu1Ljwcur=xGNV!jk6?eTDAO!o_ONI%39w#v2J>FO|F{?Y8rk^~9tnOpKy-`({Vk&l z+%hzOGT+p55&@plrVQ%Ln^YtG{$oXzFLnb${|=|MRum0Rie^Z9Cb&m~JeUklaB=^m z-b=B=LnyIqT0B*|XWn9z!a--exm{+Vfd?YFV&_earR z^|wy0Wf2h0X)(nz0M(Z-ou|CA2s0|2qgq=q#7 z!ZT}02x^yAcAq7Gf{RPC$ zz2x?w;CIO>NNylwgSAm}ek9*pE*Y_ozXRF?esaUtQ|C4352V_yAY=kEZju_YSw#HA zgZ|v|zb5*|dAjOB{ke!>B7~==-E9&b1k4)?1odbN1*oMTMJ9LpxYoMF%cnt((q=Bs z$p_&-4eaCXTu}^V@EB(VvEVKip9|20Dm-@>#&8n12bUV296-j#<1#@SRKc-f{ZpbF zuWxLd83MXrj?HvJyHEBL_*rTL%H;9y+=6Y#!Q;wg?290=sTypnB^RH8C(Rk)V-1&a zJU1clD&oSM7s10}j|+}3=5i%fbaQ+mXFm0w{aetARwVOG(tEWe-2v8MfC!u+5enJT z8(^?@+w()3G9cRC)uzzw_UmJEBGfS~$oa;9)-z`0wDNdnKd{#h?18t3Yvn z6=(SScjle-Apn}`I+7VTnRj4(@sn`cn5_*ExSh~8-;$-~3eqn2;Wm%~^?8Ft;i&Z7 z;H38%%Xq0_*8rQgYMOmyBS63jj^rUAqrm%h?N(UUDW(Uvj$Lgs;XDZ}{sBUvYkM__ z(9s*bg}^p&d9d{iR(Z|Km8-$ydO+gky*Bg|KBT^p^G2r>c-PYsLX$&yCTJ2s_HUw7 z-lQddf`c!$7FgRT1PN-`&yK`cBE+x<7cuDE)i~Esz|=2Tc@$LL7x`ld=|D`as*tYm z1;2#*o58&79dv=-)&1jdJ}!5N|Y2ZA`Fj;td}6}#E9TPwC%tvsXV+N==?e;C2tIy7qpjb5w! zKji&TP^{wF?cE%*4_IsO$Gk--Pix7mWWa0~J3x`mui7Nr1i&|3 zy;`J?jkp~z*SuB_Zv1=m34-5*Zo*{0;F9qJjSoa z$TlA_KeCkY6r5f9t{Iiq_Bx~0(PjPsrGaEHT~o;QCNrubqGFiUrgoj9Nha?D+|?7s z#Gt1RLBkYL+of>%(w)4c7*5Dv1}?XuJh|AAxCsZcDHXJW5Z$sdcShvri@Z)){Z=O% zDaRuh4Qk>KFUy#qTiokZH6=n*H9%UaEWBjvi*%FidX)JzZLY76_%dSBXze=0$1<#B z&sJ`~xA=0Jkda))aR+(Zn#J=uWWllAeve(RVtCb=JO3#*+0Xd9N4Be41NRKXq*%82 zgcjVzIb#`H)7cXgX9^jCrmPhThD`eSEs}YX)3GU>svtcr3~R_W_1wO0ngeWI%}Tr` ziT3EPbJK6$!Y^C;M?KCQphynryxn@9I_s%_!~@WLYr)pq+#+4fk}?w|LJt6ZT+j7x zhAVDaSSRVGE!?TT_U8-R;;?;=p<=f@%~EjbF^fH?O-AQHn-WuTUm0o?2|9kS0Z8tr zi2g1(n=zkUh1(BvJ!5FmKUDVTi47pLRS>wdFzIxm zq6RAw8gX$=@W^R4=8fjn^VOH8S#Q+I?B{zQMuf_ynRwFxK%9k9(1}2y$sw4xI+n>x zBEAGPD-)1iZo<{uLHa6I@7``8#ZlZEUdkOm08s{5G9 zl(UNFi*Ol7;3O)v(CP1_T>D$ssWZ~u!sB}2R?oUa`O!<(h&#?@Nfn8H2in2=BwKla zHY`7x+*oQ^^vPR1P`(1mi@E5Zdyko|%I*P4OA={R`Xvtc9T>7JGg(0rIf1x-$SF}V-{AjA-2NdVt4lgmHjyNhftFz#=Xz)D~2pOj%0NTb$}Kv zp^3ggjE3JJ9){aB8Em2T6)Qn)&l{1ia8{5WV5iUkUxV2oIa9gNhPm?3_dx}Y-t};C z?o9%jk)i@MHGxnT&IIO4T2p_z*De0-f$X{x_>`X=Fz*HBc9NX3r6k`tNhx-s zGdyp@{DG4Lp~H4mn7^6#cBAB^D_BWoOvTf9WwA_3QkIO2!t-ewBfRpSPP`c_C!30h zm7`hPo(FfT=e@duuEF50wTbjVg;LZ)S=z~UuPn&1mhhx19lW`xWILbSSscnxW9e(6c`nje*@&Ut;9F}ME?sZ{E&&@RWnO3 z7A5g>lvWt|#Iz$`fou^ZSp@$)PjyzHwljDJPTWJyn&0Ws%Co3+D`&t%2c=ah{EJ1}=O6qA2@Nt-4naojrcs>Jj+V14w8_Ly zK<6-ETpIeqVxUBodnDftNM*YusL{(2;CjSa$<*yMn+rcHTbZlzZ(ZTmm|JfE#JFC? zt~gmZe;(;L)zXl*>Kp=mesrufF&#iUf%LjM{<{fR=_#iy0j&Q-KPqcYVQp}z5S;^# z?*^#z!q7+fm-#6+(+JYNMaoUY_Km0mhNFPOR-;ppnq@KJ=`uKuFGTl)lPQjgoX?|j zy@xsv4z)Zz00)KWMIccJ^-cbqFBy4|{GA#&!+BF8uS(NJl=@Dc2lHSC;D76r@>BMj z(LBKrItF>?m`gc{q|H+xp&Io|P2Z$pHy=5d?FGZs0Dt_8B)|aF)dN2qJ&%T&@pxC| zhvqD37o7{jL^l>gxwZh75PC4cLws%_sXX_TIkDTqbZyUx;^bWgnW9~ex?dtx2;X$b z#88O+2=yPxB>;q9C9h)m@FI|YwN_5b{Jj@`Gx~1F9v-w3*tSw$SZ!xLG0?z;_t#a>nhLmF&zLb58r?z&r5M7SR ztFA|fgY+1$N>P&iQiVVWys7{^*PJup-K|A#>Y9I^aI0AA!tgxPZMxNI_L7 z{N>m!yy~_BK+NPhOdHBc(Ok=w+cCJ=QnpeN7qK5x=AQNzG`lAgbvu8~H<<~{?sB2z zx~LpMoc4y^-e+1mZUmO7^7yi~04x?}veQ9O>MQia9^|x6LViP}A?HwKZ*BZH8gO!1 zu9YNw-m%`wx+e%88@l|Ev>jw{k7Dtk7Lls8C9H>A$~{yE4%pAUZ1QPfo5X>37u63D zl@-vFBq^!aks^`ES~>G6PdTghT?VP<<0xURS7aQ>aEPZ7+dpyZ?5Jtqb#-fvxQuWf z*Oa8=Avyd_)G;$rNcLc1%Ai~4fZb{gdm#tO)N;#AU!Qrg>=l?53cyhmyOS~F(-Pzc z%tCo9luvK`4;aGy#WM!GCJq6*b_>Yjd;tZgN`+Hn8LRg?t)35%Hu~aqb~288!8PgV zwSYJBY3LiS1J&&Drz03wIMIzXiR%!cp-{hk7FsJv0fo%luE3EhF9*R#-Pk(x5e=|6 zklC5wd5J3|LZ)U4k}>+eyFviV2Y$wbkszBOisnexlA{Ez8w0D5aifYiiZ zME7WuKgM#eSb^j$-a>X@aAY?T3b;cOIVa51QVvFVRR9pMoTA-gTC|YmIBx}e?+V%h zQQ48>1#b|tc@E*tfT3AqYqy{HjnwvE!Z0Y;rUY`RmIyflOhyJNSmfIkr=)#p^`*tlSQuIp@6ZdEaNd@8^D>&x1xE=7B*~<}ejg+!flrlW<_<_LR(gDwR?Rj0Hz~ zOtBiZYn@N)l$%-`lRQG!cddu=pOb-itIoOBLv6a|M_5|c^V&ppLE6Y=_7K#e0 zz73F^^AQvp@g{j!*5FY}%v_-zHnl)8weB)8eOf_w%fpb37Picbuzb@I6d{RmRCRap z1{s*9i9V_pcQKP!Loh4K7>Ynpbye2+wfEeC!h{lQzo5b}g8lGGiZVpU${FWUxxFI* z>a5UlESINPhikK;w(H1)TBe;F#C@DHoHscwtgRTM_jo~gd528nw240`e1VdA-13etvDpW8;5l-1HInT=50S)=aZPQNYOsOVjeX-_*g|d#?P6nEO ze%lA8H$aL4Y6Bd*@A;F)9v?!hd#=|&7Oe(P<{-h{?dIIo zxe*sGWR^T5R+C&?N>6^yrHC&xNtM1^bJ|YYW4XnP_rt=~+KHT4CKNJdo%0teD>D_J zm6G4s4}U?~Dd&OUYSb7U?zQh94&THy6mKcjy3_23)>2io9 zSmQayCEw3hM_NpT)V=we3Wt6!`P6=`5~??}AX|F835VjPTjniKh6kj&@P&Gma9@a< z3e5aIgIL8e&Q+U6edAd17uj5%^!8EBV1&0Vw=Q8xRHmC_&ZaH1$0YdmGe1z@9j#Ym zQn9uM!PbTga7pM`a+C;c)LQd3j725R-e=L4kfe6^7a zD`|Vp=uG)~+7lkvn#M_(EH&{vb#ruF>X7yM{PCKJv&cy zNkYGiO<=Bet8{UzIy3hu=Dux;sKx9Vd{{g*2CbN50=0!q#cX@5=BE*=pcBm(8sqzC z$eQo>P$|!mL>`J7>Cuax=hI?_7SI#ul z1@ng-g0^mgs9=!J`H1NCQsQ0Km(C%5zh zV~7X{ONRM^InJ-NkkU{|Agf#K)o|E;72MOv14Q(YI{)sfGemcmfbmHNw%SQ^3Ewwc z%db{I8P+(Tsupj|6Ew=>ZA+Qjwv1tyn*df-frshdotw(2X)zJaE?PdlBqOe}_{EP7 zvM1AJ;nnW8pOQI-sIwNAZ%>CjY1&rTA-UL~XE82VPeYp)MWO5VdE z%kw1>7e#YdE0pBViaigvO-2v3Eue|ACPxW7aD!j}VbTt31{{M!J6nS!-n?G7G4z*f z!~rc^x_tp6I`kDS^5)Br5G|avN~B`bj^b18Fc*_-bceafAKbH$nsA+Qj)3HujLF@k zXhFx3ls>Afl>9nr8cmD&G@^|@JI6#yBz#15&6da4`j?zrVK7E%ZZhh0L&{b-FUg~G z-ipTT)|5N8TRarHkKXOc%qT#T!k~smz{zLBkSGY=uk%j^p2(adnlKeoPw@nkQp+K3 z9*M`B6oDj=@@UHkS;ez9Ig5X#B5Ksh^^^qz^Xs<1|DlEGZ5q9zg~V@By=QDrA_1s9 zpZ2*AiLV6T`7+clhsb9HMqH%_^0<1SV#Ik~_qM%rIn@{M$g82uTyt!L09_G3`Z53j zf??98E=t*$*g^K-?3S6*kBqmL-sd|*9>v%F3Eg&jmh*as_B|ufGcAPioT_04C$e?~ z2n`l8a|`US++@!E*7)_P z(o^2$soAvk2=(W3#;?IXN!$hX+nR^ELzQcSt2Wq${pkE9&@{lf_G86wRBZm-qi!*e zDTF^qsxG zA#EVUTklaf1bw3O*S@4Q7sv%2as zXYF?4fUHLE zV58fOI}zfp%kg1~P1`&&YI{~9g3r-iemm(QyN-?qA|@qG@^}GwUNPq0i28lBYKqt# zG%$MY&0I9Jhw3E7@p?vef&-FF+`X-}kSg@}dL8p5ZW-r{I^5o8hpGm8@I;rO4c758 zAv78(Rko1?Z8*lJHU*&Gn;R5UBNHu@+_mBP%eU>snv(U*8&yw#k8?vh)Pvnv2( zLT=KCcER=6^WP2k-?+A7hWgIYMJ>=Qte&7)r1l8LUs?dCCoSru%X1(Jm`nu>sh@6W5HQ z-XRIll^^JioIjkxJsE-1I~vS`Zl)$St1DNv{B_;+h+hug0yB$}UHF8k%v1EN8G`+6 zR0UQ`K(BCtNob)hpl38u6#V{_s++=%U5C?60rB9T{ITS@j_KZl$3(?>m(gc$VnB+E z815yg3thxHcU&{rTvGFiQE<4--SwUXsZdWJ33x0#zL|(EE}H8-L)Nbm3JlV@(`QNb zOOSwlZ~_+UWvVxg1pLLLyM2cGx;2>1Ctz7@V56PJdNW_wUuJ}DB`Himy+43i4p(&B zgKV%8I=thLOtgPNow&QLrP#zq^8Th~H&6`4`z^=_rE^B6Sm zzJ4SK;Z5~v1{?6$&^m0O!pzloA`LJoU;Fw@697Mbfkk^0St->MFYt4ZU}QvjHNe-h z#&EPj1^(T6DaA8b+hN6gnrK`L$=ws~e#RbqrEyPs;*&#D;CX)dAf`YmSq}SPQfuuj%X_a=xhJ2<#FW!{1P;X`|18qY6z zgGK-gTA-m-ngi)%h+eiX9(zTOh6W)P*L~i1sObw!D~PZcy-!zhLKN#XjE0=A$PLQ1Lt(+Y;@B$ADILDvZ1N(RoyIzwFw=Lzfnrzq((zu(`zz3C=h@{B5C?740n1Eju^T?<9z%LC@D6c{T zxTQzbWHUi&uSNNs(zgvH-}Ry zx+FIqD}yRX{W@m`#P^;j!NffQW=}f0M*kIWFvaE1J^b${*z)(0W#93WeVyh9KrN${ zp#%tV*&kM&0p@!cR`q=_d?Og{yTnGaQ?U78eenE%pf^h%f3%8-7gV>zj+ne`zLz2c z@rHW^X5?8pB5Ttu8v&#eeK%9OUL1^k z^D?{~3JP1KX9Ovi8CV*J@!|T|g~5&s9?PR=8o;iEJJ+}KWESzC;B^GklP|@Boz7)4pTxz*6q1c7<3#4nMiw(v)a%(!zt{gW4BF2CB%_7C|lW zVMbF1>Z<^|SoWA;3GH{HJ%&ctfl52`@u+e3I|BgKHb8K52=_+wEX;)tlN5V0t!yvY zSQWD}Q{-$(!`pnA(vdhysgez8K=2fPHlw(iLf<7V_+m489xa%Qh@38N*I0jUR7!r1 zQLvI0a^)k=tThYXACSs5fhIcNhp!BU0>6Bd0Y|6_2Cv>@3Z61}8j-k5O+BS>Cz5E= zLo$s>E%SbNxjGzNT5PqsvWE(HHBqFPZU&}@c^=nn5i;K(sl6UO7xAFq9#dt2yarUo znBv7pS;IkMuD%9*K4m99;4gk+hwZi9)EB~jmZqmIix@#5dOS7 z_Czhz#0+m#Wgb0+h3o-Y)H8x-kh0fcs;(EhNvWCg_}5+HdV7q2q9Z`{9I>sUFQXsm zZl7RVWnBy;-Mp&h+E#TjIr2CWNtERyk2Qq?vLb4XUcU+n1QI58kYIDQ7FL1}ISuzZ zp?Nl)Z!*VOm$@uqAYhkLoIf2A9M?ivz+?Nf{fM$F)Ym4=%~$-$KOL>7qpL zHS*O<`;@Q9C1tLMzB}|BXFTM+>twtieB{6~*MerKCrX)?l@(z{*U(KrsJ%+c7TDW* zG=Jrq*ygXW39mVPN;x{H{|SuKbon-=DZs9{pXT5Lp6f@9qJXw4;N=V0AW?@siUFZr zn#qxSjKw$2ME3C9DOUJq6{hO|kP|nBQ-rDPgf=uTxx7_+R>E}^3qJEB#hAZYV_?I}1W7~YLbwaaLGiXG(2bN4F z3&O+2qksn{qv0UWIu1rKo`+pC|2_9>I9r{ecp2g;r&Qt8%NZO)9oe7W>Q6MJ&p&ba~GmDY; z^?eXgv95sg6}vFp!TBCE34SB=%79Gj@!@#~i`ZV~z6osf#yr|*r&&`Y*xQ(ML=xc0 z=nv1?JUko7_OjWvznOR;ds`jc^1Dx4PRf}#n21WX z5W{-{Aang}2FZ>Dvm*~)FZx8j;WMxB8P#gxCv47XU(+><5-A z=p1V1!S?f!$dTvPx>8;N2OaG&vX}=!aqV^3Xnx|OSSgmOg}hGyXSF=|V;Z+2{Rf(m zS%7Fn^J81&s-f_mzoX;&+Cab7`PkddP(v(%&N*CpxA-Wde_dhP)}K`M&FW0Cojt~U zW-?wuuqHBCxvuQ9DcqJ?O`37<5gfOLDJS8H--n#x?1aGcXqlS5nRrH6w~P zQ(VTF*$$newQNYYV^`qNJWX|6fxCFz(G|0_Vs9xh#XQV%<2vR#<9cha1jojd(Mtqt z;xy~%sdY#6^yBY6cJ;p7&sq&7l~}WQCXtw;LFU25Na08POrwe0+s9k{BG{rw_U<)i zA~=d(5VP~b-epSZN3BsApZg<_q^x0hGv|7G_Qe-0aCy+kx3_6<( zbt3VuNTRIy_BxuZPpm2_mUxbU7b#8+1?M~tw8>=Qu8>^1Jr**TcCxC@zQT&=FGLs3 zr;TePhS!Fmi0Tehj*VtC9mFu8C1o0S-Z3;!aR{Vu9v?XtdXDoaxCx-VSIBl~k%;Ys zLBGZt6T1TE+Vm^oAzmP8W`{Z46lv1NrT<@FO+!7+##g}ZD26!ubZE^_#_pXHYpWnMg=@0Q`4vGjczc`kj26tx+%h&TxU}m0XE0IXYa9VLwzBz+ zZdrIZ(-BDgb3OM#CyLm>e0&BO>J+E}7g^JeCP5gFOsqBwP2OEWbiU9YB1#V(ywbR< zO=)FMx4Rr-i;9)bRG`<5P)IWOJ`oPYWrz1UgLxnG!qen!9Nz5YsQbKb8A<}yZBzeZGS1~Bp@((5;=8zEH2myr1_|n z`FKQV^JE_AnRW;(P28q)%J)w-v(!_$^{3?V54&bhIFbt6U7Lm8JC^^J*zntSxC?um z{?mFQfx4y^S@E~=w{hZzEyRD|J|;o-58Tc^su@7`)>vc0c_M=O5Ga1cP-PJbe=zsI zW9aXTgda!?6i+f5ucP1h2kv?A@fq9({vq6M)`_BpiqxqBzmi}(?8;l+!BD^4dj1u0 zGra2OrokG>K>|zo!;;rSNkogXz0CkOu$y#)-1!V|qKS9@kib5Li~SrRK}Y0~K0*3naZxL%8i2=`NjHg-K30JI9&~8P zpL%lUZdTh;5UVi$)R;WJH9)MB@W^tou3b*^k?xagu==GO*diNq z6^H~Et`rJP`P~E1fA7kd1y+Y-W^KiZjSCblpK?@AYtNIRsjv}-hH=hooL!3E7wF%Jo6c7cUFL~`@MZR_bOg7pUQu+``^ z*h0xmJWX}HWS|q`D*AF*^}!6J(yPt?E4X+*Y$&Nrav@Dc7Rc&iR>xLwEzg3WE80v2 zBR((#AMm~;+C@{TK(^gf3&}hRyj3rRg|4_`J5 zFz`};k{bgTC@|^!p;zUd*(S)f)nFgV+EOlrig&Tb<0R) z;lYaU!o6de%A~Rzu(0?`K*x!(`v`R2{VV82Fcfc!3OcdKcMXp^Pf`L2SL>**kpX(5>R>AdeWBYP5!TpJL8>_s6 zMYdd0RKQyiSEz;9)11$M3S@?u)gr|q_p+u=FJ;mjVe>52mELs7wn%Uy6@9OCwHwHi z043RrSj){14r(F(nnLPtn2}(dMj?%-xa=k1rJ5Ct2b)Q>ldhH{{eqjyp#HF_7TqVK z$j8y__Y1sdXyvYVKHM72|4E_mbOuVM9`n;GD9*}m!S95LAKGDUZ0@8qRD)7mS#3S$ z@UqEmh`$-B1s(>BxCG*V*5e|K7{3xsSB3!=anvF!V5BKHD!+iH0;BN1&$^hxJ-(L` zJhYgYbny-Bz-4p>mUE~uMinBkFenbw&9DtVY&6^4_O}-DoiHOug6ZUB*0)f4?197^ zEpp}GfPTIFS{s62(P-Jbu#iIN&h2mM4M=Tz~A z^)YWZB}vJGkroFHk`dDj@@0RU5i!GvB7TO@UsXv!{2`#ExCPO(7}5?zDrW$m1%z`< zu?Hxa!Hvl#kUhx4z*W8@uWZ|16`9~eudA+{dTY2!$Qn!I9`~S7Ld6~+gPO{fwZf-% zMuMGDxkF8cVyy&jy@)w%2h{sHR+qCbAAwg`0;a=3$la`lpX~mBhMmqSDMBRsgxdhV zSHhz_2;Rf1r>E=Y+5p3`3x2MG+@CIsJvb&Z`mo>o(ygP8B)?5K9gO5Y?7^3LivG}E zI%qZ?Oyr6?g2bT=xu7p?2cU|glBR{+YjN=5r99B2-QZ7UI1+Ztlh3+ADshAhZ!evl z3A(|T;e8!w6aiGEvJR=_EPjM0&fL9_End>)a+6HF`+JWCAZb;ck+&S6e6Vlx=MX-X4%bKR^uN6`;Yub z)Um=qNVULlvN;36-V=L#%K-QSZ2zzmMZBHpGNqq@&a<4w>(}Yk%G57;tvn@i*umrK z+{#A6&(FQMMZdt7E+a?dT|_)!z)*}58{1*iiv)P!INuFY)#;l=Zu{E5fGBI;%)3{ihJkALh_q+q^#v0~g6`C{$ zetn_qHop;*@xFTw-QQi}4$R*S2#%sOjVFmH#Bmqj8?E|F*|o^Z_hsNq5ARP14mu`V zcqf}pM+;n|U4pttuSv;!!F;oFc~f2`P=vxwlFsW(}hIvy$F8Xt^M=inP z7+`Io3Q#9kTw==>2_UCriTSd|INEc{{2(DdWo%Pg;b3czr3J7>S8`N*V@wWs+0s8s z(^Q^L`u-8#sAAYvh*&CcmrmAvGe~s*m0D!gaKB}v`Tc-gBA42%jtUBQ*X6wt`0k=PwKtPk-D+zz|oQOPzW?BLZ|2F&V{PDuQ*jS@{1K+$!K#+Fdfo8 zRoZL^vH{KV-e+nPw<7pH(CiDLqhjRXwNnrzM#+MZwo2-Q2>N{|C?C$FjlV`bb`e!> zk&?-H8FH_kD)IeOY|BD;Nu96_)X($W38?KJ;MtNq%n#QCrN#(c?^|u+3IdaE;!fxI zxgUCDxLfkhS0k-k4sFoHSgnA+G%$HCcdc_WIb}4IJ^&098@A}A8I9m@VtV*3a8eg8 zpsk_z4@d)fx#~Wsx#s3G>X{Lw8Yw(!7d-%Gu(Y750qkKh8u?b^quazl{^cVCzHm^) zx(*R~2>uepGNbXbZSd%ujd+ugN8v96a$i8xOBlWBojw4kR6X256>w)(IrR1qAEN)K zj2x;Z%cyA~R&5TKz&7UI#q3U^mb>eIK~0Wo%spz|a3hrBp}|z##K4k7vLCc|4?++H zl|DT(as9nP;+|xo$qZ-jPUkO`CuY}gBY2kd9a`c1<9qP3o%`6LZVsAl!4G=SDY?F18U5-VsE^g~qZ~=^_Jj-c~K7%RBIEW%urY zIr4X9XyosRj<13cOq&C7j25&u&Ot?ZhC_%&lMOi5zK1VS;tOTOD(wM1c z;i=BgV0t!+Sb8ST|4IN+{&X+KgH+T~^Gru_-_Yx9$h!h1Swi8Ot(Js&_CwANuuN09 zZENxPXHy^-^l>%G9p^lkrg??Hg|=LTWwUWvQWm@)vHZkgC!)x`(MrflBWw=Hf(5fh zy+&sjXd!==f3%K}q1=vamL??ORMR=5puKB}Y^-Z0+%?;T_k%>ju+XLRtTYP`>-P`@ zt8DrS^&*q|*F@s^q-6`4;*Z$rL-*!z&ci8iYJ!^BI}8&HeC@5)ZG3PzJ5Ac zR3mF6_E+pZ(9-`et_VCL0_AA02xR)^r_Z9d-rUt`njp7n@bJM!2rS~?%oPbAuq^To zcH*z0fFNR<@}lNsLdi3WYm1d@ICmWuFKKO;DSl-IMU9jZSbM9d7rc?Od1U6LWp^Wt z4FRG0;c&VlR9p;9+(7q3yd>{ulPKfEg5sZd&n?JwRkwGI(cKD4+rRy0t(|kn%A97z#?cIs9zj^eha+nqVQ@5+ZNzIBLT;gG!|@$FlbT<^vE{;9v8oH2*HqmmCTD9S z?0hc~qJNil-Yn`hpfL*BfaTg%HF&|BHpCn^TJoYv6!c!`3y00$oJD=VV69Fx;4xsLxgB`#&_~+EdF}CKT2QL$iX?7;*Yv)cBaf?C+-Gft)Kd!yb?}Zw z6b6OL`6gAMYrG*}&8E9s6601hkeIjrHDe)rFKNX3y#vj|{E9xHqwVEZoQEfSdluDf zk<&b?8@oN&shg`oHD29VKdYq!n|*lJCDO1#PA)d;o8D;vrm$iSehqlwjBU8Z&rR%>`EfV(#Wr%IKO(V z&a7z<0p&Xq#@{m=1N5QM=&scN1DohoP^R%RzsHK^9{*K!J_>@V>@0QU9cb(Z);oN{ z0yn&S`j0<+^(o7WC-k8}y@>7sYxaN{M+L0YV^-e64(6+G3GU==>Rh;eG^?sw=Yr^fp+4yep}=9}wGPoH6sHXRbLD2|_`_W7 z#OH7Bok#OJjHneiLrj+BjeGgg!F)MDSp|`%_2nSjZim957T)=e6wuQ9)&94LnfHK5=y-y~5{Qdvvp}?HfP_PdsScbj=ZFD=__w8CD0W z@Tf1h?KDA}tNstE+jPbSa;&2%aej0kpXwZW$}`%CEs!6Evsj1Vcr*tgOO4;lIjye` zA~EnDjjBxpU{a1pGu@Ed7HSj_ZHMm>A$|Z7*CG5iSANd^(h7atIzjMx=;4xnkoq+j zvgGc4ou}A!k)t7_n&w zX5^vLfR?d}_$-d=bWeZEs?CkEv_4%e%6*v!V$d9@x{Q|H_n^=_V4^0h)BUiZUrTr3PvgzCj$j)t;(cQupuWpzP zF|)?>?TR%YDGv2EB|*_##(sydvz*@=OT3V_c|=ozBAV0vk(Tdw2XqpnM&ugc=yr#t zRFgu$Uv<;Ez^K(_h)%CG5V9`K$Ir2v<5aH?%j1iIYdSkm^i)pKJ5A)LPI$BE7mV3F z&PtkvY^BF%0~p|Q?!=nlE7>IHpYWKN6n-$&JtUvt9aaX{$k<_ZA+Q5|I!C@!)byaM z@0GIMUh}@Ug|YfixoQvu3Qx^JH>Q933*-e55HixnD|Qft@eA$33ZDAL_~FB|SsB}) z%4mt7>#TqqsK-%kl$p8Ou&wHv z)(T!Slaz9?e1o zDggJFt5Ta@!K?&Uqpqejr&NR4(9CeLYD>0bx|^c170Y8a zEsUao#`a7+vibY$IQ6fomtQV|&2?2Ce;pdFYLB^i5a`qU-O>9Yig#DQyZlPJeF#)7 zx0@jsNl=m6l<=;AW+>metfRKn!2fo#MRAVSTY|x-jC61-HsbG9nbD4dv(ZtfT`Eq1 z11e=kmqtshcI2l>;Xl1P;Ru$3qP5pj*Xl^H1%P;{M%2@|VVC9c_VDPj{`1haGR#3L!1j>% z1zrD|#?3eJ{g7u5Ssnj@;froRzha5a-}aG2VmYqF;ywYy_N+(PvM((YN<`6Jsr%HK z!?-<0&p;iaJVAxlls#_vdk_PD9Bq%ao8~CQSM42OYy$7{@-OnnLdcp6dI3D-&DB3g zt!a=An0*q(`|uV=;9q)Ie}&p=^blB?98o;&^EC425)qy~I6=l~7Kf2H*B7KLxfu6P zpdtDe<3T3Zk&v?&-r^P<29XoZWb@Bg9`7JhwNgtV3pn8MuY@`_N}ZD%>oURwT#@|sXET3I$Frw?vbQ)uCEeh!Lt?rHt!vbTQ6F_ zO5a%)x;pGl`c5E=fXs{^3y!YFHiY;Sz!TYojy{Ll%^=lZvnXsBqTYz;fM`uP!Lm!X z+E94(#PaLKuBv^_LR!vW7{Y#J?j*(S`Qh0=OAdEduWLv+<8tt7+m6>&C0kStBPBat zUw{q@Z3Ao0T^UNYDzhe!aV3~ovN<%|YBy8)C~M^!@J@ZX$W=}hB*&gz+cN^Rqi^M;C5uI94)J*0Qe2cyqVhg$9 zhM?=7%=oqy?vQYw^~4o7eAadikcbHhO_)pX`zbF|xormcO-hnv9ACEaR&&BP%b8<8 z>TLW|xncQW46@?bq9e5NL_|Ht@NvFMQWyj`8r-m(Tf-~huW}HCiA-t0oYQSjS-o@m zaKLc(iUKVp9SSz<*yD}EU?iqs*Bs|GnA)}t#@-;@$mV^EkI8{!jWe>S zYnV0F!Jyl*(KKTbd)6M)M`Xp2gCImr57u-ZOQ0Ok%r|t#pj_#5yV&(@N56v;Y)pUL z|9J{wQLhF^t3yy?k%cVkPWcWwc2ak{U>Q&S0_20Jrg>krUG~S8N79N{H|H#V!k{N= z=?F*a=luqSrBWd7CJ#EK!_`8yM^Y<~vgCql!cREFMP@27qlsQXi!%s&B}u$Gy3(=i zCNNxHElir~6v|~Zc#qkCRhkl|dGnO`U?Fr*b;2KiXRh+$P7h|)eU?_$LM|^Jaknkn z+>k1&GUEV|`r$g~4}W2nfw@4Y9Q!N$lX^Ml+J^zjh2PX7cAmCs-_8pCXNvXhd`$BMW1TY>mg?YaueLgd>w&-_uXwIEInvbguelT*H%ahwhI?TKLCx z@WM?{d?U-y&|k>t;K=0R=+2*eK8St`{bR%C)BiEBvbessxIQa-&RbXl5bsw)R-M6y zzABb3U%etQLLiUpgWRIyVtn&LIH~020j}ohmf-07M2N=H<*92^@Q@mhHAzy(2Qa1L zq=((rX5*8HX9W~rqn82b$QG@kH@L%SeS`7XP5X$QJjTLxLTb8R(D~}(s#_w}Ch$z| zb&RSBAn)cOo-Sh__7Y-9HC+MiVbKd2RUt6aJVFw`2Pmi~BoU{wcp%Z!4}+T}_MtIl z&O+vJJ(lL7_0oO`h;KK+3mOf<<<&uG2fy@HR6jnq#@hFQ!1DeBB0zo1S3kjn^8prf z?DKtp|0Dmg-tZ?9@k0OHA0VC(5}o;vULwh7odsQy@Mr;1%PHUn_Uq#rJEwn9^9&hFeAuF|X7NPa=X)4eBVxs`#mGl+ zZ!vRn9;3=Na@U&yNq~9qbRB@J14+^56ydI1TK=^HC?=$E2b?KoaKP3JJ1nA!lVu+7 zkd0oww>yb28?Vgbg|^HyCJm5ko0meSqozjn(4b^Bm1Yb|&Z(5Rs7lt|1;kI-Z~42U zU%|67=(Z^uwqHym{*V5?G)2sT1vy}V=fn7jUeTNV!d3ZepGqxfrE%9P#?#Wc19teH zE*nB(rxU`hJVr#8$Pn5VSRJX{fiT=>#g_ihoRW{<-`tA)ne@Kh`{pc&=ps@#y;}r< zQ0Iu(>$#%XUdiV&+pl+md+>XQWLtkEf2ml%Abj!@@yW{CN`TXbjT$H#9t0z+LS6(V z<4WWB34$3ddPU=1h0v!if8et`eq(oZ-U>3U;qezr`gOC0%732F2cy@C-peM{28&z3 z?3G=CY6&MV4OBU|J66|9cBGm${4Of^D+Ml2BGo|-f47oCqP+Kp3|6B6$p)jr6zio> zj6mS+l1O9x1qhBG3W#=UUD{yFY|K&NbM*Cr2&kCCU7LvO?ux!ZG}W*Aj|!)2g5Qr{ zjJP&KC9tW)y4?E2s8wNMl>VuO%*l?~?4`V>U*Idw>}QKMn7`CU{EOlJ+)$>*Zl!oC z+W=_5Hr;ts3(39&ru}E2;y89@46e5faV;-av02(OvgOGDiCu_%Z+Ylx}@RWBLM_-2wScILy{IrmL2f0lVxbE|NgSP)^Fehj1 zun(|YJZSO1!E&ul1}y`A6P$;0WBv8ZKZpTEHjglX2VVo0@jRq(I01V?@f(0j3}uNt#+;_CFD9@o>j-Gd8Ug>kxIHWpBDcd zSz51Kax5~3U@pYpMj{`LC}4QdwtvOkk4rzD6X}}#cmaDi5wL4T)}#V-yybBGBa30w z)=eTO@Zd}DkDN>6CLV{qsLq_M#;oIRJXK>xKYimblSatX5=?;ybVOt);3rOKkWx+g&CF${}tMf5yXherb`SaIecAs+82T6Q^Q}YNd zN<#~|{dlA`mHR6W$9D9BQT*N_Nfa{|1~spLy^Lt-_(Y3powesaaOaHs&LwBsdv84^ zkB9hce+t6al6r00P0z3`n#HalSk&b zJiKC|b`v_hU3G-QqmPsf2vGzpmJL5bDE{J7avK^2gn{;;>bUmEz4WFRh+uq4zDxal zeR9#!-)gq>ImXpv$6&GysyX+ib5#mB-a}l_Pt&Fx3uQ+2m!QDUEG&Ypw3tNcqyRq_ zQ`$eBWA<9U>#J;$7%K^h9sKj*R&r$10BhS`-;bCuU{j)Wi z#$~2(ntUN=nQZQ&TCxS%CM!>a>gWcm^yB3|wM(CVa9X_i%QIkoO6bR6%!$}1fnzM& z#ne@n6#wTJJXQt$bXqCkbgi~!w&}f~^wi2v5O1pwc@Uxi8u$$pwTyFcb^s8Kf=j}& z|vKUU!iHU%-Qw8%>%`jXB|Q1sd{|MTY~)&4r;ZbpkBZO;*j$Kb2yKIA_T?S zxckDDi;Rvs)S_5*g(h!jDtC2ae3X>@+1amq&YJiag2p6Cg%(weyc-faq;R=@GkGWO z37oQ^4GN(QH+7&lloiK!+4hRAhv|Usyfp2zw(X=gnO1#CT&eUBXak>R#s7F|UiWYSHmdf1Ma+cl5TpiI0M|%Ncuz1l+%=-N| zfcXmUoJ2o@n%-p$m;(-5*=U%tU(jPDkY*M2JlG5`E9x|1DXOZc=kFH zj&pb$rk>1E0g6!8H3$laYq5ze&Y=F<*j<#RNR~x3pIz~pL-ye=|KW1mYtkjK#)P(= z=v*J}#Y_atX_$I~VITCHom;a`g8f7K;BuibN|adcA9<@Kcz87tg$kqckE1vZ=msg6 zst@rVVMh6zc%_^u108483EN5f$wdTfwz*sQ`O&fR%Rj6$ia5K!KhrV^AuwXOtvhO+ z={o7?Ma_(DM2b&E?ksa2Q=z9u)`P4IYb2s1nQb?he6VPapBA*r8<_HMSTV3 zMmTMe`rd=0>(Bh2EKHONZafxx^Fd`j95An>N=XQteGe{F+q4+8xfU}D65$-N90S4K zCDc{Ql%q|SDj)lWtfxMA=H&)j2ul>0N9T-v<*j~w=7?)C8k6m~9E8DCE_19-)@{w< zo*yCK%y}4kuAL6Gj6E8^{djNTkU5W;ydw6k!161_3e>a>wC(vOzXAD>?6`fp%mwD8 z^Z@7=yJ^qXLVP#NGT_Y@@UMY9ss#*%vtAKYAuqt=WpP>zb)5qtp>pXNIRRoauZ*F! zeGCmT(s(f)(_hXXy}y-AkIc40fALsLIFRw&;0(;?^S8VPRh zB2Y+4Mt_Qg^4VkOIX9zI{R`RzG2v-mpsukwSttfo-)NB3*4h#^lXp%G)@|Ea&a)yU zZcQ|QF=%2Ygb!ObcFI*1z!NW_#wb&QJmO{*QL9cZ)*k z{MGh6f9SoVLvue;b-_&{=d2QxYp`rl7&$jxGH?(o>l_uM&dE?br7!Z*LEUdl_A2Tc z2Y+*%UnDjFTXoQueuJEpA2^IkDU^+!C+o`=(I1jErNf6cECr5+Q1flO4TrGMeU7qD z`!%;aT0GgjJn<0*+K30HwN}pi%Fq3?8C9 z*-V6mN5J9w^V^gu+4455dqOy=FdiO-eSorW`KTDS$VbgB4@e~)liKyGH>Sd0;FBI! zWN%{j1>6tHR=N0ss;waCcQ{@~-6Xe?r{cFgs5(zKM6T zydToCsC;Bd*ZE}m9xphvhg7p{@FMhrrLyXJek-SJ-}m#M5>muN;p0=^(cuL}Otw0- zghX9E2A7E(whsl3)rU8@=Z~iBGkBlUMzVg`g0Xe>?aA~8-$q+H@!b1NAqY=D7WTYO z<4$W@o`c02#G8IWyxVG5#9Ay&cao!wX0!<|h4pwrXz^@DXl20I<_80`eky!9*QO8* zmN{a5)~!`mabs(j!A==ds!(_@pIt#7k637_RmkmqgY%{?SAM^~`}enJJ-(L{_w_`X z#QY}woVGI~@iga&$!8I${%8#n_3Y!xoP#Pw)3w*gu?b5K60x*L(6BM#%zb;Q0oumn zNv+a%9;h+3XRrbH$FOM(okv&N*7&g2TT8s~%J>nYKoSj8e%?~P=j17F&jjQ(aR(@F zI$Xp+kwcM@*bbtL$0a+GorZU`Ky0^kvf{~n&8NY`$C8D$VTv=Bcehrp5ehvaGp~`S z>&F8e%n2I)Kx}*uIF-D$$1Nxo6YyDwK9V!C=`}XePw+hBY zJmZNq+X4D(`Z?#ZcMxI1pdmrrqVCcUeaQnuDRQ781HFN_^;W%~0X3v3SGa%^Uw>ms z%EGqUjyY|-ao6Mls2Y9NoU{W|orL^(fh#_XciH0plz4xJQ_rzx@3tEfA4j;2mKLR;H-=>#l=pBz##Cw*)mZWJ!rq z9)Y3l#S&P^&D(=Ly584K->o!$^XFb@^$>SDT`OjyB{+8mj*mLWIb3ck6dr_T2X#kY zjUB&=5GS7wjo0KBw*XkUt66$Ytv8Ukj#h5+n$7m%*Ju9|g{XJMbCyuk4&%?RxqaXILr0H9!N;q)LiLHndQ6(WUUuCgl=vEIkbO2fmYGH zkt>1sUCnx4Lr&lb{&ue6{kvsIG@N;>CBeq6*cdw9Pk5IteIrda$LG!f= zKw`|fymc19?wK!b5^P}oV@%=X-AOw3lh9d}7*fW{sz0?LbRNxLfPKwEdq)HOPRF+a zVfO;&vQ|RRGhx$v|KWo;gzS*Ydn=(fazxl$9U$iGmz#nFVWziQ$ksqrq6E_ z;_|Lj83yp=?GbN;@izY6n?)zOFD@ln7druWAb^^n3#fH54jEyM>`PmD&YovbJJysV zUc&}9qhNaEN)IxVk<#J_zE>^wFdi!wSQ8aim{gdwG!0Z+nb(xQCT*4H1v6c45Z^Nn z@KST|=2Z^}Z&I790k?B{17G&l^ZA=eFY%fEynwAVKa~DiK01ji7~@%>^pivS zVasY=3{UgM0jk>Xx2A&Kv8Lt4Rlu>WpbNx2FS~Qvf~=y?dv&v zFB}@wsjx<&STB(kn42u?XRt8A@SJXZlfExNmTy|6rl)6Yfl3<>4I0Frm=oGDum6lZ zeE$xJ5lhZ+;y9o*Z)_bkgvs0jn3*-&7z_z$xQmZ(#oMswZH4|Brg?5l%uUs}I4#o` zgdZpRdkDtRQ_ON3&R02rk4S=KHg z$WzHIQ-H{XHG0@#Wu(}kJFM0s0?Z8yr z7v@>21QchLxxa%Zb0-vg?)O~>idDtoeoqk~a@N@~-EgTL#e3}@%{72;RkSZ>X%VRBL;-pwNPwMvR)LI{L+}jG`k_0{V%Nbf?s`amL^C1z zNlc)6?0||=Bto1}aYsQ(FE&7g`NGTg8v$ydkc9l z7ZQ4cM}45I%hMBhKeD))C#Kosw6gA2odjYKXcVGI;16xhT001@!W78#Q)HLsF7rW~ z;`pK3#Vfy{h3Fta*JAOd5?|ndadwF5%*H%s_5+{I2XYrUNM+G0?|8GgpCo9&zIuL) zReQ9SWTF1d1k0wM^m8;aD)kO@yl5?|BR4H~cWw}G_6(R8 z52@!hz@WF50b|I6-1xmojyo#>?khptEp}XHsba047+1 zT1VTIMu3I4pm+3GD$NjRhD!}(T3qU*c_z=uP*F^k*)!#8@a zpslm3(gd}Kw&N-6{dNt^YXWg0?{Ko9W;@I1eMYyoC_nD>G?MT5y#jQ3y2TMmxt=mD zUlxJ4@`+Syp$z3;26+SW2=Mt>uWMjRrNdc$E;o*A>#|DrsPa8jv3&Fj^v@^QrCLAZ z&Eza>T9td<`$3bWxBwhySsgnMXv|qfatvT^6oVX(_GkeW>xfX6Kls46PXo#u+na>4 z&JdCGR}J9!i#!I4Vo=T|G9j`;Q5&eefQdZ`p zEM;TV_4jXN8#=H~8t!0h$fZIZihmkL5FD>e!uxkfTbR~K!--RZZbL7GcYB9{SKNf8 zjSU_HagzA$A2wkwp$pv)L0QVP=(|Zg29zU?1+8LL@j)pIb@9(ZR zG*kR^4bmXlP}pCo~yo zQ!XjuCm``)n=f1B^J<(G18_^|ITR=_Zqoz&I2ynr`SfPOZ|(R8Nh5FBSgq|uEsT!v z{$S@55^#S*(&CcEnzxw)93NXD-n2=G6T}?ve1nZ_lTX-!e0TFr-DM{2bR23MSR|kR z3780Y@~zQrPXur|sugrxUQT~mT{;k`K2X#C0C;y|9JH7x7D2!)ZQNtAK44-JA#|8W z1WUybKirVK15VrBuR23OM6QE$SI|mp?n7Hvo>hJ-KlW3A{DX4Mf2}hb!xq0d>CzhU zrNGS2#FiP@{LRjrvEBzB=+~8-`G4~oj<8S`gyjiyLl$g70-6~f1blPTDiRwq>Ut&M z2f$-kfc~hOw2)6`c<5nup7QV?jU5>X9QX3d89IezSe7VI8BD6D8T|yXf$9g80#aSY zMNBqEGs7Pe3*0Ypd8bX~b90`Id3@}WQap(kvQCTu7|kwxsx|vCeq9HsXc##*cycPO z9#WxoM6JtO!ZyUut}+%Vqvn0kL%qCVA*yC03M47Ro8+1E&i@)cgt@dniW|AR!6TOX zah-oc>$hoLRzD4aVoYXL3C#inJ_kXh<#dx(lXlR;PgZL}=_GZE1LI~V8G)jE1Mo^A zt!G3~Q#ft(+@KVy{|hcSZJ_!Q%qrRpy^~UVn}JE}nE~92JTo#r2b0@u8_BERp`_Sj zp~p3VAEDmKv&-rakPjtCoU}%*A7i6uArgSs+0~L}Cncc=rofU7W0Amc1ER+!LDgnH$E%#x*1iAhNX@NcTnlm_ z<_M=Lo0hQpwbY+$a=!1CgBvYjw}g(HT@iqiLqY#IPx%!V)i&v_Ky}6-tLbY#uire@ zkNBA_UgxSTUQil4Am)`o>A}nHPWq51ZMxHJk;V!a%YU=6h-cK)Uar$9;b@=OwN?5s zFk=ET)G&H8R~Bfwv9p2lG0xjrfwYZy%rQ(RXSyq8sGr~TL9qOa&u%w>j{i}LG2;;l z-%u3sgGkxY2SDl!Md3a3xB!=e)b0#v{1=IN7lOl$U*Nfl>|8IA`!Z3vfHfqSt>IcH zlA65OFNVQ6pCLjh<&vnyu#EtXtYH}zfA0rT>wtb}3MfL7MAkul76!shTVKZ{5D-H7 zRJNY-FV;6SiB(fM;11l-kGVc;p1%M&>N*x{tn%KtOzx}0Ihzh2Vpb>f{{(Co6~cch zkKa~H?=L4C_A)I#RyWu)728e+nEfC#Y@ES}{Y5ToquqESAfjL>VvpzgxdMR$W0IINHA^ssPFJ9ge}S=2iS zxXD#1j8s=FaopnYW3cI6GiWN(gf2OfuZr1Qfy^H;=I`3Vis{)opu$*?n%TZyYjE=x8oKrt zfXn9+)n(tb{@%Yh0y*`;9AL$uSm6%ds(BO8b>~2$XafwjYFO|QcJ9 z;l%WYP|B42(F4EiZm6Qx;~NsGr^)xO`8(gza|j@69px8kRqkCD!iI*(yFmd#k)H5~ z4>)NgvAk={Bv|aLNy9khS_XF@Hl697^!2E@`;+!1x3K-tY%U*cM(z=^UqUpb!PEuD zxM!pC0cEV{UC(x40t}GFuaokwanJ@{q6hVZouMUlCz4r>*$NvXV|rB8%E2KRx-XwB zQ@NO$i56F-@l8AA<%y$5bcG)j#T?CnjN>XW_n!53DFW@$W3jS`W*{qC#^7>Q;vl`E5OMDKsa@ zIAt{qYbKPreFB%F$O6S_PpPQY24+FnDXCIePnDB3$edZ&-zSio${RieTFB$?eAP+$ z$kxmwQ101N4VW8R>N*$RSti+fw?bSjhd`+YQUbgXuy6~z*G*jfx zBIm%bBNbvqGZo#80aU*cB-8AV_GqQID?V|pyy&Mad*Lx?l z+dPPq-EpQixbGDsk`p5hhwL1cfgHg8r;AI^6~RC1M!e6G)`9ff87af&{dYPc{Sef^ zwDXC4kqXTLw2>X_C8KPqqfq&DjMT3UgnmcTmM1N!EI?)JCC!q31g(3libU@cS{=XU zEOO z#DDlKVo#ZZ@*{#v>Q(Xn1xrA|FNM~^v3Zn`m;5c81Rd#HkkDkTmS53l+t_wtp!zW6 z%`>DR>!O)Azz*e#@)wpNg0!07-)aff>lS*9t&7h|4R>ds+SN&}9d&yXY;@9 zf3(%S!Xim6p(i^;z8`j+msGQLOmfuPZHFk70_kdfk8`RjE4oQ;wvG}g#s+#d`T`x$ zMsG%Uk1s2nZ(rZuA-xwgjis^zgr$yaEnoQo%u0n?!e2RH5?h8_clY!>&NE&3rldj| zo+Fx->v-1j>#)@SenOaDkHyFqU>7wPmTMNKSAos3H;vtF4mI)7*Hn1?XyCrz1w^2y->V0KiL7jXjT+A)B6?RfqtaxrF1|#p@C+^dptD z#+9x4*Z*~FdUaTUcTGZLV`NSH1V`Nr0i=9;4_fkq^C0zBE~GQnWU(@~d^;#N9Oz8q zlJ$D&IkUaSv#l`u^O*X2;3?eg{QwRJ-4%d5>)8)t9gB^z>H}0_#^_kU`e#47D+R2r zQbrDB&*b_STDww)MIi|j?>Fj1HDgFoR-dB-lNhF~BgmqZma3bvr6_tA*mW}vAaPoK z+X(XInk#%FJFLJWVS9~E8la9-tc;(94q;N)Ug3e(E|8Z5yF*zmg5)p}qaHb&8#;u6aCD!+dhrH(`9Cxv$GZwHHGt@96% zRqfXxt9EjWn9I0LL1@Bi|BwLg*-kZ=0QZBwD}3rBqmm2YS~&o#%0ZWCu@PL}ZfJQu zi2W1LrKkroRh)x@1~zPyY%gp34fh!#nTl&(+}Thm-uA04(1W~ zohkkcmq9*^^473<7dW6K7;PQ?h`K2zYD6z702nOjVo;x#3+~KdOY=*vn^dG2Q0BhnrT)`P!Y(I8HunDb}f_o7kG>6%<_gf zD6ZPV6}z~l58sATlFu220J8P>N{hwu>@UNIyDB~YCVTvaw=KpfGx`Z&EN6ae9~Sdg zcZSlG;RoK|g1a6jc<=LO`!(4v2XDKP;5r;LT*W(Io$z}|0BIpS{tWBccclp`xSBsh zp&j);V-1&gAEFh%g`Ai5=N^dG9(;X#a=Wfgw=b7^sLX~hKpqkb6->V9lvc7V<>pl25zDqDpDo)5x?(xY7v^43x8@s4|p3s5g$ z{w3B}>Monx?_i42db~4z^CXip`ixaT(sU>H7n++v;yQq!jgI({!d0>=! zHxhr_3F>?v?~cE;ADeG?Boz|~XRzZb37e&0q-+^i;ypB9xj2O@>A|EckX)9uZi6)x zTSlG*?i*>*FF&mJ#sY`&=kAoIz{H;H<7VF_%fW5QqcfO|LfBZPF%2lx-`~pOUSG0L z9azczc7dij0ssQR>$w0u2aG(GHcO;}D^k0CE=hZtoypk7GH$nN7C@njK;}S0Hh+G_ zq81>=?nk8eXl_zmrBKwr8B0D~LO*i)E@PVZIM_`v63P&%}LZLIMzqeB3NH%;%JUwrey&}Qb$gHRP`@4IP#i}BU2txW{~?E z6TRiFIuwyn8jZvM#xR24PWJ}2mw?0Cmt23FB+&IYf<5rDKqh9}Z#cSL{pL8A_T7tM zSy$v#BARZY(RrI_CJPbanem=0x{@>xqSmLny!`GVAxzLcH;${7a*Y?*nZeMt6LLA#EHEaK9{+b$xr*Je(OMl5rU63vB)>b&!+2 zL@i^Xe9u(O$2Rr({Au65gC``2UaCBqzL|_x@64y9JD>rCwDP<;tv8uHe~7KTnY3#< zK2YBUzU`oVgd2VZy4s+%D4YCw@EXx88qU>wm=fMh>k>@K@=4CkqBdFP&*IptpI-0d zayv(yJxG|>x=xok9EChp49H=j^jkmC^t`BbUEh9%Mb%Mf(fS)@5o3ejn@YPQm>KYp zcH?A{78`DW6B<3dyB9ctfVG711*)4gmUjnFp3?Q>8n`G^15*A)?5Ap3))cO@p4VrH zS_IH1yss_1#ny&3atUeq&31z4`;GwXGTEK{^3rf^e#1pv$rE5%GHRA##U-hK6=(l~ zuV-e=Lf*pmd$HvKMcE$%=gzcqhoEMz&l|uqU(SjqTHOb5B+QO&;Cs}CV}E#?Jz`I7 zL=UjfXDvN|dQedHnrrEYMqio;6(q*(Cp9>3z~ZXzRpXBo}S1 z?tF^`9(NN$=N0RhJHRX?N#}LSKYi!%ZU^*T6@DEo`#t(T_gfq*4r^zMb=mh(wFe!Z zSNG8O_WeR3Y@;Zi(;WK<>X#CFs)M_BgtLsVvim^eYg^g+WMcZ!)t8mMlU2H`CZ~}n z)L_UfbxGJbwUe{EDs>+2h#qzTsDUsWY(G>KJEae=zw2kw*?0}Y!hPI3c?hbUPUT$D z*-6ia_}jD)Hi{}*&A$&YXi;t?fmGisd8cLXU9tI`5kQ6lSlmEOLRnG>Tinq)CeW<5 zSi9Wg~e`p+c^nxP1N+tm%77g%CdCfwJ~%P?H&{ zohSMaT^F4DPn8Qe=H^BL#qbm?j8D`T=b!O#TP)=l<2$SZ4kcN>;)DhDq(-3*W>J^4X z!GlFDHoIJi_eTT}Mgf0(Hk9C?Kw4}>S(HH`rGUTuI2aRzvPTyR_1xv;2;82eO{2Jd z?7)7LALsQxm++&e3)Ih(?fi8Rrk7F%YXyXs+W}i6iT^_MZaaAKZM$sIhcV>VttMO^ zI|oiV!}rI&t3~PdOsHA+lTU>R?25LS%K+I6Ep!t1J{CVA&`_h5K)oyK)s;${;SYG2 zEo_<&=%5ut+YEZpJOy?+kNBjKKvoMTwJ)DLP}5{zW7`P$MetnkbcjCkN(p5sR;a}e ztL`c9(YmZxbLS%BO(1IN>&Aze`3&%PL>=#f6VG4Y?Z+b}MbaYd|AeRiRtAp^6u~#O z<21h|x(1aV)y0Z5eW&%&wk*MZJIim_~91@q1Gxy7+8bON?m zKWY2x;6mS;0SX^O^2Up7-nwBn7+-UlPSE9oy8@Xli3~1Q)|5KL;69OOo??sN9;4WI zl)){K*ZmE-<9QqG#8M*PexljiENjmYMA{Q8w*|<-W0TazNW_G6Rw%sC>OD1`)-$fq^3zpmm9D3C%e`-cDL%5aNrOpJWOr?TLJ5DRYw(vsaZ=Hwk_!k(Dx?F+klq>mniC|;zRW1|RLq{Nfj}@4=h+dLFaW*P!-ToeS)nH4|$sas;%*C@^Js zoEdiDZ9WR_WrU9KKClxz!O8U>G$Ad%>$|)9chzunPvGr8mv21yd#UZ54{wnZ)AAu7 z2VG$)m%dvtq~Z10b7%b+1@xC>~`Jcl0I8S9Dds$FG^u(Jlsuy$Y;}xlk zqqh;c-}-XV)iZ7$L|%|OrSvTBZ0Dfg!yt90Jn>(R1O6a@crdr%|9?jT)8`5UVyel7XZ9eG_z+w~8-rKj*CKK@(HxIfKkE`4|`YL<>Ycz60 z?2_#notP-Z{dlL&!mcY1%cnwQq?q~N{GyPXepOA~LQ307A%m!w7cjEmGn~C*EHLuS z_HN9+0Y1}frXyB7)Cm+-6U~REC|p(c;qa`XbmLlDTT7MM{H5qo!9P}Uom0h~!ve)4 zs)s*yo#XJj?Ha#O)A2b|i@k2TM7iQ~p){gs8}uKlj9iw$zx(5c{ic=bESLLC$$6W5 z=TF_dCUWL@EYoO(D{F$nkz&gxm^c@)WFe_VPZr%~)Y*0*dheEKZdrMEhMB{SduwaT zjA8iT0zA9R!2+$&Qys#UlnHvNsX3hSMaq0Nq>t7Zw2PB{eUS!F4L{LJ6(wARL!o%% zv$9W_5=aHR!-P=X$>Y9u>S6iQo?UOdHtQOi_#D-*( zCla4RV^*JNn_FM)c*o~1d}2VrG!4c~{QH0+VOqUcBTrEq`d$VKNt#1Lyr%woGrQD_ zm0f2%Y0RK;N2U=;BhSO=kyxc;!hk5*m))^h0KRO}-$+g$zVBxX&LR z$LwbzcT4!9Ar0?{@-UjAMh2YC`@L^!^QG%k<4OZ*)6mugC`s-O==8Q_ zCMOI84KOjfLB~R4=L+!utkU>SMXjDT5~SohiI5JNSqsW~trR5; zsJ`j+P8NX2lC74gVq1_Q5wexS6;WhJ3sDlGUtW`A45LJs;XAd;wkftaSr~~}27qEA&0~^qZwfT&!MpT!!qsRBW)z8NdE0LizEr1JkS(t5ArjBW+C>aOI*bBXxE$B_-^EFNMg9Jk!Ug zx#91UMsYlZa2`S<`^la_ZFWjr$2>-aOz`i%;-SUM0Q_PY2iwwbx!#}+uB^N*rlGN2 z4SYqSm0Z2c3FeBbL)JFlFblR1*@G`?u?FCAO`FGY}#mhk|xr^5S2<3C&ba>$xCEEia0gP8xr)s11 zPxmeh+|*oQfRd0Ftz_*`jujJblkCv=6bX0>VyKHoUP)p{cjAERdFoCjTldgdn;B1s z!jMc(?qY*>bq`L&3FZlYr4Bgs$nX~%fXsYN92hQu)l{;*%p`ui++jX+SPEo(@4T5t z-ic0c(Yu?tc%y@bSK)!3AmHtUwYs;U7+j+QBa1}uuQ7=;p2oe)nA#ilxjrKZGZ`gX z$pQ1LWXnqkw>$~+-n+aQ^i0K;HGw1jNgi5>=q&3Q&waf2QHfl=s zyoc^+C^LAitn>3OSC+FWol>OOy9|3NYcAqA74(+&+fMHqZj)-by+ZFcwy40=eU`*q zxK3|Sd*nq2jl4Y6TAGqA$nN*hmls}1=mjJG-EgNr{f14mFgw_T-+Hp$UT}A07wNNU z_`qvX&|N7WTIC!QfgC46jU{xL!?gNIfGS9~Wirt+F#HOhVuQ0?Ny0`-wp%pV5mjzN zR)_hLX|qOWgig%%3*8aJYp{y&PCG&Oh~Egml63OCMjmgx(Sc6yaT!<`v|Zsb_*1gv zT>%mDV!~X+Wt;oYrHnEx)EjI?S_o?za?~8hnV&&_K}o@Gdim#QEo1NhHj(p_VO|hT zTKy%&tC}s6@JP~VL-L57|AwSYC&dc6?9rjH!v20f9&=c#>*u!7MD*cww zbwYTXU{DmD-r_oJrc(L+?_eTkJ~K>CWHw<5PZ9@$u9#UN~6x1RG4FZR} z^c5sD7D97fsN~%V{F;#IjHg{;$k-!;yUyhbVX!Y??Lh-s;2Tq?NFdFjKhwt2w}B#w z0g>OmoqZdgK~5V>>@a`9Oz2gGF)VNIUB;o*9&=?$JSb%iL{w%sh$BZ9a3I^CoZvuX z2;m*`D105~7;&b=S#azrQUVWX1y_-ECyxt+m!(oO`gBO{KoIMtXfs-bvr~-b9-+E!!Jly2~cA_^R`n4bW%PEam1A z-@zWA0&k*Xdm3#MS=JzII#a?r(=Q|97@cE;vR;IAf#Wh06_C-9_-}Je6wj)d?s_T( z!-i8#*!Q*Cr zg96fMnMJWmbFPY2HebZYtk8@VN<% z)y#McI5yNVCa$6X^lz8<^4#RTQF+TH$^cjryoAPYuuqdgEnQPSBWL%vsJnqrn$fVu z5VqRh(4Qm;5dI?DqIYY$FPTVP2`B>^gM-4arVt^dd4Fy_zr#HK3z#Z!3)`)xaP)P8 zaKWXb8lX;jpZ#DH973FO7!A3Oh3ZOSYC>Efj9IK1J)3kPc%qdr91EvSKh`e8(`6;WqI*zm@Y_S{9%x^*%!;5asQw?Ur5$Wd z7~rG4t4D%gULSXk@P3mvX5;uKaiFjyYuX*e)SJLErr_HgDR2^JP0Plo+t;J4iYfvsX;FmN)bk^fzEte2} z7{wM!tfX=TvI5Ja{kEr=wbRnZ%r)|U7f+pGcE94W31?ht1M@Dwqx+&OFF~8ak}1%M zM?cS@)3xNcfUTlTf#J~w)5eNR6#bVP*iFrMvYDF0ca14?O&(hD^19|r-q#xYjWieF zE@GA4aNsD$r|ih(7zP=J_emIt)5vQqWWr7Y^;m3RGgC5l;%BJ>9Ez@B$w+{{YZ3T& zSg&!&=S{*irobSHqg^tl85H@*UD6iEkm9Q#qb$=7C!0|K2h}#C<=_0V=S#BYbk;Xx z2f?<0Dhzfh z*}|k0g}!;VM?Ux8JHqUBmwi`c3|ADvwWq*-7GtUF&1Bo?y{q9b-_B3%_5+gy{ELfI zwxO|d9{+)-bk4?Qct;!(O;nX_As!aJ)ieW6=ddvKwK~v7FtuqN=6}`S zCjS2Dj{jJzaoK%J_W3sj%RL@nF`H9sXQo=S1r#WPLF{lOl#6PVi>_s}jXQX&d{pMJ zuq`mrSV(@D>0ruGA#H@5%y`w@6Y^H%RZ}`0j3F&$e=cSXfB4>z{)H<8QAhxrIJM|V z%F~+21(R}$u6{jpz$S>KTugzVPno2*XZ1$5=$s{g~elC^%M|gB6I_2SB>blLb z**NO@?7>qT@X0s<|8GHZxBhn*bL#s4T`Fhx^Xkl{T3wY?R~qZuT6BtR3yeXbOz>Jl zH+(Kn@+{-T#x&^Pvm%-;`pJeGh z8vR`I0pU^jIIeLoD{M*VcIOs2U%qKlzi?W#xXGo!Ypt2JZl4 z5q|iwPp$5>3{1kQ4IeHHX;~-f4E50AM8_|#uikvGK(~KyL%099lPilf&Y-MU^}QcV zNxewd51&rl>pJN3t7;8Q-)uNf*R7N}n)(i>uYk_#+9|Vk0oq99e$B}%R9Y()ip;wf zP|apDqZVvJ$8UCZxoUpo-L^$Lw$*F8QpKp&I;`fyL-AF2UnJM{NFplkC^>sGt`4?% z>)$#W&Ed$2$GBPPT=4u~@$p_lZtox9L+tjeTMzo)$ZoB!6lFe0Kj^S zogzAsoXuA1s2Agb9^jY#dHhOJieSs^0p$i8u^oc3%1AUy1uiJO5azb8PNmC3@k5{T`a|Teki_pghC$cmAnGZ$2c}{gpnc zoQG;QrUmo**BADwV;@w!uB&)`>V0y5(o3JN%9lQD%)Z+|!GqU-JB6!1$V;ije7^c( z$ffRY#)+7A=+|i{E5Cl~k|g_lINjmx@pg%UGf%`W-`98j)Xe+{(0fQ>p{VD>4_{CC zxv%cJU34tVmkTqJ7kTI$@^_yjE)Y?P>9BzC6t943Coe%w8&TD(xq(BS=FO?W?8k^m z1tCQ9XYnXRoQ;{_DSgXGn_{GJ_!1K4p_9#KXU<{0Hyt1AHy-!gkCT2JuPA|cMV5 z{5S2C>wS@E$(oD5kcftw{++ARLX;LSO+G5^-+sp4Zqe23F; zEPYZ#8+j{m<$V}Clkf!DonOQJTX^*J&fXB^@^(V4CaLZSG3+|G$G+{lBe)oLq21sw zlJ_&lI5Da3T4dBXn*RG^b1)W}d|p}HDpc)6&sOMmjbA2jZAe6W^okws_{{GZE|Id# zeJw1KQD(p${#l!^gD8dn#icXV%n^G$R&4S{_9}ADGc0_@%Q*z~Vr?1j;q!!VhQRqdbdY~f++&;75U<&T`%vclP*;+7Hq(+= zQXJyt^V&u=Zjk?cKmVSHQ`iEg?7(?6azxyfOwT^bexovD|H|9B2WNIxJ&%mckq#Jo zarou&qZ7P$4{1;a^sXeW;_8!yj81VF`mtJ5UVSfa(YZSJ;!^)L&f6ldhwiKyn_ z>842WQ-$A((t4vfXAHK#6-L~}k6O~5T*|tnIwZ4hg$a_kOwc$z-ULq-7>h!jH9nAf zwX{;jE;y}x!Lit7Bdx{U7YXMwJ7B&q-?OIJ&Cw$a;a}gZtGS+{(tPSYkNRq7^q_C> zv1M-QIyYZBrK8982rJxSGb<|8$#&u|a^;90xV&g#J7qOHWr(U=E~?If0Llc>K`(JY znasp9rTBWfgus8zfoLK*Cs2BCFgTji?q0rumEYTm z&*?5Njwcpn?C<=u>*d2cFFk$?aalu4)XhAUQ&fN^dS<2d^3ip@7`I^hi|4w`0&Q)| zU)}h(q2X`)JxBZH9m9f;73egKHYApb@E0HXVDY>+L7yfAQ zZnXX$Q-1*_q4}o5tv{sZ|JDTUUcESR(lYny26PbA$y@n9;W9)-qmc{yHhR;A@Wo#m zYV4(UFDx1?ERyahYE!(0CpvJ-TL*&cze=ei##Rz2CowkMYD;Nn*&|{6;ZKNZ>wM;9 zsXgqF;TDvuS8xD{p%O^Hd=v?pseJxGylshFL`L>>hk8?bpgI7?-<5fIu4Q|E|1c8q z2ldSO>bvPdv1e|vzKD@Gqb+fpX%u3}qwM-dBj|_a4h0I23u1KGQRp~B#gsPqnos1G z0^^coc;dXJvhH0()uXEtw(W9%x}q@&32t(Da;)u9-t?F6Ygdd%2aXBO^Cdui)FJ@(?N6#lUPEE~0jtq7efif>LvTpbNQoOxw@ z?^12|$-$LG^aX~5=}noi1j=qU{}-)nBjq6P{F%;TQZW z=T`YTbp40u?BQJ8*5WI!!@hBsp>(>%H;o^3-zALriPRl3?>v7A1QACoM4(@sJ&Dm>JM&WP0Tf+1^#ijO~6K76ZRc^sYt?=&Bwd$Qc zu_#cI)za<#LFj?Uhg0Dxx+RssbHBz>QpvPl3J{82k&D}hdVkPy-XUZoS5Q!zDO)+U z#w#f6;4Kx_4X)5{DW!~VCc6o3s6UHi88zgttvhYO@T9v)cPgPKPeXT}R<7kP9_<)!iWENeyqqDRoq z_*z*Cj~My zH5w@mGIg#?9V;yaM=ah^=>w(6J<*4Yd69n09QnS65Zs%7uhh)kw0x?PRi{DjVvBAb zMxGJTQ;nB~TOK{INGe}|W*MF9mWUT;XTX-Ncs)Bu%}W#k2b`nHNaNL$yFY)bO~g@Dymxd&Ra{5|rJjzI!Sf548j4erY()?1*|W zjAS0AZ?bcL==8q@Wi~!>UY&q_l2|0-)E=XA{2-Yv+ql5 zc%J%yQNASxsiz3?O(E1FIRfKS0_*(pR{znzFvutC6@W1vHWibP!1)&Q5W@pTO>5^m zE&D!l#N@n}#6CaB45{090Zy)t07qAztYF7=TP~pv{d?O72L(i?HImO1z>v0zexD)&hzbjqsQMwFfPSEIwF#~hn_v*e<*nI*kze(cTWuC z>K6{VGL0xZs2+daIzJn{2_bGZYRR#wvi9X$M1SE{BuzHdoZR*)vnT2+b!dw z_S@~<3e??b%|i6t99TMU|UFY(LZtuljf`k&)nI|V3PI3!!? z;b!l9#J-Z)>dpC!%#GyLGwfQ1LFBVmTJy-9leeH1Q20WDRU<%-0UB)>M$bUI&a<{xT zdd0*6jbJjUbZQ~r*#Y@Ahp6XNTaA0|^8O%e`sYojeAL<%vAaCsy&MO9@|#Yacq~wC zt(yBn!_lsqpS6AlM_K1XKZujHwQwADEn3*2; z*qS~4xUBO;q{A30^RA}JC?{Q`ksN+$>Y&u@XIY;oCtf7mewI!A)t4W2+v9fw`>8Q* zcSF+6n@t(Fp741P`?n~OKFEZH`zIkmZ3~y6cuWNI0jx`H3NDmBRpzGo9)%te%o;c4 zxQO)dH3+hR{R$j-xQkLHWLE!U(=^|+`7Lj{@u^soQw-SnJoU5-H610Z$l|B4=iD=j zsH^vrhmk|iPEC(^wK@-SmU9lcEsg5)HVt=i`2TRw0^>B4E8FYojTxx}QoGUXyMjk# z#2Z&}EpBFud^jfy^Qs~L$C+$(K4^`q?fude-tDC5KK+vd*Sd^l;-)@>m6^LuVLxvs z+kW~?&PW=DzqOMDE3K4d79t4Ot2m>+M)VG99OV^YVwD?yu`J3Mns*YwkZi9}}0 zX@n!WC7}a-(SAJfH*XPLvVwZBA<_GW)pI4%+N&k4A@vzYp)YK=*gjyCFTjU+?#p!A0C(W9_4y-;n-+i z(;)?p0UOXfg)%`y8jd>GRV?Kw$(e_wc?9YgF4vGoktV7F>DZf^HH#3h$FH0oc0INn zsjnYroyRO^<9Yiw5UkiN8IB6Vlor%S(L^rm5lap+B-n0{eDn(EeS z_Fi0-aGI+t?qf@WR>FMpf$*x!nIXFRl!m;48NrV9>8U60%5Ml84V))eT@n{Dv{B8n z+cw|w%j2&KW7a&nkN7!O?r%o;kIUt4$Hu#iKhOj-GkyF1c>I;TJ-nuzN&|887-bXE z=97v#H0e2Nrs$O%&yb4<8`wL{>{s+v^5CRcV^`gQaa@mM^E9Ig(wYCh5%$ue0Yzp&-k1oyZkj8KSimT6}EkGi+Rx_@r zut0w&6~X`youd2r?HzoP9CcBl`G|yh@y?H>BY>PBa;Zcmg51GuPV0z>(Bg-*U$c_~ z`;b89eLY8qmrmtqkB{7$`-N+Ye<2m~HA0!V`fBcv%@RBKWW%0d!uP%%*rj1iTJ^3z z*^-hgy_jayzW$i=bL9jvOmMINf$f_JZ+q-(537S`eUU51E;Yok`@)5`B~Uox=ZO1R zd#a+VyYg9f%D>ML@S|DN?A866R4fq>dC8rR8PXlzM^$gZj+={3@)KI*Y0H-M4~C1! zarGg)UbJ%zKyY+UOlEg)$e!Miol#{Yjd%Nln-4c8QV*EtC;A?`&S7o++mY?ShUB{q z?hd06t@N-&G+8~W54riKhVp$}U5&J|hZrX7n{jv_{aG?Qqsrqjw}>j|uenK{4ZVqA zs{1zlkb&*ngbLX-g?&Gy4cH0WGH9?VtOd*{5 z+8A~^Que~}-$MO2F_d26`zfBGt7o0Il@Bkub?kv)RMARW^fLw&RhH!(=cyjaY+s${WjV3gk0+F zt!$Xihg?b@<&>+FI$m8_i+IT(C!`UH{f+#F3DUnVM7t`|lZIyg9ThSaPg z=RHv;C1;4n4A^p89^@`D6qGyFEB3y||AZX+TVJsi?)|;|bLizaKIaEZ1mw|MznswW%C5UBG`0XV;XyXH))uq1vNLA$vc{T6pHPG&s@oARXYDi%O&X- zRUi5T&+!#sXj6FoKJ)6fqLoa`d0*0-R||LbFI<}9TMkhvGbWwx{qX#N_v3wJ>8C2# z$I^ftX3{vwBzgy%NuF17uqg;fkE+oLmH|*1tXP()9w8L)im&8D1pdALMb$CW)>pRkO^OftDnfT0GZD-YHd;DVFq|m-|7bc3u%_Ps z?~l<9qkFJPNVlW|1`HjbU{E3q1d&EUN@*ApBUC_8Vgl0LC5~1pr5hBG6sa#NKDWRB z^<3AH!P&iY+|JH@fAaMXODCB4F^XNsE+oTi2SdX@T&z493u3(Uqt~PKl_NmRlw238W#XJ-T^Ip zz1n8ifN4|F2d(I1$nnw=wPD7*H)e(SsF9-nQjNT2O2sdy6mkLR$naJ3R%eO5e63b$ zRkfB^h?~Pq+id7Bb%BZyGvyyeX-A3Kh?}11iAFNBqb7?k!LS>503(v(ob5^0Yj}oV z9BqEYjXUqeXuLv+-$S))Iv~U}F8V3KW>&K!D$JK!qbnL?^MzYCWa0BW|Mk1%uV8O% zKMr7f$`0{qRt&|m8#i1CG5&jgcCrOscgVLG>3ogL=QjGKD$>(-9%?^2OF{z{VSR>p z>dCUG!HHMeosYdqP4muax7eFG)qM#gdDI6DJnEYeW1=&{NBSG+#Hu~{f!R{ACCd1a zHx2Np<8MX0oI_9!_hq+`%{e}cPJ+u9nK%wxr{wHpKf-qYKKl7iBJa$S`1;e?^75nP zP=O@vM=cW*9z+p6>hK0*Tq%EwBpHv47h3B5WSOKGUCK&9z`Gp>L!xRt&$1+xUec!( z5i)SWlWexF_QAK93Z;;bZ$x~n^0UpxX5be}?%;UbiTQ{ZX6Lr_mmPqG#lj%*a+l_h z&ybRlPAOcXl;915(PlkDj>9j^0%sV}<@dG+IrKYI=^Tp23llk8=_S|_!8~@u9tgeN z#>Ku);mdsFnNH_s^tAs?dI+c4;oNwcf>mM7O-RKHo^SDVX;-WcWi0O{_SfI=FP`k% zGkPn7-eYO_FX>IZw#MiZ-4F_POKAcACA&5HD2Ie zc4$TJsXlLUS<$}zy|B8KP3m~zMX7J?tN5VLp>6pBYs2Q(E0;JJZ+yP`NWVzJMxe6z zKRO#5ITy;x;@p1s{hVcuSd$1N`UoQggu@TgKpkO}Np>mF8z<96d(#Yc3e9G@l=pEd zO7v1*zD!Yd=aD0?H-F=Zkx4-fyjr|(_lneDWOnZaWa{~v66kk5a|yEjQp{YmB1jlJ zr?}d26@ZraDEFF%q?b;6T47sxVP#eu)#W$TJKjX3NLH6KRF{9)cq7eG_a;KrKJTgr z{-F~)dow!(c1Bb%c?~!xQ{hb;#)n4twCNid$%tyiGJlt(>s_^W)-$>PQD!7T4um3} z4lt*xN7HJ&9HxAvbpKFvSs*z!fM5G7RP!sejec3+L~RZ+r8lyWXyHLN9POI6Per-U z9`=d-hMyC}%WM}Q_qC#&&pzMXid$?2eiNv^`4^JEJ1eE`1H$*u?Ed}>=GXcq_s!EBL{&iF|m4v3RnR1qBB#;u{ zXD%@a%wuyCzge&^@d909V9KE$SlOyOywcdLJM6zgr$rA(_`Myj0q?dr8QHpmQ`4iC zXP0?SR;5T6Sg{jq9kGCFKT9cPe(_T2mxQdhWcW`e3tk7Z7p zrII$P?>E0Oboqm9gxP&o=Ht%Q9Dy5eW@U$Yo7uPjvTXldIVjUNr~pY1u)Y7kyvIr2 znx#hftzsMx>XjdGE6UO|U6+R-2W3|e$~2I}>iGfKSAJq^ma`>!7x|VY56V^#%IM#n zdx{LJKa?46;RG)3L76doyZJ#GrOhipRdB7q!-c88FoQL!gEGGU+FgNzGSeTWLP;$Z z5JY4Y2kTn-Lm4H z_wI0c21)ke&rbu$nPUmdG+CK1iIcQlVpw{U7lEO>pPb_c-0wFrCLTrPe86G4|AJG` zaPgg%>hE4j&5$b+c2^{pBq*ayo0mac9Zi7bbZdh5n2{|q0gg=Qf(Fl)hgU|Odz$I5-!KcImgzt5A*`Xfkp|= z)P$R9TeiS9d1Z#W0P^7n%Vv(&LyVVwgjIh(leEwb(TB=k4x=iTyi!NGn`(UzqzNG- zdXN$DGliZE#Y~2Z+=TxN&n1B?I}18HI>qEBxsNyx*q=7EcGo2<)>(58oTe2m;aV~v z_vLl~*s;szqNed_I+X5TF5zw(v(U1+$7y89rG%XikP^!K`HJKgEMusm#5o>EYTB^u z--fddy7ohmTTvCo@P` z@b|fEs3jUNU!8i6yT1FxgqAv)z#xS`lX?(7Zr1<8|-#IrQ;P*BH6ZAl<0AnSCv$jl@$nAkR3^Z7l*}M5&^H7 zV_^JoKdzPfv-wFyyj85p{Wx;o6^~qDru%VsLQY}4xT2Ac=!)c+COwo^Vu%vS5_L*< zjXC!f1f>NElY&`zS44u=M_2-&jI6vXyu3KeU!4gfw4L7Fp4)+vK8ufk7jl5X8z(t# ze5xUklX&yeWRU#K68imxPRsw(A0HJ^r~T5{3Bn^Y2i56jG@Km0Hmwse-_1!72;(zF zshTMPRuMHkw=_b9B8;);8CO^8ewHAg1*kjAe!enzC3azrW*cM zxqYKRvZT5Y2hyymlHgfiedUFA+)n(1-yDePu;^%63q*7N!zcR6GD|GVqm>(Tx=s*R zTlrFl+U|fS=@UM!Y^_=VNL#>3fhAj8*29*cwE>jGB!6xwzB71Lh6|YQqT+o zH+x?1E5+S<)R*!Ym!jwx?}oAQE=BoMm=t$%mp3OspxQsVW$FL7*sT6n@a`~Y*4ah~ zq1BTUQV(L1x|CRUh+Vjs(>N7g;O+KHpQI5ym3zL92ICA>VYZH0FDJxX_{4I zObQz#H{Btb?XGbZJxtfU?UUVIZ&ze!zH_DYdPs(y?*^@ugzm21cTYRAQ;(u|RaA?!T*U>%(9u6io z(;U|&xHrd4%$4-SE8aNWOTa!n-Z3YA8|Hq^wt>GpNY zy!_p+-4Yv9vSssa$B|#X<|@|j8l)sc`u+AmDdQs(^Fb%Z+Y{z0^f^+Yu{KuZUAqtq z$Te$_y7|w1pW zN*_3Kw&?JJ6~(<*A1M1fL0oR{UK<_fKmeQO-|*Px{C|}e(dgFvheeVG3J^w6c%LYQ z)q)O|mxsL!+vY)8k*V)#(d>yP@#!kz`=TI!O@SY0(@KhV53I|(}FrGFbtR>%a~ z2Ei4fW!HnUyfn=%fT3=a-J?+eEbu=7lL6X-`}0Pzf%{4WYClbco1%|yfG6B z3l2l;u0IT$xpn^=BUqUY4rt*6DB7{3=FN`M&;4 z`+ww^WKET+f3-w^tZ9#BeT1hv-`M?)Ae!hz7kz;6R+!d%m!`Lg8SO3Pj4vJ;_$A)t zR5LATkWI~>MHg^}SucSvydH-_x6NpCS&A+-e||K$ubOz&EfI{jeLYUIl*hdE*Hv&% zAdar2A8nIl_gW(QZpEO0S*zfmj_G*5<*SeV=-=`icoN1Qo<@B6Vz&P$`067lO|Y-i@-4>84gqZ#y0$tbjbl>Q}TJMo^1j34M>Hg5kpVUK5o!5VhnS!Xtf>xUGyz8I)ZPUtuw;Go``>fY4R{mWH+ zi-6{jO|WqNz?gdN^&%!4sX8(N-o|4y3xB!vY(to=Uy<6~=E=#B8fXmd@A9601QbCDt{EyY# zt!6p1{&@;tSjIaQWBkH35%vp|5Dg|fLbrU$=WIjCY6DVy9EXt2)~(k9$TPl$S+WFq zd39HOquX9pfr^1U_10~sr5w2ygOtrqX=}(y1-e;8iYjtD+^8vq9et%%- z3P3fleey^65(HT4yglL=Z5&2~!dS4x#6+vdWTuZEr!k1RJ%0#Vr+HTIQ5$6>uj>=g z5q6=C7@lSwm~F~_RvQ}#V^oMOzlPZUSZR7tY!(sqgQbg%S;w3Z_4<+II<-;MC#nb3 zc##Fs=9AT3j`m-28$s5cAhAN5Y1EH|q-EsV`a~kvkPDUY>s<8dEfY1+ecPBRj0fK| z9eyYul zwe$8%o-jH5xC!AD!ny*8Lk|r;=jtdlyod{M9tX@*Sf9fOi;;r*89P1E9vxuINJ^1F z0GwUISES39qN_wd>`(4{&I~mxB@K*4CilsMOtNhEy-+T7wOOW54J%auSbQ(DzebV# z()`Mu9t*r!1L)u=ei6};l@X~(E|>AXgb^jT$Tvm1PGw}FH&v?xOY-=t0DUAxP5bbj z(++^AxJ}neTQUH!*2lX9mZ8X$`!8$2C(SRG;5d75_qIP|Qt5|jbcWJ&{eF^u<)jK( zh7Vufw>bzYT}4_G6G4@)!yauJXAHNX-@BxW(UpQVKKI&WyYM~Sv(!LVm1GcqS#Dxy zjE5l=mB_gNfoUle5hSIP2lPmgtO6o45nQv*%Hj*mW(&9^Zygnhx^6Qa##h~j zd>%$3#}FwC5*>f%;P~u#1q~7vPAjEoha%(w=$I5IqQ@hVbh6iL#>nMvX&*F1qo<&` zB~Od~CXD{M!5wB%D?4pVU}~7zhKFw~Y0%`-^q-1oU^H3V`pM;x)c8p?43w$ng4@(K zJZ08_!~l!i%qwo7FReSSd39~@%*d?ljgS~&5`O(g&LXj-pONOsc>`U1ndQ5ohhec$ z2dcQ!pm_29$h(Gnir-?V;7loJ;KA(TkFl7k=kS-QFr?X4%@cD%rt()U_1)-VfX)3C zjh9^az9jR=|K?-uFRblVqas)Nu+&dmdTPioQC^vQJ3)PR3w6r-Q_S@FK$`vvg$~S# zw(CWdMT22eC||=GB&5_?&Qf8Y4kq5j*aQSFqe@Adkx0-oTKye-R{Y{0HXsX)nobWG zQTM(3@Eg*pb=(Zkt^%x*7l-J@!9f}s>rQa#;_FqeUBHa2M;s0?rqaZr8OiOw&<(bM zn~jwPbE=KuhF2Y4rC$o!b_8IS6kEbC))Ikg|1Q|Bp+Lj^93dQrgk? zD`7FmxZG;?^TlvIM=H3C4)Sxk9~JY@CV2z0iJJ}wa2lz3V-tpWwmIsNjw!;7(wGcgl?@%JjkqsjV6(~o zxENDfJ$Hf}dq(X*T>Hb_`yNwYEPhTWaI$NY7R6Z)1Md~?M6?Lpc8Z@b&-Ey1r1}2b zeiE;J+&V=pVLC|){m9d*M=ML(z1B^yZyh~}|5eD2~_{$y7};=cLl6c#x^7dgO#Rlz0j8b9tW9>KpuhJ^qBfndn7ro)X5 zlAVHlhFdqca>a%~=bm$vjj@h3lw0^=-(vX3<)yW3p0H}zMI*=?IeaZx!;$&YAt^c{ z4@n=gc)A>5E5?u&lN3gN-Lk-|pitin!V%)NLf;i91UV9itO^!xmHe9s;WLa7&SBw} zX@deylYE{ojFhh&%z6&vCT$|}N>wMq%3x$ z+ELz;DWxh;BB;K`PO%KIB40_5!m04VvLS=5qL@_i8s-!X=$Un9!becz6|D2)?);Yn zwXUdxn9%Bo1V7&hoepHiI!FtX^YvdQ+28a(O}`&VK$ptj`bK4Rh|Ztafw6I=n;F`G zUSiBMQl}7dR1JS!^~%nF!YVVyoL7WZd{8#LFuf{!;V&Rm!@&2~07A~)3ot?}cz#^rVXvf?L9X^mGT0YTKp04m1)<=*+^AyIzDo1KBC(h@=amIf-PVVqM zd*OkkhuOE4J4E;M zg+x_DiQiJj_|wD6%hWLWoVQs(elgoMTMGK{nPHpvYzh+w#fEJ*CLSLACO1P7DZ>BPA_l?Xj3e7RMFCHvCO(T)lOXq zf+2Tt-hL*Q-_&f@ zI0K!gEHj7%8dRL{$O$M0BnezxUWByquXHlMPVJ?&gCO?b*tTy&Lb6~V>0#|S=FR`8 zXY)oo!XHvnE(!6g+*8J|FPb|Jt&*IU_56j?Ss`0F$V_w2hq%%*$Tbl(j-w9 zD!JaJn}X`x4h%0*+&J>}j?o;@_Oj1Rg_7>RY%#)6Em3+(?Y?B=q63|!?TSPO55lKs z700x{+drWgOTHc&a%AVfEj=CgHD+pirSEck)pQS82%I~b$_NG#Ht~nN@yBmd;s6Y6N(`(oOQ*H=6rN$}(X(oUp4|+wM ziHBkcsJ(};d=Kcn2L$l%i->7rE2&vvmi3T5>xAPE@$ZE%lc-j%+|b5M$-~n2$U9rz z-)H^QbBiyL(}l|2!7~7*5zS1IcG}eb$l}|)jU(QIA9os1&0&hK-RrB*$JBVCyy|x#!5TFBl!w8ek>3ZiX z3+lk~H((UiZ_8lr!x|%VoOo>iF45KVPu4>{w=%AkK6v;u{C8n6Dhqaj7BTHN@Joo)>#nEWuyg0}~uD(k`rwy<2RNCe|ue+aI69oaA) z(@*Ku;e=giF#d@ap=T1XtENU~^B`}LAn0Eih*#ntliX9?qM4PPV=Cn{q~tP`3c8@&xf4>r+*4sNgWIz3*3EDe8!wI%#hzCLZ zZuEc z`EcwcB>qi0{vZ-L<3O$(iL{cvAFv-$RA8%t!@z%@$*;n6hAGsMrDktZ5@j2h>+kBj`WB8QXdtqqo=K_R-Y9R1& z)YL7cHLD%@fkt)KLvnG;S&BKh{pW#K03M*{MqkJHs>%hBs-_s2t&N0miqGA8o$mo@ z=a&h>ElXf?zI4<6F@b35-tw-FXB~{gL9BZ(=|}y!q;!klHVC7h#90X{>$`oTrV24H zy#=)$O|^90DmvV6Nh}BO~pg2O5bc7?}A}`6=bbeIT z1L&VjG2FM7a%D>}h-1uO**6W5GQzo0s1d%@tKii@CGwbztB~i+mkV<_h{T2T6p4@)z;ZiQa=UM zg3oV>?s=vS{CfFALnZJDNVT1)8ZRtj7Gg8nI!Wyg2j}@OME8c*{^;-;s865xdEzSX zK#0o~Z|q&^K(7JvV>c@b3&SH7vZ)bs6F-8ju!GeaY-tA$W)!|QdmV045$U_ z0BrHDfS$fazuMU86(=19dOG=mMZ+wQE&vbGA0T;=JXCpp`<961d{1jW#Q3V_c+J*_ zghqda2huj@hXSIP3Lvksu-V1)Gtt(L=s*ck(SU>}FQI~Vf}~>AzmOf`BBPEk^p@%n zMIg;9%c3Vg-`AA{zdE%0?^+=z8Jd?1!z^p1`hJpxh%-EtABjZ`4{y^3C*X68hE(p{ z1DfF6Bo?-M8Kv+2Z$^r_L?sRHf4-2|A3aihTeMU*C~~BDQn#SOpA&{u`u=Z#Zh^-> zU7ub7(`y{J01i7R6LUT9`emi>BrOlz;YkY4YBMgY6tJh&U!a%qb1&G#vXNop;+iOe zE7_qhlyFADqDXW=P$gMCi;QZ09R~wW1GOXey8^Bm@(D zW<48j9f=JL(!*mEQdY5RKucGF33fI#;LS-oju!dy?2c)Etw-*lQ2b|;_eI?I!M2=~ ze9oP|@l?%!(R!fwEksN2ze&pe!j(IcTRR7`E^rim{;7 z6IRiS9#0}nZ)`)ME(02L^4GoT**H{_(r5MkNgwC#>*)UaL=X2@O%Z&u5~wf43>U3ZerJZs~j_ytI+9?;2>*MIgiBc?kxL#}A#Wn2RV{;eX! zXqiR*{wF;#n=zdy#SFC*I7HFFN9)X}R%y{?540?{JIAO=!^q*6%CAS_>PJaiM!R`w zN-?q=L38 z;WC#*^v-Jfa6VPznI4&Nc#|^>`-DF^SG7Z|-c?rJhhBankz}E<*(;$L0{Zdw6O^}b zWuU#<6<5aPP+qq*LYr*Yjj-rKaQ7iB*c|S_9Hjr^$`HQYh$)8TT#zpQUmHIKi^Clj z2lu+`pA~#z4gw?#=hIZ~tyFH;Ll1nlfrnV{m4tfN9Rgof*HMoJ=oi$bmY<-MpLhzM zi!fyA2s2~>00wZTbZ_~I5wd^3!hQJUC(20{PZQ^Vk}M`k7LwAw|IWhZkOO{a`rj$C zxFzK${_Qb@-=T&xhJOyB7<@be!A)LLRbDS+B2p18^ELuc_jnTff2@RXTUJy@jFfD zIZEg8Gw0;dzGt9?ow@>mR~Ng`l%{MtTMQwbpDWhe{8ix0=p?*KuVQWeWS7iXIx-V}|`mr?Vt#YfEI@|XM_@|Tj7 zv~{U-zSne5`j%9hw}&YSb`Z_miRO1aKzXi7eTMp4<~0L?Ql~C<{}L++o`-n`u$xZi zE&_NLo>X$1WXsu_kt4mt8A!PAFs*XQ)E@}5@&np%-@or9J{QaEAQJ_SX?13m|IcNf*Qo2`@or~h4@%xm2 zg3nIU&O<8$O&=r=rSNBo`0BRM=dN-=JQM&Qk6^ULu4WrM5eG8eL9Rf6hcOjjH!`KO zO9>wUf%8N?H%$!o=wOT%9+T=fccLtx3K8*6&U*|L;K-Y^_;4`w&D z@&!mO_3jd`&PE?Qys=u^3$rK0ODS`+2QH-6F$|lbp542Li^{)YB-ACZAt&g=N*%)p4*#5mAj_nZYmW7VHj!Vw3&b5%i zori)L9&Ek;vP&aj4@pUd5UX{@W;kl^|3gWN^QG0IOiSGXJ>S6%avhaV`|NVz$9rpL zGaU3Tw<+)`+-gn`n^jhbi_J!Vfu-Tcdtmwj>3=hp{kd>#uEe*` z1yF{@44S%M^7+`2N=ezVNmaR#+91AYb(4_MV;rXFb6Qb5L<8?0T?VAy`q9^gmO4Nm z)OXCA{_cqPOW!%4$f#bK@;(S>RR6IvA!7j$=I%uKOBU{JA@~05OML8$R?>o^WKL27 zNuaYS-1k`5PfcJPthNJcZ{JZhrO*?pzDAiiMkzvggv}z;SiezrCGuk!IlT~og}j82 zr~kJAmjN8<4yDo0tGxB@W>)?XR^vPce0Y5qJa4^8x6em#`~WKPyiOas5nvQqAa9s6 ziIl!iMeBZ>SC~F;XXLW9B&N6kXm+E&2?FlD`C&JaBx8JKd!mMXL;CKT+iP9^2KON# zQXc*nS1i_G^+f;m(s;j1#BdC)HX9p-O=q9dDD8~+oRZceAt_%lRx5ug}4`443gv9x&v30KeyfBuI15%Jx^$lE zFu&2Nt^SzB{L~-J;OKk=rB~q0iP*;?X|i5{sl6Nu|4~_jyGbd= z1ev&sOuXuNFl##2q~Um=t2LK^?WhK%%>)Rcw3ZNCQ|pN^gZlVSaECemj>}o5Kl>c1 zU4L!q4E|sbkvL41d10p=$kaQMZ8|=2!-x%${x}j$jx}`DX;FpQJP@DcroA3@@RP$#n?r0+?X_!DPybqjZ){MQ}L@}J5I|2=-Y z^|HMswNL-nu`Iu6QFNT;RaN7oHz1YJ300NoMIfDkmgR>LdG`1lLbt@^cO!E_g{((Z ziNU)(wz)NkYBQB;v$a>+Pp`B*a{Ld5983Z=Y?V_cz^`dw1W$SdmzU8DA@lH|_4rq~ z886Zp@sib^3}0ol9imBx{f#yva& zo(Ov>g^Myl_JULJ;(we^=|*m8s&Dt5F8D6%CBy<}(wF@`P?wt$Vat{N{2UUbp5iKR z4nfY1)&~$)X}%~z#s>7qf3a+h+>&l>>3;wsQu&+c@vE)={R>!YpTD>TzY#ab?On z(i${(*(@0a&=b!^cRYtP>pCGKrCgS?muE;thqnIA^B3>Tq-Wz(m91$( zW|=tp!7Lf!H7%kwGX#YH9;>C~C102&A9^CL>|?(RZnY4f$cL8wF13gGVlBg2l^k}1 z@!=LmEXQqC;Gruum>b{$mo* zj(Y_wWrFvzqke}a4Q@=))8zQxh^iSsdqZh-RTy)B!>g}0lElt)>EYWZoo) z6n<6#O*4{XRwCHS4q1|RIo8~REkAG^r7Lw$V$=fQ2F;<8 zW}m>ETdYhfu77fvL>y2x$^ZOoQiB!fd=YbUf{Qp&hhi9p^HogqM{7`8GKK`(ldQEo zax;&OsB{hZ*QEY>r2(!nB-g6tW6>)|TYvxfGXSIkmHBP?;Ul{EQ=Eg$aI(FvJR_`df`TtO+g3r^y2CWF! zIHMFMpDR<*=7<8|FM+ic0kze6x2leCWy?bLKFq73fU7BNMv?Vr%C?NJj;Bn@S90A% zoyKo4jpi8n7R`+q$v&`^eW35V9&~+~K3`)tZdXZ1%@WXjSm&orWG{y3%RV4)FQ)ss zew5FN4p13+nl<^9P5>S7937C=z7*JAJkK^yoBQvWS+?x$#X7RzgRXx~E_=FLwy9qp zx9f&zdDt{CbAnw{aeS%hD>BR9uX6J7zg5SVl3ruwPuv6#x(~CG;=;Y(*5wIABJb4?n-porRwN+KCDQY`ULLxSxVR}WaWdd zb=Dh7mM;u2hlsirD1n7W`jm#qX!HFQoqVPSeOhxZGk8?y>^LWhxQC%yB-x(UeIbb) zjm~-dLY{g2a@>uogcD3?h@2?iU#JUaS8!Y!oc|S?$^#Z&&e4bB|XHa zF~HXrKr)hbB$N3{lWrh;(;-OiWJ`}dy+L=zg(EYhDcdXl zkQ%YPNEYE%6F)FHj}1gAwX=@-PUtgC5_Xf;M$9#X6IwHU=;?%TWh^cH$gt;v_r6l& zt0&M18Uc`KbDA4Fq=T(Od_F@Q)BPyIY_vZg0>d4IdCe%B{pTZgUWeuM_|ZG9$;lUs z+O5asTs=ceKO%yru>Qvpq-(ZTP7n$+!jPzc+WlKaf~dNJ_nt(!e2opi|Jrbxzf9bF z83Is+@b;ykZI^%q?&#gN={^$60$#(h`&{Jboq&t0n4e!`nKQX#GA_AhepX&md}|$B zDNKlAq9M}L5NDH7Ell#>w?sd+1T59UY1U4(Z1L^VtMi%^D~be z>ar1qQil_s|HRkQ-9^E3STL&ro-1Ya0 zN z+e|VHvlD^ak|6kL1b^s7bMN97k(z!@>T2Hm>_fYNe(}`+*Ol!POVLl--lkcXex1&P zA3Z5aR&UaQSbg>%PBv$ub_MU_*Oz{=s>21Og#{SdoSA(rKbRS+Zx;1+Xr5uEgB_{y zDP$Fe+>^lyrRtV!kac#M?UW|WS)8?|3zjVH!cl~>t^Mb2UO4MI-l~I$q?tto?2GCGyXP=_$t$74EyETqAqL8(#&J#v1XN( zI+orx^_SODs%8ozvg+IW(p3N#`57vA2qIxAX*cveS=IZlZ1B&f7$1f&JoC*nnv469YaYYgk>-OHIFZR*dsOM;A#1aeeP~#9n3YFHSAD`>zGb2nrW3 zuN@p0)wf=LLu>v@3z-;5+~m>jfha^0pMn0Pn(+QBgb{n_28z;-)@4FHlH~gb&qptW zn|Os=0($mhqUzeJkY+rsE)B}*Kxv3ebRqx!{b61xL2*4t)4vbRvz+wo8PKeF)N@VN zcNT)t!90uh8MOf+1BWORQ0BeJrDo(0xz3XpDts@8Q2^pndzeivUyb?zFLw`e)zN(> zy95*_xLVq|5t|W~8x+Jo*wJ|^Le#fTKPk&C;yORMnKF|7= zKG$5D{VfD@r$7DI<}qfx;I*c;beM_X1z=4+Nrt<4()nqG^pp14GFl7G=PMK;YgV6* zo==YTiZ88f1T#av_OKhS$$7u$GoIT|@%e?_cG)iDJCmpTID%i3*jf{D#WWLqhF*!a z@&j26YM+$%#++3&D1TasfLC)N;iS59-uflhu(=R87cE>}9ol6q!lgFtc^WbG6L}mm zI=aD#`@EP$s+)D2>_(`<<#RBZ@mb5}8;)$v7=K8UQC^w=-Tg!xVg-nb^y`~6)IwC% z2v4)6RG#ol1SHxxGOD({dB70H_gElmpVB9VRzejRxgg>tK&i@u^7YlB&KufVD*f1E zvdlZTHjvM?Bx;J|?LcvY*0Zm+A4EYTNDfJAhz^*~m*&=Zfh?xdfB5+cg{x|FYiDb< z^j>NG`FxvsZc7Pl|2%mHdKi3T%(=?pp=0AL0uZ1WrHxsAHwi5*9s+dUcC{ zt&PEJTgGNgIbv3gZ@7T$6+*`Na3IRphxkKFwl)`@c~g75Om|)Ew~K^3Y5pbVGa@n8 zME%P%_Kr<9!*+^J3HAmbA3^dB-U?ED(}>g(+j-q{l@-O0Rv12c2x>R#CUGbuthc`kL3?qf-Ww_Y6EaR*#(m{rA3us{gp&U2RO^gk+{wr3up_t?Iq^ z6nJ|H4M-;bgFJxcGqo!c$&NU+1zT4A*@F4P(09bW*;4i1{gmIX?Ad@02>Y^xZ`P0# zOd1|1>gZC_!fy#6eZ}%L)~RSAMjJ9ZxIv6w#w8fI`xV^Kr$VHnq6~(j4C?5H}uI^HfLxb zV<=OB@LUD692Gud^tH=hl}kMKY9ItkC8j(DRaNlqPGk`9LYO|Nis6$mSb(gBdi9y$ zX6C+L*m;ud=FnL+BK!jXOU`9*?u~8 zlm6TS&i}Yh%a*L&uZZoh>SnucNtP2b`2pcJA{w9@lz}Ms+H{~oL*|=8WE4yPdF#nW%7wmN4DY2@wsG%m z6OwNmNNMb5j`^_Bky1K*J|OWma!GhOFNPN|2;tNq!`5jtILyAM)YLvYxoP zYaZ55Nx-d^va1}ZFpUD`!a6KlGU!Nedv?td$O2*@Nb0l^NCoG>BZ&MUtxKEGXi!-& zkr&joR#2N&LWoh5>vQD&(k*fDJo6VYRERQ$VauxzR6SLRN)L`fFhUr6y8o1BQ zJ58keDEqnS0osk^uIrQ`FZw)K*Kdc=W@ zZ!IAJTGa-k0#r1Y6(z<^kdi zxZ0WAv|4G$fJMuWezFrJd6ejL5J_Tj$!Eb9Cta)26*GIH&K1Zk?IM|aQJt%uMT_Mq z=`>Vgw2E<=9usgi-#%yIe#dpAwJV};brg(p6pR8zC6=$!5ZR!c;_I2j7+JV+nXs`G z6mHy)^y{p|jwSo5mS{sa7ZS5YA39`wNM!9qq%~K|`(%CCu~%r6jj-yv2pOZ5|E}Y> zLvU@M(Bc8n_29VH(odzrwKCmRxr;nV#tyiA3yO{ormpvfdEV2&gpFMRdkv$OEH57t zKk64hdNYBH41@g{N!qZF2qvuBU<1Rka^9E4eAfQJ`csm9xtckQ#)}K;{w;stGaQ?T zj-3+C=YOgO7q_mP#$jGezg0r5>E7R3How2coZ~0WIC&;G69g>FjWRvn3b2{JSN4(c zod6q%x}RXXEY_^@0y5g_dZOy@ zfo&F(U^9dk3mN?1Kj(h*dfIQkW&!9X6%A1!K<|d-{weZrg)pH4dr)a~?*7?1-yAgm zLM151{)Oae!#^XR7*^cNSA2yxSrerp{sg{T=7!S8nmJNv3)c5|TJ*nQDpb~#tHP*+ zJsJ$GCE!g=AA$)~RDJX%c-_7H@sAC*1J!)S2PdLwzwe;qjLvN{*7o{cQagblQS0E8 zG&n>E_=5%GpqjO|$CCD2Kn)C*8(4g5df*9MKVIPbfi#54{fKB+QYeCfNFqC-Y0cxk(i7>7Y^ZcORgAc?u0AcystPM8ycb>?J%vyAy7NxNdr>y6MGKzR zQcjuVjBAQPJyj%$^VX9Ntr4VQ zcivEp_<{Tstq-8bYlCB4x!=ozag}|^j2q7%RBkoP`@f{k zoQBsGw+u=z$v@f-yV0)15d8_|3y16q5z{(YD`RJ77a}JE`6oLEBtHpF>fPx&T9nuN zynjLKbNS)5ru3*y zJ3-p~T|HC1-;)<9_+Wz=+fo?Yk{iq0t`SrW_I%G0d@!0ayL{#uyVc1Yv$eQ7OP0KP zb{m9KA_Tvu3Vx3le9*Hj3C5-ge$S0`lC1W14;7m0c9*(X)*QetOK2-MB!hwQv0yDMtNIK&Oj~kCSKPI&ogHW z=~xL7{wVsfCLW^&*y-9`_;Wsb2C)4oTivpDWWPR=rp#AX?a$zKF<#`l`A@lU{$rNXTe# z!$(-gG;#9e0XHcYzKi9d4<#dB{uNkyan@2dkP5P;V@Hxlp;QMQLbQ6Em+`I6B37*Bp7Xxz2k-B{0bH}t z=DnYnOyH?c&Ee}GOc=4_64~8aS{5Y{<-KAT)XzHrr%fj{yYB;TcdoJ_+8*4VK4#%< ze(i`GGqI}MBrDz;&jEbNtRHuTwSM+zrmbs;i8GK;!BAu^?@Vt2Qx7*>HX3~l5QR;6 z+w~o9dVK|EiS2^&XaPzM=YwkCsCW$+<4(bpB{F@_f9uy?=`wk$tQ#P|mQ>iM5hn@< zE|B~&;V$QZJug51>G+-ul0Wcf9_%W#RY(o2e}qid4umDHvKaJ(H;mb+dKBxSv_G~A zBBYMD#kLCZwhBLu4V?HdN-CTdbx(n|a~V3<+}}vap~q=aF(Z6(9wH5cvN$gP&XsE) zxiK`i{OcX$<#X*N5PbW0H}zUw;JgdVoUe(m;L= z3xKsS^r@ol>~g(17q`JI=t&2O{3wjWjsGQWu?S^%lS-=}y(4bR*Ll>caDPD7KLRtd zs+oJ}rlj1*41||1hn35)!MjbNalL zVax|X!`KgK@X(rn9xzx=o07dL>K~zLQLH%rHnj6x2OlTd^W)@^F?1 z=^d0uJ;>--^i&wD&dAw-)l5%TMo`^Fk(x`gt}VAZ7{wO2ayx@TE{bOKl4ts8U|c2g zJN5&&3+98f@rR|M5061+N8jp~CVW7+7l%mFZVcHm@x=vBSb7l z9Fz`LFo>}k5^5W_(lRf3a$>?At1I5pWUf0;o;xO?8Qe^)NxcM8;GJI6i=Z*pyW!J| zpaxUGFz1;_tohgeRr?aqQ=;{Y)9kjyY5nAsAyjW`#HuD$7H1B|Epu<2xqP_{C>Kbh zdiMpcx?I{~JlN|Y$ge{OpX#r$%-Q3hnSAbsa029kcDl7dL9={BLL{+z?sQ3G*Yr3 z(P=Pis9F=ZR8R}BN=E9h`EN?wO;yavjaxa;WC#U)cjEf)cr04S{HPJ2{2g=*SWNlf z(?vv=t<$yOGab8f4uT3nopw+nDr{n2qOQ)1^|W=}G?Aul;) zYFy2~Bka{C-zOESMdH^TfOj~LGGa_7Yw`Dx%czxAlk3mwMvP`u5rz_p=xPIS4r$hBc2_8=`}7sw^B zsWhOLG@;$EHp&L>c?6^PH+}+4@9pQW-K5rBhbY`Tue>YYo7lNektOI8Hrty@+nay? zY;Sr~Gsuo}6RL9)YzVLUr&(=8DP8Xe{oi6^Q6S@aT%Qp{Bmd| zeCZ$E0gV7!I@KK5i^in5QjEYW#MSu(&5>%DCj8 z08tG-0}>C|A=nJc0&<`*|R>cJ6@*NKI-hp{%tgaZXNmU!yqrqzs z5RXsdj9{jDre;=@5yPa zTBc>QwyDRKtuFc7w@c!S$BToc+judk6HN4OPWcisiNim)$GyFrQx~KUFfagU1Pu;CBkbg-rDWA&4N~7-)81oD)=2?4jI7y^7rt6WtsPmGG922~ZQwnet?F3MJ2t;}A=Js!F(`@p~kC9ONR!?kT_vk(k$ zei5t4a!$A36sF8w@yuPtkV_MKfrzxc11RsQ1<{Y38UlGgPW&_+!g(b8s1+esS!$d#C00dBXNg&*K%T2HA^c&EVAM3x+3#+?8BK@U44ac%z|C;#ehz%fsaG)_Zjg!Z0S@3cKY>-ea{}?T$h|>wfO*~5 zor&@op8B>?#=msSi4z1q-Y;!|n0fl?rjO={6#&Y2ir*L(aZp)IfGtPIt7;sPacfW2 z9hN;_iv>D${hdLAYqkuVT6-T6l$&sE(|K9teGq5`&9dSIWCEfWh z0SJFDPqCrT!qT7bG#8xXiZ7|}PD}-=C^1O)-mr_Bq?Tvi#9TYCBinN#W2llKlBGnz--Rn2){OHoa|tXD0df@ zGK>}1j1jLhrkEKFmUMFS;Y2{$evXlG?s}TA-@Q0}S|H$|Bg-QXmq$vT^2Tr>@CX1% zb|7W+FeW6k8=!G?O_PO`z+vf>jk>}2rZ%3bT~nygK5xrW-l*$0S8`tZ0?b+P^N;7R zudy~R`Is24^%)7rXLIFY*)p+g7fn=Rc&hnyaokmUq;KOui+e{Bm%I@%y0P&n1D|4A zG)iI!yr1`CRaXyJGS#z3wtH+6HYQjw_(hV#z+VKlbv#@Fm4(+{b4~naN2f~b(ch;$ zl^y;~&p@KQ-A_h)o2V4N7LwzxIGmc|n?L#eU5Pfps{Evw$EeO_D9>elciQ#RtA1_F zQ|71-9rpmCdV=5|Cr|`@N%h~z_&JQy%T&?n{BFp_Bhl3A`+D(9_N_aN!ADdB*NH~X zH02BZ${B&298v&}p*a?{HI^Nb+v39*tb5PqmGwZnRGYCtbd!WYG+`|2tGCKgEtB~6nm@>}M`GOJg;3YV`6j79O|8H0sUm#>C11_xv6FAD-XM6gyyL@xhv zt5?>uXa>Cj=0$zM(u!x@yjl?-^1y5|kHF98TDJ>W zlKBLFLUV3>=SguhU^)7us3cfexW%r76YDIBb!Km5!n49Sffe(Wt7y!540an-f9@> zOkO1o<6y{OR=xt?p*JE7Bx_-k^#>hV7kfk?NJzv}z2F7Qf1Zh@2%@`nD$D`!p)W>I zur+EyZIa-|iqVb45L((E@2Zp(c-70=B?})l0N{SPcXJGnv_Pabho9%hFI0-r~6Z%{bl(p(crqKg8|evD?bw zHD+j;w7AoV{JyMR6dlyrA~kvh6a&*X(}*xHncPJuy}C4RZCBZk;`bau88?KB5@JaS zVQ(>}OU4?krR)`T#)XI&#*SC<5!k4sz=^V+BeFI(+fA#_cf9l*AdysdwZ6%_M z86(b%p)t?#Fnax?F7e}b9QVU-FaMd={p@^OgdeQ4(-u4({k81NZ}YZXKiu&qex#a@ zklFV#nmVVrw1lk?snWJu)Fu06s+@c#M6=)xef=jhK=~ct;9rv!9-8y}ua@#xfp%PE zj2P^XDiAz;L9|LpZbmX3 zxJ=)+aH4&s%N4TmyIZU56rJ>3+m=ZjUborUCWNR%ev>yp-%S)E~ zIzS#UyU!(I@mrLA^SvhWoH@-eO<1uxf?tl6clyJcX+?H+gSOR$Kh|z|-57O;cH@Ha z6_ug~y*|MwMS8Cd0vU>nEf(ig1Mh3HBVJpds{}mEYQoxu=oq}2s=*x&&ATK`#I7{P zMh29`cGUmEo-iSFHULqO>2eJ--^GvF45T6?Nd@#;KPsk4L9kTnXJS#k^`BG#8d4wu z3yK(mMXH7d)X3YfKv6YDEFE=dZu9^w#*F9O*`;1lr;IJXSSP@Y;%wX*`MgzRaV1xc z@bi4e0<=&Hj(@5L0P`Q=5sP((Dn93r>($03jNUUTdm@I}q%nJ{v>$T_0>u~ci^k#? zz17Bi1qXa6iD?PtR+n$gn#tj_t){(QJ63|cEIXFZWi|DGqkcDt#b2Vy+=(^0?!y=@ zfd~+QS9R9e_DJ9RE3UExfYyn(4l6Iu>?Z@o6*M|Q23Y4xW+Eu|tgw$O0y`pxF+a55 zt@2~88zou%$)5}JSc9dDL8Z)JKLtGv71OJf&8@ZDBXee+?Y(+V3}_Zx;uK8HE8NaC zk}ekN7ai#g^>~nt$UO?)IGuU+#chFy>-t3pOdc>q@*93v)0|b)1d~$6{r7`^GQ__- z7wZNf>s!F^_CwOcZ}UHOoww|PKxRhH$d_IBM-(}WiS`QE4E8J z78fP9uWUEeb|<#0PSPI2F>Bfp%aMKjbg{P&=%?Gv3wr}n&{BBNYL8t|vDoF{<(r`!Rhk zBv%!}%M(?d<(Hh-RFI_qSSZ|)wF%(gIY6B@M`K2wKZsXFkU&B5paiuH*n`m`Qmr7v z6@d|NjlzKafJb~}AVVbj4k(v#M+W{PnyLgIiVTbeS?d`9>44qZ06a_&r? ziPznsI#|teSIM3DPi~%I^g8$`G#dZ{-Q_hxrsQJTvnTNmZJ}OG%&;+x=Oc#p45{cL zaO!dX_A;t?_eApqa;fnB${V+^#nIW?6aWbc@yzb(HqI9W^R3-q!@bPGSkQA&M~y)D ze|j4>cPO&9VQ(qVVhnU$+ROl_+~k{XcV~^(eo@sbXML;vqF*$oDHOmngQr{1pn`sd znxlebai}1G*p&1#B=}61eNd$fT&)8DM|HIv_0olEy`&=cCkto#$d5NjwZJnpVf~dR zO3J|u`jr4CQx>w2TqCdhkpQLsrmZm5fOkYEwS`$7&W5UdwV*kVSjRU_$W-82^iJacA@G1W- zFFefx3i#F(-Tvy2=otXOSNMiiEhs~H`LJ2kjK*am@6IjFdHL-LE3VI0c0KT&utI1uRL9-pDO8$bP=bX7r)Q@39B=k0c7 zI?xg~E1J*n9yGK|)Oo%mR~%00rtOH*IzyY!RzFU|qJI z_N(`0ACZg2Lgjw?jCwD@Y?sH1ZUNX~Hs35?dhU*=YwgCMlLk`~F7kGB!J{1(G;ae4 z(1$ryAX}E`!u1;fbdp#P^Q#k^AnI^S9L9@hEWPSvK;>SHpJdOIA zdoCCXP@sHZL;UjE;E>u5pG8k?zKxlXc9RPj;mAa;6(H2;CwxA{impYsKXLBsiU_`J zU+@D&l?3;Ifnij&$00BMJDp_#Gf2o5ZLRA9wg_W!`Xn$JMHDe{uF0(u3s_U@kM-Urd0hIReZ-_>!z9z1Jie zI!$l#_%y_NXZ2ZmD{B6n!X3R*jd&f~W$(+tJ4T4Mgkq*eMPk zXK|xBgZTuqqd97DbX7q%X138nSb7wMzNUq<8a7#cIUk`OoIlX9? zPoPW=eQ7oUF&qc`*X((6O@)-XxRjQ89g#(|375P9q8kBrYQdaD=?0@26ktMecj9%| zAaifO=w!z%uV3` zgqpV6i;oh^tYn^jyyUX0VmY#6I)qi|Uo%37fmi|TWGv$yO73(>mf-ky2u}+qmQ^H_ zX${9cEjW)_(hkU|oiK9KyaQDJy=ePpi^6Fe^`EJGnxU@A)90o*Wu7U?cuN>7kUtx_ zC3jx4+nHiYC+!8b9 znmnw=l?!HN`Wc%{(O`VCqwoGp_TTrc*CPOhG6A8QfcSKhlPA}N#Ku1>&p*2g?n3;t ziHH>j+(5F%wNJ-sW5IGGd8=(>1Eo@Hvoa!JEH9Mw(ha1QN(DY8B34#T%yk(Ic3gU9 zy)>Iq;GRvX2;d}eNqw^%RJwnZ!of^LCa9>;-ugRd^})c$Fj=T-^`@v7o*DBundmNA zilfl<(N4?u$skf)GDX0i7LlGVA$P`=Qf&~|*;&pkH3S&cr8bPb3?}+1F&b|~a2h0! z9%#0w5bzSX;Nq&Cnn0vUEHd3+{qLnx-{H+eqLkB)S&YgTcn}eAmIm6fD@Wwe`UXK z)X(fyO@RdmL-EQdo;m}E<||KC<@F%nLR%_{z;7d>3q+xQAEh>v+%U^X`9PWTTUfSy36Zs&AuLNNj`14D@C%%CD!oVw-_V;80N!C z6h6H;3HAnSI51-`d4c;SRFLG7=Yxxz0Brlua^B;Ab-3{9GGQb2(rAo$^XK-9OFQoN z!$;j&yV_TAeNlxGzgX92vk|A|d4)n@QP z?XA;ptbGNM?UHhz@))Hw<~=Akk>)}lJWqfB2oZjC`hQ@Dj`QK+V}<3$J=zeFp`SsG zZ^JT3j=>~Eye$dji|bEnSXgTO(mOWghuSR%7OGSiT7EQ|XKq%G*XP@ls!;CC?jBvS z?~Gk<8O7WwQ%Y{>Ov~*&WV?>#D{kqrVBvbSeA2p%anhRIy_Ay|^Z0X@cCe}WNYW_o zyjvpdY(qsS57Ou1`O66~Jq`bpSocf@lRQH)bIwLcpj1cf)D|C8Cv$xD;$@Gtba5!) zFU7YKImW_Q%o(wBWNjxg=iRc}^z+atowaZbP9Us0N3c1yY2!NOt<_NT&X+OvTrWTz z$k8VMT{)pn{^6WNfX%4@tT`{HXq3|*-mmiP3a3-fqFb^Fnh+vb9D?{!bgranbrqRj zE>xYiWa1!GFW{94ATHfz3{XZ5apUo(9ig2qj}ua^2V#JTHcaSYZ#V>(rZ_UgK3C<(SBST0O{Kk!v4MLd z9_u+aJ>kbk>CeF)3gcx;84fzZQrdg=-JA@Nv zz}-&NCC=?H3j7VE?RNtVe%#pQg8K^uGe3CNkadi({Kp?+Q0keIqkG%^A$S+3mMhMe zpJ|(V9b}0eHg#zrAQhtyg=x{6_Qc5j3d`o^O*swHhmMC%8`>$>?^wF+FQL1WCeF(! zPizwHT+g0G0!4;!j&<)E+ke4|XnM84W({&|!p~H{IPN1$Z@hI?M0&FkT~P0yQ(~h( z@<)eMRBvgLfn;Mk>OD4T#OH*>Ei*rno9|th56Cl;q<{mgRY=nN(Sy&qV6zT!+kTMZ z&7-AD($dFxQv>h*!yRyB+xOyd$2VOO-$(!5L^QjE(79`p#tKZ7w4K^ff!Gfq7&IqK zFp^?bNU_V?)WTD^#+^+|x3ZQ}gXg(-ZzpbrX;<%r>Cl>3aif0GJzgd&59xi66`p9E z8VTAG6dxB9zqI?9Uwm|2WInXfVy7A5I@-oMx4-WuFc;oDtO?&VmT?{r+sfimksNjZ zRTau}_@^*6XGc`+p2xE4@fh{A>bn)T8=LR>KU`S}qD6KH=t%Tf`vKGa608V3;XRT;&Flb;qhE*8rXU2T+eas;}(g%2K>JoVM zP)iT;DGIl8jFzBW+zek@ioCL0z9d8Yh6aEHA^dsa1Xj6OMCKs>MOjuLA#(2#s5pzY z#$h-j12<7eggbExz$vKz=>p-Tc)wn;YeR0zRBKksmEG2;lqtiQlqnhiHhIandze73 zP>a;`LCoCF30}F9!#f24ISUV49?^?Lm3rsgQ4ZjwQbCnj4rdX1Mh9Nkv23CP2enDr zDrX&dsHF~E!9@ujh&|~5Jd929RJTXJ5O!EMG03s zM-bFmHKwdAze8ZCDXoX$^6XS#rle6ME1Jhg?th+m?{OSvjTVz&DIil#VjWfwkmru% zH!MURqaynfN8Q8mX;-(>AKENvJB(Wlo=0gN*M>@4h*ut?d@jdXQ#S@o#8@o46$n20 zNrqlboC5A^wfx_nzWjxLD#9?SZFMMUi{y2#|3F$r2@GWF{R$6~u)+*$wU%qJ(VMuL zKR7N)0!8Ca@=^Ya_`ezpZbVKT7pEJMrT6`XhKTlKQm#|t@VC7r`Hd@@%^Nl&e(xu? zfn%EmI*iY%vUu{~3EYY|*W?_r$R>YI#L6WGgqc=p8;)Ds`EwGMBdYytiA5o;lG_SP z^$Z+4Fe#X_RGmRnm-8hTcN3IWi0$bWcH zv;?9OtGn&)6=bxTO02GWJJd(`{;4dj3rIllsJ#MCJ@?;BsRO^=@@C}VTd~H-$8JVO zcqoI`B!M*$yk|`}L8+#;bX0`tvu05DT*&BUAgAw-WQ~wl|7*CmGkF|#lkMS6YMOE< zii1!R7|N;Qx}*U~c|rWGV$kquE+m$1?u}leb#;NbkIPSmt)l@MlLP#6DE8UVRG16_ z=x;ERR;&c>2t%962|ykCLKk|=FmLWKAS9D%>&O$ zLcjkLO^v)RGjG+vPGcr{lj3+KbP2~QPLEwl3WiCNI(`nAV?Uo zx^rIK1P9tRZaBv`_FPhj#O+yqpLQXG@|VR`btJ8PeFfxLc`RW-x?nTZT6Icic0T{+ z+^uUzm2rxlM)+~0u&J9q)adE@Krf1UM+74{(yken&#wi`O&vc8_3OIntoJagY`^fP z)PUbbbMN&cf`WgmS*E6qE3w7ab09WU%F`fHq5>xvJ7qMKWHc1s&n+#A(Tyan#%&Mg z*g7fLbtue}!X>k>&>Cjfyx|!Upi&KQOfDI_S289nqa=IB%I&+15+EFn$z9V{saAjc z$YklE$&&TZqnCMBbmM+dR%uC#H>@=q+O&0@-ps|N;5QNX3+$ZL5?3|v7evl_5@$V= zXG^4Iws)6bW#vEYgKZ)qiwmSajzS7N0xdk}gEW8hb(r`Sund5r#MTiBc_CU! z79DmpS_`Ix8w^$g4G2oO3aGd5-6?V51Xzjlq38=BJzL^pT;c-e*?kUf6`{PbPQ`72CpwIj%5HarW?4VVO)~LA4;pRU_|>ZCiqMcz)&3> zT&b3t-{f+URWrjoZGp;Qw7|Ugao%<9I~?ml?A*Rcbi+fPuV!zZ8kFvr$Ct6$Tm;~4g+4u0gC>P-dX&%PIKR6EmV9y2h8T+1h7HY-{dpkz|!V&LA zji*jgGdQUk3^+Ap?%IMwTT$>|0PMy>{uFR+0K^;jMgLi0s`?C7{S-xgNvhOxjfeC> zP^uMkq{i$>4MQncwRFDH-t`H+!NmUP&(n1*Fd-RSNuey%nb4=fn1BVZZ9NxxgPOS| z8dg{3slVi%i2l@Hv9|Sqxl7w3cbvzLsoat}k8ifES8yU~d6oe4RXUc|a{sF%$u^Ss z_ebuir%1aE)j4Uf_`lUrL_)D`GSL^GB&;hSbkf0d+lnnmd9g5M%&Lv#ZPvdAHrxcxqOX9rc zIoWKEKZ@>46AejO8lv-ZqXRgBwg?NjBhj969Y$Ct_B`xf9+s)(Mw|_W!2k`mxl;B+ zYI)adZXW>#ZZc|8|H+xevx+zJ&Hogf|EW*(-vZD0#69EB*n!~aGO6!LQ6Hk48yu7u zK3~~43D``0Q8C-fgTo#N#*dzpSSAj*_!HZIZ{zzg#kME9KXSw8AN4(n>w98O>Vsmo zgWG%gTR69=-Ox4_Jcy``@&qigQ}>!CD&6-+2PFE}gYE;59&qOWN70aQ&;Mf?`2Tq4 zoq*1cB$@efIw;)yTJB#8 zpkmyOx7b&{8-D+;F=!R=+nWIur0e%jg}>VWYaEah|7r(h%}#(_UF*T)FN=Nd|MfvQ z_m>{Jt1WMK0uV;fcUU4pq;o*O*XuM>H6&cQe|H#sl;D2Yx`r37W>I#VC%t=P^U(_QGfM7h5m1-nJOTL03DBE z$+lB~Cer*-?yeu;iCCR;SsRhNd-s0Z|8@VF#eT||=l!+YVvT~XQ&O1a4O`a@srv=*kJhzZt#Hjw zwhf%sYH*a8^!>OhKUxk8dDhywbfZ3{S;+9+(K>j|;PRAj5FfYQYyWzgNBD;$M?6ZG zP;-~4%JASdtFj}>MjV%h@zOnsV|N}_d9y)jHP4s2j7N4_dEKN z3Okk^O5#H=l*BK@6Lj93$BC2Cw6vVOhMvCvgtQi4JaYciHESL!T+icz^m0Oa>07u0 z(Ki>*Es!VzU^Rf8GNWBMYbP5hbFlRgPWdMZ&8#VE``N6a~&&K8G3a35>@ z#*DeL5Eyl+*|`V)jdD{_`tyuWU=zfnC)`-in~_8rqT0VGE9XJaO|d>+`vBh^a!3x% zffGKiAUn#etqzqk{B8wVT$-TTU*PnR9GzeUh4H)9`K;RhP*S;(6X>d({#TQh+{um8 z1~NO^!Ks0=I7RT2X9|44CcvT$iE~f4I?FpVgO$wcWMu0B%vtv82tz>8-kg@P?p$J< zNbA*rVBrE;zpoD69BLPT8DRy4vv@|g!7+0+DMXmns#?WL8WRaEI}D4!T)W@Kt9{&o z+COyG%r`FmP%HLBW6WUFsp;4qAM){!?O|D>e}T7==-*9U^=)^M#5y^<#!gip+Y(Bi z4QuXl`Zj~Q=@Sa|bK(Sc7;ypytBJl8@9Wi2L-uVEg)jUqkD&Y*BfL)fkdqN88@FK3 zK5e^igT}6nm@ulw^v27{|7^JVjeeHh>XE2DM1|#F=|3fK6*fn$EH$hroDVIPBAEZ2 zpw|3;b9I*0?QLhALiJP{w;!DFzAG;A{~;Po`~(Q^@6aVF0$*1#TBC+mPIrM)%fWMf zYps{S*f!Yh?QsQ(ORyH#$mU;}B zsc!Hm%+v8S($jaCFB}XQGi$tVcglo0zt`BOBj}v4byG)SoF(#N;Fc_O-xQ+FL-~CS z?Sd(TZ9wnkjBe_n^l_`fHzOv>mbg6to4>9HKzz(&+Zs5}Byifzpw8t=%ArAFgg5yr zfU7xe<8K&v(DwhCyhZgt2aASBtxem^xdt0~U+6q7Ul+i11lP*%n*avuAUk?NevwmaLCU8Vf5LY3JTj$3C>U>OgQ9eEP zKhC@=QQWN3^7{W#<$(Zc$rNa?81UjzT1{85poO&$?PliI0uly*883tcEct+}|A_Se zaq0p0UhhE%fC}`B#QQqQU-PQ=>c8e>8Zt8vY68q*>~+b%AD@yR7lr@VbTr3&y46&mOmiD?ZMRe-Pwr0a>s3 zH4PA-`f#i(2OLJ*Quga_o<_SJM8*G3d-eeysjV@HIKrG`cqy$sl<*Y`N~G#ZQ9ycN zP>Ep`ZE-HC%dyi4xg{@o7{*5DC9d=YaZ!I&xg?Emh}>L zdgHexbrW`YD6c=CA2N>S1mTiYdzc6|I?;&}Ae9FvTEyfA{V4k>9^yiuIty)Gq~{mz zHTWGw@P5McDGA}B_%b#09Zc7=c+y`?~Y zIij7g_a=yB8Dmw#OieT6jySUcQ{!~O9FZ_T^6eV7hmnM5gMGe~G>BWW*3t(!{vQr0 zfdKAg7tezqjAoxVwSClHa!Q)vhCE}!$2aa=(D6`ans`k`bfa03J`;UTMo3Jd?i;V_ z>5t>TAelIWv9TLh`Lc`2B&FWz>r2aSbNiAEoAj9zGPX0o^Sz?KwHSZ7~y3~ zoSGpqEhN$xhp5tZ)_=77$;&d@1M(_?F*ccJY4YQgo+HR)0W0%qzKB634G6AHZt5eV z>zWc1$m4d5W}779^+@dP{+getTm_T>X2J2()&{?yUVSag>; zsN?=kM;-Tn<_@~Gsckv#LhRlOgL1EtRSkc?+ap_MZ2*^NKAd^98!O*Z#GnvVdK?4- zdww|Kuv@H{YIaQip!dXH$V@K5QREmS#wwBA(2K~d78b=bp0=!b`EtrSs!9y*8w^QG z0B8s7EOdOR%LU8E(GT*rtOt~zIPz@pNuMt=V8KZ2XMS%2{WhWaeUHzGfm8m%>T*-A zLh58j4-%S=?1JBAY&--7EXftEr*5?%13Sf9oav-&K$8nGjvMwgM=1OI9h&pB$<*1| z>jKmZtv1~5_B3;yNHeI$T5);d7oENEF~A1fiq>AD5OJZ~wBTI79&$*XSa)d7H~moa z`?)hKVY;82KV<_r6Vi$qla&$pbf=(xfAWcR(9EV+Cu*C2YP!`RdTC@j+2E-JS&1?l zYeTW*rC6?*C=P^LDgNB?Cuh7kb(#exS>3rR)IXveXdtUCTRsxwbS&5gspgEi<`;t( z1~9leM&ew86X$mmMTP$CSe`~bO3oVp*{x-1@wKQ1KO4{YpT7vPz_^dxVduWa!97KZ z^i^1PbOD#2=c=*iDld1q)o2J3P4WOMR!Ve(-)l-*!wOQK%zUvnjeue zmH~}Hea~2B1EuW*sqeky$58nzM%XdptO1iaqcO{M0PW6wvkpo!Obt?!Hm*bGFG2QI zt3pnx#5335tYeM@JEiXW+gGtrpD>} z#r2*#lJHeF;u2f#A0tcN%z)yr2>|!_L76W1BGkz8w#h1KxfjBzGqm63(1E{|GJ7bB z37O4@^vDk{05Eq|KJTb;KP+%7*$DuH3Z%nGGPZ}^X`3f=zzHBE6g zO<`@keh`$zktqJ}nH#E>G8}59kenfn3x>(JRux!w**w<#N|vSWt}D<_nIc#=Nd0M$ zl1LG(h0!k0o@46f9>h zj%1fFGQN34>NvQ#PteA=5N0i@3Sj#6Rfp`&Tt7SZ8&?sXh{x{~WV|H{a!Bey%SCw`?|QQ7MiDh&q}kw8%{J=wdL@OF7eQcJ5T*%f_GNG+) zz$EFe;6n7ko5Uiv2q&pJ79#lyD}t9BC`M*XF-`_(4XmTD0?2rP3f(KNawg z+8e-@-fuSedWvdEYUjB6v6dggYCi3CNmD@qc*J<^M*6UJD;G=FMM!eTgM8m4M5hu@nF*VtcW#3SR>{S{p z+_qbAKK8GV_)E*7?uCh{zaqb!Ftrr?R!~nQ;%agmd!nU^qcMVZR-OEKXC5_AP?QnNOGn<-gE5mCmA)$LaW5{<$r((BwV~AFq7%$P05_uPl&v>0_9q){dF`Mg&%K1HHe%>WM>NO~CGk zMmwH#;DWsGyiz&7Dij$nhMBzLfV%w}94c{9Pb$YV`~tdvr00ZjLPKR5f`cj%87O@uFE_DbX| zGEn9=yChC(2q!hYnPXdY&k+p1vf!qD5SGw8!R`MZBw|x?#4zpAq6XDJcnX0jKt6Y8 zEBUJC=b%0h5HT1F*KtX9vVbwp%0vP&7Buf8j!B}-d8;04e<+=4+mHCVJ@B0qzL1=8 ziMSub;}&r|wJXG`$B3?0Ffh+vv2cF!rBpAfDLgj5a&D?@4)z}z)F5YJD#nJQ&P`Eg z>2nkkKm=sTk~WOZr4Jc=GKe-%%f+*e@A7Is-J<6jBgVv-X+VLF1BhAJ0}07*|KljI z1Kt9lJh&??F961ZAN<;xC0Rm^ZNWJZ$JiN{*ntR2yiOB9Td#rJzw;EcrQ#TL)l;92 zmC^REpJXMMf`I5=bHB;Ep-tjFm%I6R5M&++$0Eiq1H8^kSgH-L)uXZNnr16fG|O2m zD(IU#z5(dac(774rwg<}fn9{;aW83<$IFAo>jzF_3e@>eu~X|neIC$vGXWy-3@T1t zZPWrtcm%1JdavuA2awUhkDalW^AFWazx}qHe*;oIK%?+?3R=36WHBbpPL)VOw@EU3 z{n)>F8ld+A4hy_(IU?|O+w8W&>Ey8;QilTnZJD@ckW?Zc-4=TGeizqR(CxiWm*n?R z1Z?&Awd-x!=;QY{XA+OQpEyq2v-4Y&dcq{p_DSJ!ZL0j^TKNdvUIlSYVfnmquXftT zrb$-KGmxFz)P_lx<>7by7jH3#^{z=dC)KeP{8@w?+kSVJud=@pS!HL{kMh@#0x07D z%ml2Gf?mn$NEt0YR_FjHLy%EYT?7Oi32rgVuH0g7mhEWbmNJTWaEW|2!+-R^ULe*S zN<|!OlIsu$M4On(DgL9A{AbSG+7g#~EiT2NA9dgDWPKGzn}1x6_& zI-;XVuEW7*D@)WH0?q>#NkIpjyl*pregT^TlzvpF&no+dlzvo4&Sy}CKX5+y&)*;f zmsFQMmyxY__fk?2Xgm%ud#04|WvB3Eg-%I9LHbdeYD25Q;=m%Q?$!5q7lv2aRXW6* zH>db5Z!v2M*0X~?0OtZ{e%ErhAE}8|6`;!rRa&WSL?MbQY@LGui_E zv|wC&<+_U1?Aw)%50MYpdJ|5$3(Y~oO9EwCRWrHJloA!(MxqoAO=~@mi5kT z$6FIhWCMX%#G0*i(;0fq!ilMEHooH@c_Ic?2OmQ+80?7?c)QSg%+R{6$c?>jcA!>I zvehemaI2cg;{Tc-QyHD{rsR)|(z8`fyXM<=%`8-}hPaEv3KxwRW4?T4kkkqkKAyVJ zR%|&tN4_U4BuUgKJPKqDF}r$W6Lo)Eu46CX{yP^!SBEiyXIah7zb3DJr)1I2JB#jv z4ND$Bif)MV0BP6Q?GrJqBfn0dUwItW19@H^xOju@-J4*sas=H#Y;Pz_69rffBO6L< z1zFVGk6+vg==9ivWmNDLWhXn(0LbP-#kO}jIpFgvg5q2Do|9+IDq>gx-F#a&W?Nhi z-2jrzeTN5ESQX`PAS$E0{uIwzhsEp5KEg6NbFPXHuX9;&gdmvFNV zCI7H{ym{C#kRx6Y6bHV+@J6_}=N6xMNgsj}Y%tEiMu&Uaf^rDA{VkAx9uySEfZi0@ zPI!Qw=pZ3|b?}wO3Z+#gW?R}YhE+R;^*>CzXCGJ^Dp6V=tpBg;DEQ3b!A~g_nI8xx zZ3n{Lg5tM81Gh-F|6*Cs_<|g_H>r;=hE+3$_1K%@gRgqRoNe?d_gNspRPxUV8zza3 z{&o~yGRDb$2c!$4k}VzwKtJSY1dW47xoN?atYUo@NHU;YP28LUJOeu}j{Av=s^a$)CwX+u>h z-v?r!=5L5&H+yGuv-%*?th=7Hy0*daG0CxFvYuwvja<11gUF%zAaY_Xvm{Tgluq(rGK?Kww#n~V=<=r5~RAGJ-ebP&Wg(vrh z0jm0QA8gq5)%u0k>x#145&O?!#&CigK*Sqc-l-}YB`^W!Zq|IKg=Uw`6rTrdrz}bRu(qd@y%C2D%!G_R~ zUGbvY9Ky#T=0rO!_#?5T61wTpFJ~B@-vSB~33R!Q2NH4%I$!l8EJA}BgIKyYWCFh2 z7(x&q66>D^)?R+iHj(Rz-oB71AxHdd5VBZPXb9uf z^l<*{$)FVoP#P=};;s4DYMCV*w%FBRoJ`m0!Oto3*LeU2rr6?w;x#ed*Ks`0DH4|3 zSKg`s>GkXwmbB-`KpWmq&AL0wN%ys~oJt{x51Q0qf}p7HFbKn0@^TNnxXb|YKoK`? zP&=(&*_m%~=v;$t4Eo=w<$h(y1WgXVY~Uy45iqzhe3wUKxLEY~5XkNYOyAAu+F z?x7HLpJ{PLmHpn+rW_{Oib5k%2s#wuwo^CN|G-N<@Vag;bK#^1IXL`}_aD|Nra7>zU_y?sM03&b{}X_dSO(KL8DyVw$T7-$qt@ z{V>3lbZAU;#yn!Wx6bC9lz0(}avg?3Ks)>WauhDC?uLPY;}xxi*w+tR|4r;N)ww-j zd()U9Hg6cEAN6JVs@X3djH0eTX6-BG^MIJ9i4||xR@1=c6=7H+;P}_H&0Ukvn!^UNdpzMzUVHoxxT~iORiHuAD z#M#hm696u5s>&XOis*Bs4JbNvd55tAe2Ank0A1$^gAjw~h(I1{4U*~%{by(LSsp-1 z3xKQGX%;-WB)!5CL_tc**Vkiw!Gh+|;3#(Ho_%S8&xEV&Loe4P`pxL<>;c<-kE=4h zMmRchC*Bs!pws_ocBO0?p%h>}EBD*GW`OQbIYx`Ug`2?NeLr~2P|VWIusY+Psq-V+ zV-VyR6x1lVRXB%IM@{ANe0sG~L9OL#;Ck_`UFCU4y1{0bl6tpSrM@(f&Wg{wVv`jn z2rfL@(hFUayc<3Cb$XVE2cEbC8x12+*T*HUkFN%@kjSh;o$NyBI$KVYBu5x!F`&a` zc#dG~q1x_U(^eUZlSi(vtLA%=tBleg3P7Nl`R*mzjSe-2LC|AUwsz=NU+BcKI>gGo z@din5v)#&4wgZ-wFXT;vpS<>-PTqNaptn@2w-hlQbBjnzJ$|TaIIw!eJYy>*{6@vv zjlC;jJh&Y$qHg}~gwYzJYg99_~ zw!N`QcbH%bLSf{kCBs4kb>W=5g75Oi!Oa1KJu}(lPmd)}?*iDnu15m^$ph3Oz!z{V z0K<~xnUDf(aqtD<;~)%JM3eZtz!>^4-l!5*wp2$BNxGJgZF#c`D-h^45czlG(#wm8 zo1X#hNh0}CFO&e-u;+(s64C24J5}JNlJRX2Bv7fJQ6LLRS{P`9jwW}Zzy*c#H}dZ} z1b=bzdLzI;$;V*ECrE01Hle@NRy353g5A3eK;j zxo+fX4yH*h3 zUOvaZz7rtXxJ9}bIrm105x>xY#pnv3C7R%lSF|s!=$){*PsqBxbzo3P^fCs077?;Z z54b9W7K+Pubba9|uoxS$I($@>c+5XJ#dylrb3;DU=1xDKV5CyFk?37wILC+CMWS7E zK8^^&b`sLvm^R<7;Po@JYl1@attD@2c_drQfj_U4pOOc&=jQEJ_#>50q#93&5Yo2@ zx(61JH@(Q7Q<$|A2o&15_Mf@dTB@&S%K5FCtmRfIcX| zC`M@Gm-!v*)%Ge7&+GU-wO!zH_U|=l&?8^FkeO7q$ z$lN!Z5Y&&WM|=P3v)XxjPv?Z``(Y-0vBl=7u$i2_?&z$&q6^-jvQ$ss@CbRhUV9^W zVh7&DnLV$T!JcjFRvtT?9BQGt+R?r9ai?$U&h3xjA=F%*$|oB}9xO|^E`+--xbsOP zSaHcR(u`X&mILhP<96`YCG`uhH@p6FPrV1@OZ?r}sxiC1#8sXS76rS*#YMnagrMK` z>%ij|f~3RyHf1Mzgn=15HSD}B09N$vI(UFL!S905S##JsKc2pFGX7GS;t+ z7@u%5eP^H!&#adM+*gEwnI7l?q%(jz(-S-DeYTz&00Q??wGc*=$hlmE;}Is8UrI_U zd8wa3CS0uefUi7YDl<<8m`OxWo2{pLr38l-Xz=g{1H^RJK}e)MGFNgmR!~JI%URWtO_A$`{v0 zdj%%$Bod3h`2_%AQ(1seb7!1442}jQnI@}T7kYu7$Tq76s}!GCa=@k{>#WUU17i>J z@|}CBZ&G&N`5|PJFJ;1>ia*0!1o|Tq(T?gd@&zZAd9nrsNdkbn5zwh%%84r8bLtbP z@Ig8=#S=?<6E2>q%M+PLG%A8gi1|QDX3;b#Zo5M)aLSiq6;Ne`h zDxy+B$vqBKlNs`TA;MqpW5iyD$FOUTUb<;{5OEeTeF*dpDL_>Pj(~+&`xC4?!pfBc z>Y`$Cz)c?a^LN}gY23Qm!n>w(ty@~xIdE>s8k=Qtf|wQpP5U|W`pat)8|6)m2U2vvv^JOyX|(=o#ZmKo_BsDH3@%Cbe*Gx!sNv@q z!PkEs_kOMatF*k+S7+^m_Sy$Ylha$z+-vuxY4eO3b$Db?(W~UD>VJWPfC{_Mc(5@) zP}0LztOPZV7x4s$GAMmXLkIN+VSMQ%ii#3k)ScwVo7$yGS(OO_8$@drs+XTWqF>Nr z7y)EU*8M6<8qOa5UbUqC12ViKPey?ZxJjt}^6gm5P>QjOC5!^4lD=K^AUJO`7yNZ@ z@zEy!BE-tE{FP$|8b+Vr={@9pZ=b<8^>E>l=XWg6HQe|;7fhr*)B|gM0^Yy^aZ2~n zp9$3&G&PjJh%<&+sbAJ#sYkR0Yb>ANrr3b8NFPW4La*8Hz*<~%qlNBAS-4q+79P!w zUOvy^Z40&v-485A!7nA~D$ehL!u5G;xmDemjZFy7*!Hx&&}UlM^WuBRe)&oM^4L_f zv*S!d#S^NG?R+@z$xOD~rfMO-YUJ@0!`Abkq#*@nsM;iy{Dc8%W=c3O3@1YbU))G& z1sS$tRinEvUzIaJg<0Zrcu=s>CaAP~!`XeS$5K2d{^wp~{_&s;dq+#Ww%vdlYx;OHqDQlAhwdgrbfbiM?O zLV+&N1-vT>S2cU2u+6ThT9l7GBL}~>6S%&+atWmswU-!t^r2rSmdv_T?>wUCm={(MMb|KODQW zQRzg_ugM>spM3r-XUevr{wy1RPkqaG^EcJM9htbQ_WZ7*W4$DDQPuI_53SvW;UcxAb?rd&YeS z!%-(gPx2D$12ED;)UKc^)w3k6Es#&{4_y<=YPrgm*tqj?^8HB29;|}76cqcB0Jtus zCI@l^7j0ifvfx6)A)_V=cd-Wxogo@1G1U-KfUAUpfJg%P^ z*t=M4u0D2IPRZS`DR;;5b1tT5nO7c@K5R&G-f($oI3VHC?tqn7-TUqZ?|B^Jkxfqa zBA)mwFp=Tsu8U&mZy3c9lNOL5>sri~q~jI_E4{Tx#PUQz7R9bCM{QUa>KA}I7H0~7 z*oZ6_XG`2i?(u@t6~mh2jsTAIMuW$VAATxE>*UmKAHSe+_zD2Y0VNMGx9w<^JUmAzemf1C3Oyf#8Z~Mvl!lS@2ODB>b$Iz zc33Yju&eAx1~5ERb3cPLT8!pR+SY%VC$6({7&+TMBB^vL_r~A1%o$AI7t@FlHOcNq z|M6$)QM%nlLw~ROFvYd92YAvIN`EbHJot;mJ2ayCew;Kq?vQ3@geWblJeDK`@bohD z0$hNm@f_U+mY-V}e0nl>#&XfQIKM^pCan^?8BlEu#{#r2$+2smr1-p`=%S=;+iwd_ z)LQrTrQk;z$4{th&V9}gu2YUTNI=3}7wGhqBgiQovg1v5?&i&@r+6mHD2-TvJ<2@P z2ZCS^&lVj$P(vBa2Gj>EKaiv=w0Fr|%~nKiA?bdr2Ea|Be%hg+{-0nX1BI z+eMZ0VewXVaJ{Z{grSaPmlf}OB)}-dP@1%{Sn@*`QF!HxOn%s8wWGts=THSl4dCIvV!1LH zoh9D#Zd?Adh#glIloGLWw&C4#NTd<;F?BIy)=zz5;!9`hbxML?n4k5Q$i(ZN+E*4t z$A^K61Wdt?%fL9iwN_qcfqEb(Ev_E2@WpvZ<6*;Az!^XqtzD;lOjZhEMv$N9F zG9oCKe9YlO9(;#14tTe$MzLeoF{#rep-K%*N+n zY^OV68Ntpuuq)m&V&N$I0=BPe2UDbO7So5fVKRJ}z+^!QRwOBxya%ky7+Wq1fPUyh6Cvqn?hsP5%7shvnU94n{)$;cJu?ur^TqSJ|Ro5=`A(b)*pK87R&pED#?*bGPj zwwWQViHCc)Sz}qr%RH=PWmYmQ>i;RkjME`Yr#{Rc16qS9tso$s70F6o1gL1iz~aP1 zBZ>iY=voSV_g_6WoR$yt5v0)nr#ce-h9vjf zN_4FwoYqn9(*N40W)dOy|F3}68vGnB%?WyF`$_Wu+iaNjuwnzkz2Lttv4VXDQ*$~n zRDOo!Pu17LwH)vFE7~*3LV1fo(HhI>eX3s@9{)A3bPS;--q`3r4?mckJd#(+pI5ry zHP682X?CGoUWlKYEW0{NV_>NFuBL-wrKZ-F2-ATf^N#9T>yV7zMNNlLH`)8hS`ib3 z)^;ktzyIs%C^!i1)lsN{p*hb=&CGH5`J?Ju?;SsF<=O;1oj$%SAhPSXG1VXq=a7R! zvIzL;G=kDay*{HCaPp!V8T&%QcVI3zS>{M&k#7?|k5vzklZ-P4vJDx*H_83#7K3;g ze{ZuL(}>9`fJ^7;G>z0zlCkJOwmPUwB7AQCYjCfIO)?%bwYr{|WJjWP`~s^Fn50KA z=49nS@CTTgXkT_MJP>`XC+F!w@)T}guV4=OB4J~~bgw$?L;WpNLp$c?oEE`Iw7(IO z8W|GVM$~XGAk)2=xq`0rEI$IF9r!RQCujvW?eF>u?kXR^D;XOZSHs4ywnnu*@^%@H zmmJn~=*(wG4l^We=OAMtYr|N{w-pVmG>eMQ`_KEixgT3Q<3E4K|Ik{(zYFR~HJ22G zYAb!+nq@d0@sfOebhqY<{_}9Hrzu#Z>3|&=dVJe|n=z;3XI`lTl^;fi;@8M4EruK* z%CTzmSAf*NGp`ip{@=i3-2?A-t8b3$tB$JH6!fmqY~#MMn)7orfdd={5ncZCbU1tg zZYFMdlJfA{42w?oKco-VC#VRp@-F>F{35!CIA-%o|u- zrPxrT2{EnzUWK|f!!`~Kb#%HgBq3*Yz{Xp_bdVf2&uIPYi|T)kll_lYR)NK@qEItzL0*n)%JJmua3fMI-IL$KFzDKrmYojAw4h@plxtMRnvi6 z16?jn>JJP_3=G+Be3w_sWqAar<4ayCln*U*w^uLfP7W9x`bXZ7!nsubU)!4xaJ%c! ziV$qSNoT&MgIgZvzrL2zbTG}?pJ(7eEG0rI_^*cC(ZssDRzac`2%MzyoBF!BA1$7Q z3Oj}4%vkW ztqhb_(!Vh~lqfC(8L5)Uu>!1QD1J~{@PVIObGH9H9BzIpe@RDn%r>HTxpdFB^m5w*f=Ubl(PS1GgsPi38?l)<=K$BR~?WzgrK-^ zQLTXnR`hUrMnP*@K{$bQfaB@IENd{*CNYjudxP0)E%US=LX`rU_p2}b7 zniqntb%ck>pooU_4Y>`&<+kPyn6f5>OP7_9-@^VQd??ahWntgCU0n)LSsLRxT^HN# zeF6F^qw_c#G+l>g7j)pdd1dJPL6GZ{w)Rt(_{8Vd`<7=%p6e#qoWLukS{hfU3L8iC z`rPbZfD)zJUO0z*gU|$J2VoW$7=hNT_krt%9H*Q(_bfuwOz(Lp)V3IJNB6~BeG!36 z;mUUh9SBOP&bv)4BMO9aIx7kA#LMtKc{ahmc8$Lco;{&gmoNsx3edkhy9@i%g=3gw{M2$E11R%)ht8VBXUdR`zI zxAyx$PuN1S5k`DDomB*b1awD4U?-nJcW5Nfm(Vcy4-p&vp4VJ7HZpbvft4*`l_jA~ zTi7R9Q0BtMajNwBBa?m&OkRhp3F!xff&`^l?bN%rI#2{V#T>ttOx85F)4dZhqOJGI zxb^N#uSRMOEOo%=K}pCo{C@oWwECPep`5tsXoQg_#ZG9MNj*oQ**rd%Hm-d9Rz$*d znEWg*;(X^(xb$fZw-HD8O zmv~Z)70)QWRG3Xu%j^7P{7dXRihg<&@iuAcBOT=*fF;?By?Oyeo*ueasB6)M`I4q- zs>h&V?2|}N10%Q}DO&oB@E@6}FR!TyvX=c&Ho;bwU`4%h#0}f;RZ@0)Ve#(>hCBVn?@?=u?ppUmsIF$9WOKFyR?MD#K&eLPWiuf02Gw_JZUjN@z!j4f zYl+-_ICnrMGOx`I&CMf=S<1 z=Ck*j%GE|ak~(l1!f=2%vz*Ij6=gFdqSwiftqsNeg{ps%2|_}Tl- z;iEip8sRT>^Oa7DHHnvv4AmcI&XwBBxxZ4m_!`TL>6G}a0L`#=HsDf*d~JzFj5~41 zJ8^jvH?Ef9)WGU8Pt=TZ)J*umDzZb0bD>xx^DjcK;Wo9?sm2}j(WE3}-*ZH~9(Oh; z93>#G`!F5DXmi%^Tf;&8)5$dH5BuCps;xQ+_#!4loEBz(3cflQ9104z(YgXrk}$Wq zobgEba18&{nOo*t{3c1Ii@~(6V;^7arx!riO4Z*jbKD}60wtj}rXa>f(@0T8wh~&2 zy2{DE#&)^^OiJZ13XN*Go&}$Yj#Yt>m7aw$20ujH4;qwr8<-9D+-w_}Tddae?tL7m z)A!iyRA}GhxO2UaFI!N(K;_MdjkA7gMq5w2gN)rfuJAAmlY_za`@ZR1jpOAXR^awMa9O?LX5t^Cva7FtZh(7J zjOqNyDUnauYg;I%Z9-zc2g9k+hiMc+^Oy|ln*C>yis*WgY&>;lM9AP!DSS1g5WZQ1 zR&cn0y!06F;te~o;yFHb6Cqr==-63#oVvD>?2+j9(&G=)uRzd*|R#hZ`}C#^J;3OAVHr~+ zvHc;9tui2mnC1bsEP`3FV!#WYw3{fNDBJFSgbW;yfASPQw13zOQt$}TCj+rOr<7l$ zz^?DXS4puYpW#cNw!&(4I1=$kW`5yV0!2adnEfWSE?YP(3_Y41q|x4PeASq!{|w{_ z_Q+oQefkz)D2eQ=&nS8@{qCPdv#W~it1*bLT1+$2p$y_v6r0i^vEC<7HSa%?$Q7+N z1S7=|0^XDdV~^>;e-`n5=1s(_ew$4-R+Jz8m1L~wMZn+S%3UvItjug$W0;Lc{po+* zw-#kHo??u=O~iZuKrAQ_@!ugI>(RQLQQSdYi?;cNv9BM(f8GZPW2ztjSsp$N>pHjk z`{|;7Z~zc7rhFkY=sPW6CXIi8*Jbl|Nc--Hro_p2?+<*(`PSM`=`v8ypnGE4UWMNK z8Yu@a%Z0==`o#W;T|MzC7OhPgFNU$yQ0#tFP(D79oU)VMe}vsX3I8?N{n>H|4Pkcw zBWLe5WMu?Y(pG*!mkYQWMIU<6>FSc$6t*>K z=SYCY^Ow*m>cgG&lBRBmN#_N>q{sQbs$)`o7G^N?Xj$0RwB(seQ^7(*RF(mfA;z}?hSlU_U{EklAaFh*YX#rW(iFpsE+DN+|$W6V6rUds* zIlcJwz2Q)T=3XN9M%jpRg@IC}%@m}H&xGtX3naQ_y}qIuGUP-)IVZ|Qu@73QZE}nh zM>`1F;!L|sToXCoem*T%AQFAX1X;(WyWPeeY4G)Prd^6b1>8c^;3Cl~CRUN$PpeH7 zWjYDjwM@G*m3ys~3h7fvXi9D59AlWvd)!U9uhWB^u}sWfz^Z@p7F)cUyL3)`z4OK? zF>{X9gUc&ZE3L^p8HnIhY{nU`)`7c?;f0C{9`35YSd7jF(v;@8SuOJ@kiidC#+B-N zU_z0-1Q?0n8&47CL+B4kMsC~6Dbj!|0>93hsc z47Qfv8*cdjX%7Mo!K=MyLV;3Ef}9RpD*w|KEc}gNdH%C7{If3bA8zQ@()h@T)}Zq9 zGotmPkhOAPF+wP?0e*sHy;k#0+R2DUu{_sgS+9{S&pR&SO+pyS{I@Jlo)5uz0qPNdqUH~|JLci z9z4Q85N*!qT5!7-?g*js>3^wqxY`~hclVPk)LbRqx=^3m-pPm3-ua7pM?JuRw&pny7HG=odeH;Ef=}boooO4 zr|w*#TJ8qo)E87?n{wwcsNNj>ZK;A`h@fm7IRZJ7^=UhyrQFRCk8*#}d6J%1CQ~{~ zIB-%cKjxCMWkRAw?#}=qaADAjDO{_7tAoK*NQmTk8IJi!ny`!4SclL?g^=T>f|6te35vP`dz5>xX>Q269HfY zkvf`4b%k@42h|*P(={5XQ`-$I!tU9IidE7N9K=j`&FrdsJ9kN9(s?;kj1>zmp%jPP z@)qB8C4Wjr@oG+#quHk{)P_&V%ZcU4fN?xz7#pW;SumExL>a#MV+az^F^tZ(*uw{h zmINKWfYCUIm-is9)E6OMp8+m?^{KeIA@koO>#>JuXZgrvs(vc_Lb zXc9!~c0lJ?1@9t)x?X*G?-L{G`1BxXbiX;bT!InHykxD)D2AXy7yQ`cG95U<#%^}& zyCLm`Wv$ZsPH+3eiT6Dg@4NQ=j~vqRONsQ7=ZAXtd)zgm4~I!{r&WeQ30Iq?D;^rf4ro^R{F8b4yY+)Kii%-K-*%`FGq|zXMo6e6K?iSD^ z=Ou5XO@t{j{@=RidL=mnzU_OLCccqk_ho@e|4X4M-6QY0j|%0$8fV8b?c(8u3CixuW*4iQ+>jYNwd&i}&S)@4mRhNgT#E z(CrafW~elycmnhbX(#)Elxn$C_*x+33g0fV>E0aau;U~hI5Qm2x`8Ksj zShese3^`sI;spQb=**8=lO*Nec`U&2LqzB@yi6m;^_^-JAyT^C&FaetFnEw!qj&hD zF2twHBh!3_}dz|Hs&I`N|bhLS~=o1mk@s1b|*2u|eH5{ml{34^Mz9DTW3ja>(iB zmKA%wxdDf?(*y9E;*Yc{`o6*`^Dr(8QV%34X+&977m!{e(@OQ;+JQx&;hyHW~F?jRH}yu8|5*S z9FmuVoQUUPqijX%w&ZYdo7$`S#WV}0r~*ew=`y7J_4kDJfwWUQ=2cq`f~SQq$fH_E z-HKv*UWe(w$4nI0Z}?(4^hn%W?)hh^G_|Q!mF^?Se8t7-GTtp$Ziu^MT3(J<=k6tJ z5O)j!@UoN&d#mTWDB17WGg2Y(2~~|+7J;5n2>~)#)|JU4U^565qSm}s07nZnrZ6Wk z;7mn%jQ~BVF{HT~b5^wJ)!dMgdSQo9E@=lUWrXr4l(cJ2r0ln(oJ6Wl1e$f3 z$L3|v?y@Npszx$EXzWnFk#?BDcBjWYkrBehdQKOp-E^l#3VL56>2h zCOevto^SSV*Nd`JQ!dYv0mXb)TY-;#$L_rcF(P^Kj`CF3E0s0@z{j{_=m<`KYG{k& z4^hXb@oLS9D*gO`wB@)TH2vE8O^Z=kVp~J81mJqt|LWAQRa;q@16330A_x4?(_fIe zI)Q=v?)g+K?-23L^oADV%5e9Tn^#eR_1NWAjNR_tKr00}ZYK?O-Y~N8^zlC#@*Np- zd4~kMUk3z!9X0%JOyl5+MhsO~A#sAkM!Wfm-}}bnU1OT=9W_vX)N`WdL57CBA>-VF z%rh$BKEM~)4`r8{~^Xi*U+_2jov(dK9JV`TJGK_Sy4J&}Y>`ohA+sj00buDdT zdAA@jqDrks>@);0KvrHRh-k;zQ=>()7CpXpdbHaa5ouuSHQPHiY!SJD;7*f7r74|P zT0Rf_G0WwhbWtU*_abu9T0iRmM_lZ1+!G%c&Y4HLa!W!(XMJtw&|mLoz3yXnMFrL< zux&PX1~qR)SyxuV4^V7nuOI7yM^4W65-8!u9 zP@}`YkdDXafXyaPp9XUY!TkZ?Ox-ii0Z^(G7_YbSDCvh)eX zlsB7v=WYkUmCmLW8-X_Xr`N@qJi^RI5XdmJS;`wy*4<@g-??z#xnyd+E{e0MeY96d zbj-XGC9aLNUFc!ow>lvuEHdse=8?JYI}WtenE8ayO>}LE_sGg7O#KSF_7uFF+h`V- zeDgFy{bXuy6k-`ejc)OeJuvLG3>R-gZuQv81;5cMG_;;^ZD#IVB@$cjMqGjFD0Lz2c_oQ zj|&S*#7V+qRq-PG6)|slj=4R4jtX&yNN>(Fx&aS^g0+EOR^)}$_5pe>c~WV~(6*}n zYWB@v@%=5MLalDlKmDU;BIUo9bz@cH1f7Er&H|ak@zvI<>_*$~PG^nkcnRv#(52Ft#;Utu)(1~?qMsfDSc4P}0L zB>gx-6!KO&R#7yO8MTzyB=`gM$ri} zMC^H4ss&Z9<-Ed902hc;hd#|^FDEz&7g48?U^8>$QnCR3rOZ^J+ex`;XnWw zh^CVfnx<~il=hFG=bs7zTd3m|svsUYJC4N7Q|->e{skK(MDAmf(726p2;3p06*5U2 z;BGnfdlGRQq4g0imW7gPp;fTy4r)U(R8Wg?kR&B~M$-lrfX{INmcoTrFMJG6&LbGr z!V&i!)+~8E!~)Oxd=;bn2Y|Y8>I{N3f>w8N2U}_ZIIFT^tOpj9spn+Ci`%oL&xn+f z%4u-ra?bc~%;P%eyZ+`TKV=xF!_G{}{he5|jj`RiKVnm&4J}j*caZ-DjG!lL)L-z-JR)oB#n%*~R446KAg}HUxVDw)z%nLtzRpy{i&36zTc3b@?597A&sez0%nulu4oAHFO!!f4Nh=Ma)|_d_g5n5<(< zV~18VpTAtH(u&nFO`n@T^Wo6LW({0qa#eCuM>ab0$@g*wO0(Q!vR1PeLfEi6YWf~+ z!~pU%cKJeh@&_IfCNA>f0Hp+?T9j#-1{MtQdl~}UArx}2Wib?wnl5PV?>{LnYdV67 zP_;cY$G2ZYhY@zLK%=%pqOnkcD)dYuW09|RVS4|KH^{^!{uw?&AyG<(#`Bh5JiF~w zV}}55{Y+|8g2c^a*A-%r10Fir=1d)RSkb3ZNZsMRko9u zisk}1UDXaqD1}}dzK*E>tHXNZX%m|J?48xlb3AYlo|o`@42AF@O|Q7V6Y$PC<|Ti_ z=kzJkkyjZSBMmY9U#u5DK@BOn}`=T?Y?@oSYrZdYI@&qg7!YFi2NLgNlB1MTtU6z+4P(yK;Z2;%1;vku zZF;q2t-7?T?^}z~S~+d=?00JH_k1VwE_3SZaMh7h?<&pCIvm#DIc+t32>Q-{6w&!s zyY*cWr))fwT*@#PVYFtUXoL8lhy+!Xfa;NLxit(F|Bg+52c)I?TU5?Yo9hqdqcN78d-CI?3 zwD!J0kyrP8?~ShW^f>so&wQa-1>!TFitAbjZ7HF)D!vpwm%sT`Tk(0kBZ3SfnMuck zBrBh*T^HK<6y-i^%y9l*Rna(nF;Z~!0@&{9v%uX%H@c4_?IOQ5Apm8&(GHM9A39Kc z{%U9d$kw~L3n~7g+k|arRft;i||!xi+M)rmGk*g>)#U;Ad6BMJ!8V4|Pn zN$Y!yiZG5n*rUD8^g}8!q$U7ESuYVH0+H2Ars?ZoqtmD0*@%k>O-dyjoi($eMNc-E zFsu`ym-h~6_UzZ5s9~qeC^>s^+)oayWXpp~QzY|AeopmC5iHBeRAkQ+s&n_!Ryyfv z3lBV3fDyfqLDvEFi*y59E|`E$5|i$2r|x60FqEuc$0=FLq?Ket z5WVpZPvqbzg#TSOS0n3z*H{LR%XZ3xhEUnhY6~tak5vk7J^C}QRLm94pLz4cPtf*W zus^MhN((Io}Irj_- zvQ7tIJC^9DsGd^xv!7Sg+AobabW`y&>j2rAq=Kjf7*SGZ_CAbM@oD3^d=atAplki6 zgP2SH7?Q*f36pw~DP?<{m*u4OtIRLu=Ps+OJ3_zuZLxb*#NIwF!wk zp=7eW0IZrKXzGWPnx?uu@D8I0^l0)Oh>iC>~7_U2RFeBR3kBDMxrXiq@Y>tvUiYQUV*gdT3qrh-T5k_<2uOmYQo8CO`S zS4UHJ?0c>lg>1bDLKPd}1>5R|sMRooPew7zDqv#An&`xiIrK3-#G6`2cpeP#CI}o8 z1IsFLyvr&ul?({Aoi<F+=ZJ6dxXQ8QQ8%?S>VN*BJMxyB^PLhtcL?7UF&3Fe zY!`CdmXA`9nx5qk5xc;_kpM(72K+@(7vQ0yhb{fO_-@ip(tY4BUv8~naX{fh#w z$V>c1fgOH7pAqyQM4OO^pzNhG9&zq3D$EQcS)85`dO2{TZ2FErXseNFYR95SazA3``0_fjb5}y;m zw6v->T#e63vd{9+jpLtPkOQQSG7c*^md(w4dl7r!TM9~KP~7jDiNSEw2iC|W)p{Aa5|J8?HZ7G(2_zJLFs zSnPXYyHL?2zd9loV+2>jz~Wf5QDE~5>POV!l1(3o4IY|d^8N?q1|DWQMzgkSF}2Mg zh6d&5iS#34{RE3R$=ImLlgd%?+U0r=>fG9tdzONSGh3) zqqv7R0{U*KM2KCzRP^~4VmUV^^7ZS)J5wpo-bJw)GA0Q0x&4o$w-8T#)VB@B*1}*( z)t8By2UQ0~m8mVgf?#nNEF!_HMR}IzG=>q4tsP@WMDKw}a7Of3MzoykV+^PrGpDwc zqb}Slh7f=DoM|KKdB8!D@V{agzF++sHB$6vsrYIMvvByF-tVmE!kQ%tte@2RrLm?Z zuIg%tY1c&RTVvPu3p0A4O+XkbsEidQ{+U*@vdOzQ+3EgdG7`B-o0)bONqyT*6a`J@ z|Je|XrqlMo^y+WOu)gjs2&yvlF9TcPbzcJ;xv7nx=+c;4eb|qCz`e|5>$aBWzwJ8CwkyvuC+h zuVCeMg<0Hz{L6>dhYJir`XCPCd7<3y@$+KZeFD+N z%#r^rK(-&#w)02Y{4`cP$sN6)riv(7NHMdQz0|s>!8P#8Os5G19CY+L1-z|jnit3! z8yM#4exb6JY*HV_#3~z}n;d0w*vLesJ4?7_;hga%vTmz$#RIMmG>NRM3v=kHxXZoE zCF|BR6!0TQkdz;YpeAC~d#2H9Gq+e>EsJ{1$!kewd*Z4tbMSSFH|W$iYK2OsIVKR9R-O>){8hX zfyktIXfzujPWls%aY-Gg5RT4IGVX{a`UF8v=_n*l*1>NLXve&j;WdRqJ61wo+XSIP z@%_<8b`e*Yjw3SgjJ&I}h43o!+Z^;IY_GzYIy>>Lr3C~T-gp$!IMUYrq=DfNn9f#* zW5s&io4#K1Dnfh58|JH!kI(#cLavXc}}6NHIw6t;g~tv7m(wg zRlBq=~U{JqiF(^$@)aP;M5*{L>Al({sD>nGkPe{?|?IsB)kt2UhIzGa)$K?&=)-AAQ zA8?_EAfrqhE#ee#kx31v9XGgX{f&{|P$L}U4($Fr*Wl}{S)6x7(yke7rE*x(E=UGa z#L1R_pqsc3{2$nDr;pm;psd4LL?kJ|*Di#~udh8?hPgPM(x><}QFcXUrWKb=LuqKc z0`f0!U91GOmEgo8lm4=5bSQSZ15Dfqg@$I3f8G1fdV!x{;#d?~K?@n#2zd~lL`K3s zN6e>DZ?-_`jcz5phrk_9P%4*Q=|+mI4uX?56PG*MGKLDK1ebj=KG{?k2bQ}7b z-$Cvf{~nCVrwyW-Hn%>cwP|TE9_=b1v+Q(3A&$b1h`50W5+)Wa!}Z&#>=S5)okjGV zE%juP7i}{$$+GfS_4qUJB+5gyk6QhuKE|&teb47I;7)k`c>jHekJC^|*@3Z$ga0fN8m_R{|$e46QaR=4W*!LwI;^$1< z7p_c30~6$x1SR3YJZ%exVaGi*sf|TV?ONx`*%cXFu=lBhiX(Af1GPX>$4w!uv*{b*toOSWLnYca* zZN$j5mV4*U#EnvDNf~4-u`H(tq2KQ6$KGo>EA(Hh0tezDI;eOK$I^gZ=`)wcfrF!F ztSF$)y)XWh<``*nliM+lM{NQj7$}NhDMNI%_QO<`fF+{R=w-M%%Z^ru$k1^nrI12% zEhCq=ax398%cQiyN@)cxa_^#)p#d26Z$%P0gv@V|^cfiTp zX9l+co+H9z#NbFpCoRE-2XzwKEpyHvdUAqGHwC7OK?&#rjh-1KG@Aa6C=iD5R?~!; zkKCE|^Ab)^FvsjH0V2KdmP}INDbC#QPugSE{d1FPVSJHjq^Tm3n~RZ&;$>JVNhWpj z->P!*1FnNF(&m_{Vk_5Nnq;aN2XpX=z#aPZ-}|YwWk~gN#)=oKQ6ml8>LKRLV=4_- zVQ9fHFC}+q4dU@LxEdW;hsmY1WsL<|(%)D3^bcuipDgF3KSI8Vd7st=bGGT7tbYS? zYAuilOH#>-KHHWcCF3V>H9>6H9-nL`V5FOZuMmM?uA66*@K^j zpymbt278eWAc@jk^QZXQspB89OIxx|tjAi%&YN7g@qbvl4tS{l|Npsxvq#8woXD0v zk~2bIWhGmV%=lEkgnA;D0h^^v|{br~$?P>RKo}2o+E&gK?Ec|r)S`p82f2ocfuZd5?R!@j< zWoB66TVNL(*QLb_WxTbWL&DA%w&~0~Ad=8scUwN1$Gkdaz-(nd$bQi#Px89s0_kLx z!^1X@6H7A?8iQX2QEvKTMS|_zQCRTG0zsx$*Yj4NEE*zr(~)%m1De8jQHE>*bmkxV z<;WIG|NRIH_(Ty0|Iiqj#pmf9DO@ASHe~@ev`+@W9&qsg(`8cTm?+GFSWf*@R3L9# z#o!Rm=%5C*1|IUX?%=EJL3t(;07<05@payQ@8$RH0Fb^>)*94*yn(1Mr8==8I8YlD zf-am+R17boTm`r;07(aBiTY|XRGx+=4sre}_K-cb;{Bz1#j3-IWVvrf$8si+5F;0OS{6bVhpaG}A^XKmah@V)1EdQ^EO zjIuY6fwc(~DLVjSJ7=$MJ}14*>aKsC-ozGa9gNKMYQig^gPu#kNGahnZeygL#!7rR zsVTlrrv2<4r`A)ga%RKfOtY5BmRQ&47ee^Ks}RGa?#4#8l{M6ukG>Eclu@a!fOlfj zU59wyn|?bQ-I^_9zUy20ehq|0Oyiky@p1;Lk5Jv<+$FGP0>5_Azu;F3} z|53jEDT68BJdF1^tMdCLmGG6sW0akphHw#|(rAgf69JIW~9in;bbBtm-lELC^FF>=4b& z-(kphZZ(#(zWE5X9xsgd{A+8$1K3#nM3| zE};Z$3Fn8Lz~EZ7h`L7UiuS*tlEJPR_3loM?SJiie+!iic8gboYk@%@8Lryx49*ge z>0j}0bLLl+5g3Fy)w+u)9neWb84#0Be?=WI^Ph&nN$v4!>sf2V-6!)N%tkeOfMn~G zN_p9tA<4yYzDVlS2ts>N>9hZ2o^IC>w{Bya{v$kk??wZe<@m-xYnp~X@52%}EF@X;7~xoArHDw0as1-(L9G6cLe~pVaRII~!RY3PFi`kE0LFLK|87W+dbd+I-_q$! z|8j6cScfwGo1swlO#j1wHzV^C%76}h!yz+pN56uJn}KWC^#AA+56P^?AZuk1lyL0} zP4$I!<->@cumjBv6;S*&h^*XHgBS?U;@-2zXySFJ*K*Rpd272Kj zQ)X35L3(rX7bU~I|L`r9{yY5PFzYDmXVj2?f&%66vcLodF!LSYUmE`ZG=o?mQW~7^ zC;w6~rCSr{TbctO`JaKR`yH#RQ@8zd8!+~7SVuX)u^|a>DO1g|fP~B7h@cp~OsQ$? zK@)WBY4x(0zr6iL%{c|0&UX*jMf|W6__FYaufwP~+iu^1upOEeK1ZqM0HSq&0CmRf z-MDcIpQsF4t54D3OlUgv` zv_(*~L1pjjT@&)A_8{Rs=hm3=A4|IF+jq|C_!8RpN{=lt`g+`mre^Qhby0kfA3oJLrc(zn#yF+`nsmqEe$v4@@hecSrTMm`V9F!;zv% zUY-rW?SogH)J}tcqWXP-$$J#%G^=|tk5k}QZCvRH*JlPSDN^H?;wIH9pKWO$Fl#%L z+OBMv7s-VK)zi_wnm5Wh{JhVJ+v4WZ0Tu}+0W8T=);9y3>aDr8yVFtGOLeG}-FUq% z-+a#a<@EF2)%(BE+?S?=U$NNfi(af|nXP9NagWMxjRuOP<(>Tvs%ARgZzEDN^zJ^g z_t6&q!I-_YTi0MSleGIAZDTYg%9a^Tg-l(JCiPw43#88jdRAgjPks4{?lPRZ`;uk$ z5Mx{j4NIpSst-V`gLQEs&~nL%%f3xndazOn`1Z5HG3nsNE4SxeE=M#Xp`TpUcwP|& zJc++Cb{O(7Ukt>x@$o+2BVWKuLc_F;`JL8Bd+R^f`DV&4tjo#{a~yDfPP^Hi`ZaBp zrwX6*8(J%S>vxOW*xz@M?tBGwnxj88aRg~aawHMp0OaeCVd(&PR=ovKdL|G7L3 zi)vnBJe4yCT@SME0`xjMk;e=zx}kavNiD@$@x8wUNgVdo7cw3Qeop%sU&kZTFy%Pr zDA{uB6W#TmIrLL^)c%VJb9l8Z6+teWtxj@L27jt;s?xv)e16I)dAdN)V5)+`=K(fA z^vk7MFA&$p?(sn(-LO#ZDPi^OZTKpd)V<6IomeLsjvw9Nm z?O*SX>zzTR19u%ZLWO7PD}2ZeeY|U}4OJ^(^?5V3%-%6|+mDqeFbx%$BnBlJSDoD! z+c7?_H{uz`;OW&=4s9G)kz|L}U->-k$TozBi~{6B?L7o_cFb-4(p`y9-_yNTc)LJ1 zIfoz5Wq;aycZ0X?cb3-XL~~!K(BoPlJ}7Z(0sXjEsi}{m{fB22L*^`WLD%IqqvwOZ z1i<3P5zUM=1g^X}65x>r^e`68k*HOw^<{v4Y%eszZ?*iI0jDW5nKr<9;M>y%rc`GZ z(-s5Hhgsdc{E4;g+7j!x(Hv72k<+{1B{y&<@-h)ZISouuQZO-*16^u16U(X0hw=o9 z1Ysl=d4$K#nZb%bd1jcHLYN^=kin3o{4BVgv5*`4iE21h+sbU#fHmdu1P`{nY9Wp8 zga6JzfB~_2T(N!F1)zLthv{*T4YQcN+OQRJQDp;c`{mSjUqkppK#CYleZ?tV? z{-e|-9otF=OZr@pofKvASSNhB=mve!GQ9}Hvp!CA&|O8Mc%iQ%(4oN3rr+W98&tRz zAeTgVcBJ@?-4^s?@5DzeSNvKD?yDkJ3Ip%c`+XA5s$@MEk3=rEFlX~5CVXTS-uDf@ zRe(+Y09&RR;2lh0v!Xy*EkyjCi>rD&**~YXFa@1oXW7<%BP2aIbhCnIr$d1JeL)R&<`9QY>OYI1CJ4qXKNhU;<)r&r6PSRv0SB$h`|)J-LZM$|1# zMbyoTA;ADWvfy}A{9XAmua!;)9X@#cKQT24sfatK*IWWkmu{4wQ3#aG#)ufmtD(?= zJP;Ram4jVADHJ+ z`3EF1;ms)If?vQ59!&9&TnzwUb~FK4?)n)JJ_gJQVSPF55FmssqK8JWKtsm(D^yYd z9SCg*(4^bedT+6**Xo113VcHVDv?K6hXS?&R03eEP>Cq%8A6|eQ;T9LOC(S0nv^b8(A zX>$4RxEfF>OEw@cYZF>w6AJu1|6PB;P$p%<3)yl}7vqag%CKJP8mK zR|1gVQW!}Aj;|;Af9q?jg)G(hFNH!snY(O&>QMQs5kSJVxkm!3GxCiU`E$u8u!4)Q z0)nSR)Fch}l(7}{ep|WbEGX#QV1P48?B$6a9mHO0F>(7Xz_PyCiLGb@DrN4n5_qQTa zezM*apvp{MXrlhCl&~ig7vM zsTxh$2jg-9fs4?2L2Qu2n^?|P@-$2(Xk!7{YUv6<51~t5M36ZSwZk{Q2B6?;k!(Z< zafOK2SgSCG`e;Y0`e>*`=K59C&6`5@Ua*Va7wPP78(7Wt|AaOFuwUAs;)6VIf0XD7 zpOJwiEft7ePo;mS)4!IT1Xqigg@-IEU*i5DMXyS{aG9X`^M}E8WW$f)eP-`ZZnP5*!J4}qdrI3_B^||{V`EBMSPIcJK zrQ9HZCxB^2>zL3x>X;-yiWzD-KTXs6k64AI5UWn@?Fnq}OP>wKntWi=?8qF?d;|cx zGmNXAlB-`aptPMY^<}VmWey0l)W<)%3N!{He({jcdp13!=f}$ckOE*8i+~(1u714~u(t>A2CJYMSAMcDm1gv-z^aGP>er(9mAQmRowN}V&{{MR zjH@Jm?ZNb*t1oK$4#wUh$cI2Biy$fD0_&7lz`JVT&vS-@_@DL^JC_?o4n=D+o+OFw z78z#rMiaR_4ji0`9sPrkZe6|qFxN-4Y-NqCx$(`^=&N@3a}Do7of{$W6bXO(vItD+ z_nwxG+t9V99?!j?6B#@7)1FYqNyY2c(lo@bfR1vT?fqMuQmf~`!HPAGVz56z(V3u5 zdxEg)t$H2Q=@9s>M%=C=sO26IvDWrTCJN0$t?Eg^UO3of< zCb`$Bt?OZj)2Lx#8MqYqX8en*KMy1fiscc?Sm$zv82iru{6) zt%}97PDez)x*@m;7dp+i2_XpMGJ?xBDLeZT(C)7;aEWw~{oeH{_tRhuRg=bPfP!N{ zUUS^*ro(HrqE-F#NYdj1LUtpfoROdJw3yp>gxNbA5(*1R>!c!bWPQ54D2j7LaUC(? zH?Z>d@O36oL;-@uC=GO)kWT70mFS@oI;|LUuh!QQ6{ivmFSdpiuey3Q)^=OvZ8GcC zP+JJ7LuLuaa$6@@&PS?@?3i}8JyQ%6I%p$b;BhDP-Ov6t%0NOgrvVk`=_TE$EZD=x z$nKe8J0o7gS;&@5d-Ft)YT%sSTx7%Nq$!J#UIuM8mby#)%57d11U;StNSs-aTjb410Qg9Tvt6HhgkxyPs3QAv^3X3+xUyxemdikYXWkNUhlI z%?m?awQMop_+*8r0kW@bA~%6KoJZ23NE#*JSzMjKX2V#%*} zz8tROy_254+m>kwFsUs0uC8|+b-cUVE=~Q`S4}eE{=)3!I+@3dCk~4$Q_G2Fhgif4 zDZih8@_~BbtBLVLX-6+#!b6Eyj-1Zdd3Dt*h9LFVo57AyaoY9# z4#N#h@}=$j<4@Naw{n<>@VQsYH!i^Pdf{?E`Ly#1ZQFdAvg43Fpdh zDGfT_6*mbFC$>D=YnLP(ZrCYbYXN)#>;3GjoZ)>XTGrI5j@IKt+T&uMzbS#FU~kg> z>FRtI-hI!W5g%U>i)=LP8|>RC6T~9KSA*`#g0pNc=f4y}K=_5{-XS+j$grx=9SM3! z4^i>-w@&7x8bKZ|w9yxcG`QHM5qCeNY>le3rA}BS;+ui4)M-3#pMFKZS4Dq3Z{M0n z3V1OMbm=Je_A<0&d#%R(@M#10pewvsLk&Z{*RaJ$ux&SL(xo0V=I1X}eqVf1;QLy| zwzUdO#D9L@^Hf1?3^e|xp^CbkB>E{Uu`m?y?9Z#i=CwRG>#R|!6SdqLaQ#mv|g`O$S`g6rH($Q%j5&# z5`oSd5^_Uj+cx8V!K+)Q`HnZB@r6KfX6%;C`2wc;&TjoY$u!Hf8tuRm&dUan_Isf1TbJ1?l zz)jym(9!ZdZM~PpE22!hq@60QpkY|eR_d1|=_?CeY20DGjXl%%gS6HUR)j-+l%D?fXI5|Yl%Rp*=ESKr5!P+ z$85#beb>kh8k|PgB*pP+Nns1WM(_O)%HhVsIc8(F<~~_&#y4MUBH ztjPI1$8>&Cj*2pRWgzP-hd7*x^o!V7(5Bqw$*4v^R*{! z9(fz+nyzdtA4~*x`(lSEt@Ya*)$X$;$&yTd&D|Apf6hVqFn}G~kelJ9=uN zE2b6)%G}UsngxrlSl0$9wje~c_;i_dKtOu&CXAa35>4jJq5!wI7c12VKZN2|$h4VG zcwixP0-s~BtV|lTgCuVQSy>sFL+ZDAnElYrF*v%HG1TzHGmG0L1D!si?)f<0AnE16~Sp2HtY!lNj!iuSCd z$=IBuXB#;he7bMk#Io!Eg6kGNtrofkw_L#BbF8v>A<7k;1YYwhb>KivBun+q0=xpazk(aUN*Zi?nH08KN>qbM zhILB=L0ykm2+QYa{Hg7z9X)!3DLq2HS}d6TboOBgX)HR`J1~_m7C!L%G-6mYf#JtCcwSQe~7i^E^l8@k2T@c2j)Sx zW`h>e54H0XWL5WrIiW@);5p)3i|98qv|^CFkpV+S$pdn4k(fVK!{zCu7(o&Ab0bE@ zKp)uR5?!7)9A4ag8W#vVVhTJ*-p;SwuNeAVQ6ur2?)(S-UmMUn>bBw;g}73QAl%L| z43ZQyB>KGtDv@{q%OjpA4KZMkwR=FtshVdrzW89&X;e8y*Iw?YgKyUE_TteM7%dV% zt|oUWNcrPw%uT*Wk+gZ#ir&yOxHCqhsHIL5QrwF#a-?CYkN26OLJ}O*Oy78{3>qx! zSEs{pPc3oWw=(CT+yGwdKK|nA5p}8eaML%r21r zoOFcbn{BEG@f;5jR!~>$0Pu1~x**6Oip=N>&HL$aI(p__jw~&?b`u0U%a;v%^gm+< zj^;KMs!bjYL)(kXsLx;PA_H5~+@xH*pg@+cJ$`GosEl)w56?x?TDN3YAS7kS+>@C| zgGQu5;2sW>1WU546Yzo>EJ;GpCKxL||Fk!4UidT_*?^P|7rh8cvXORuYq55DyruHN52bsgSg)9&yPU ze`Xj8XQ9$>+Xt}A z^pGc2UMoNoYqWcP#Xwgrpvp+NN*xG8?7IT0%4?teX+%#Jh^4f!*31tSHO(#S@%t8!?h~IJ&-=c^I;+7vwTTANzSd9 z$>IOt{@H)%W^Xam`L=2c6YSVf}aHR zHk!C70h4^Oo@!55wbONla+4*o@UeU-4Ss=)JR{mx1v#p(%tL?3@xD1umtE6gtfhzJ{h{Qu z8V(6{CNt3Fm5i+{u2Gu4zKK=vCiu@O4_{}8cf8OCR=TQF+l&rR|+b4B}6KV!38<5Kr&cb9n|=SvcAlFC|zyVaMW>Kpg2 zez5pUrF1K==+53RbVq0EUIYw=R62=NYGQd8d>&7;$ay-@-rQ>|U+-Wa#U?qug1Qbm zlFJEc>d^7Luh~r0-(wdaC2kBXiMma6O(O~p^MPEa(( z?B`emfQA^m+Xn~m?%{jZQPZj07snbfonx${mVPl1udRVGhfcZxs9oH zyA=6>Rfd<;_=u5$hxIozXtoBI-^W@75_kW~sA>kyE?^Bd(2G(C?cvvc0Ctl$XudvA z1>R?fd;ma%d+tH}_yr~W2mxd7qx-Q_k6_EYRClFwX_`MBvT)R(iDXs(etLojZxGPC z6|H^!o2T~mQ{S{0_MHU*Qzo;id-%8{3Ei+?vpxMEGpiY!3jzlZtw%*|!k1G41Z4(h%L z@}CfBC=|%7QqQzp%l-DAkHLi>suzM*xrX+Idrp$D%5dBa$Iw1gXTjPd8yW`($QD(A zwW1-vmuG6Fh!O){q&K3K&Y@+G3F@i%g}= z=YZ27CITil%z>XlBv|KU9_cVrGNMPL`IngNOX8}{vdd- zH&om|0BFkY^#aQAzpVKAd@^ zV#8;PQ@x+MQZ5*d0DQW;)Z_z3tP0RhgCV#9EDij8xl*&d=s;dM!nP7Q7a~d{xD1!6 zap+lmZ19ar%YZ{3F2hxbS{|Rt|L<0UmSSTm z0#uN#>gx4deVYL|^d}q|jBmu}^u*&OBjPtN;`2)%7QyX=T$7oIVu;lbqBwLL(pCYG zq~O;a;D~8D29bc5r{oCPmRWXqU`{mC$qZN5%#<6~lx#Dkg?xp4 zD5iklq9vco{TAJHz^@hQ)t1=!LKE;?L<6~)vZLxS_8kC))7*$j2ePjzfhpwxYg+}t z8a7a{%3B zs6k)`;5$V=SO6R0i+oF?nf|YRUmX9VQYI zZt=HLo^;A27#XYr5dw-5q6@&_pY3J!)q)&C9KXH0*yJtv<2EI2kASGt5!4knjX-@2 z23@5gk^1Z>LEtCHuy_R`;i-U#`{EBg>=ry12I&G0w(Znw=mw)B(9WlU81N0DtXaNg z>#NJ^dC+0Yhw>2 z(p9l%a@g@UQcxDFOH-iR!qQ$C6iTz8y^3r(2~A{3=-sqEa`|~Q-ELI}3^M}k_Zn!M zzsWIEkC)C44yvzi@^JOjt@<9)0pE1+558&)1;@@K=6`a$>73{Ae@_+C7jiQAQI@9k zY-3OFH-R_(bv|D8f^FHud6?GI!>nxRmRSnJYYoK= z&S;-3#btr*1TfMju-j*01l{SKG{J$ncMyUuv&6oQ_=xGTTET2i~{8Km&OknR9(ei3eo~%` zTl`~yGewd$2zKfK5GkNch;qurMHmFzfF`;cXb`MT;M?UNdpvIe2wq^6f8(scE@BXF zuxdxyPG@i<6nypUj2i{h+S%@pJHQ^0e}X#&<2@Rnx35+l1aPhth`Y!ViW4Ae57gmi z;MYK=tLt2gTW0y1QuU0Yz8Ktrv5r)a;{z!xC%oxGP7+=I z0~}WN1V8Tn8``{ZNQ$(4pV{!aTAEG53o{r)wFU-aGoH}a=QQjm5R?od3B1lE4C167 zDd3NL75YkgzqHYs8x*?=VS3H*W#)4y&ryjrFhE==k0rT{0#7k62>+3AJN4*1@uSLL zso*5pqK~?-WEG=e95;1dX-WLyS^jj6TH+6s&ZXuv>_2XyrYgLto3G|_=IZ_i6nZ5)nj!mB69!ko>)r8>cMzsld=$To7N+?QTFuye=Bkjv zvgyALvOFYVCs7SP%0Gqxls%xyhP#Jpec`|Zz{5N|B5E%Mv-Ttnif_bfXCngiOpq6R z(;e&zKogPW8@r<&SPHHIbi6470m$#)X!>o zgk5XdU|mbfK0x%BJ_*uFzIZ>p=!6l=9~W-i#64d8;%u&kjE=WkL55q#L*-)(WMrC> zVa{B0DjWVCeis|<$Y`W!!OSoka`V- z=M%R6?*6uU-goM^Y&Jbx0}Wn}d${uLpNi6Mxn{mO6)3PqwUX%!VB;G@Y#T-sPL30I zH70P5>fONcB0ieC=)`m{-G&js+B5&4V-Dd?j;3`q+swPGk&AQ8U81j+MQqTcf}mR& zEKrItUTOK0%=B@Pvu$b{fRV|ISI5W6M7O^&(9!2_^}E-}_RE>KFrj{-+_%Js_jv`& z9hQ^M@|h_^nPn?=@@Ee319oSM;QfRoP@g#y;41oF)NuHUjsepdr^iB~%0JaUy|{Ee z#O^MyI=Ubs&%@z<_oS_5o+MGp5No-8OXwIgD<#?McAa`4!~6-HDk(2P;*O^v-l8|5 zAY^02QXewULVNn=CA8|e5iW*Y?8~^|@tjCvxkGkho4J%QBzLB9^4kkc)S#jWKGTVy z$aqo51msSG?>}xibMbCCp+1U^;mne-=#Oy`1}ey0i-WXj10W(UH|uDd&hDk}dhQWRuUP|%H~3_Kr21;-7E$CN|;_KvLJ?=CYNGB0~3UBNbD-pQ1 zv)1cVIhcJ+)JTUw8KcLJIUGBPB>m2P<_AGlah$NIv4k(m@Ehw!Yi)(hO!Z{3m>wWQ zaV=qp3wrRI*mLBAkKMBjz4eXjrHLy=M;v|>yPM?eTA~hS< zSF4G4jhx=i{YIf&03!+OMiqy>OnlYo>U@p&?YZIFXg;zp;7%aQr6QWJVwfgG0aD$@ zj}@q;@bh9{`%ZTP+W_2j=WUni&eKkp4|!O|*;vMkWnB1!!@z#9 z;HGCbiyw&^fT)sBq`!Lxj{h#W7Xh~D`^L&ZtIw)zqV|mO-?s#~`l~=t3j|@<>&2l} z8FB%4XWXM^Rxa~vmUi1o@tKt{>5We|jay+!n={L;i4LmLx48`YLxIJD@Xor|oX>F9H8o zU#X!N@mL=9r^Ph1naS~1T0Tty@%%0#0a{cd5Bqbt4DJE*zt8**;U`JfvC0SMrw@Uj zc^@s-6~YNYq!{Rm{DzxmvgS(31zur8=)AUh;wS_5#4CQnfHLD=*`Jy3w>iuG|DTK` z^kcHSrwsQOEL2B-aeqrx{ySC*l>TA$^rf>Z)qeq^YcXMO z>bAf@?MZF(J1FdBBVmqtsmKm=aKl|EY&wmzB@H)v`u`Nd6=;)=|Y(!;+!CB zE>*3pNgu-65WB6v3Df7*mb9fh!?*AWXikQ%yVxOrk9D(15Ov!FzoVKtjjX+ z_5ltsz|r$+ZkhHi9va&zL9VHO2|TsX*p~C__n8Ou_r32fA4kMJ;GFxWJ@M<@+K;d8 zMs$!6Cw7yjab<&8#WM%(suqv65qa8A8R|SOH>PJS@YkF4*Sn2r)eE7!+89p<=}o4? zmbH8%>{i>imjvPv3Nlg68Zgx=rnDw@O=E!nH);0#WKBCJnP1MYu3C4u8o1GYjOzbr z&-o=9|3mpeXP-fHCR?Cp`tvkQ@owoF0bpgFmKH26L!lPMnm295WQV1}OIcw*>KWOh zfwq{Y8#PP0_JQ`*O>rsuO5;b#4*EDBhuS zf_68vW;3npb!&cX2}9U#bg)o2s8yJ3%W`8^A8HTzJrIvK0nd3i{=OV;<}p45TDtOX zmWKcSg(EEl0=Vh;`b`7q1Vz1gubKw$eEp%9jV$m|TH~gY0%n47N#}RMgHtVK&xO9w z{W`<&STZ8nv{krC`zxKJ?pIsguM$p?hdlpH!vC|{5WtT&gxPe_K!Z#W4iUSD4m_?M zyUiUPv;Xv+kiKsp*=k$WbZZko^(KC5vN?T0Q#fulqt-Cz{MrImkBmN_f%v%j0sdUs zaPCwi$I@VFR*xIiL3&uRPqfEWpAY^&_gJAu!`Gaiv%*45guF?F+zVzV0u`U9^Fi^~ zyVizn_1CXW?E1rnt!l%W3tW7YmJ9UOc%A7V_O^&!*qTFUkp?%F42wmDl=}z!t}A;i z*Q@>5Mei5I%YUWLzpRD8PtCr&52pOsbgRZ-rQo=G_hE~!=LKdz&ATdIG5dt=ILgN- zNq;;sTX*tO=A(X7PMGT4esRRsv>}}ZNrp|`-O345rUH*HRzJEm!|r^d(C1@Y^FnLs zlM%*6qIX@KE)Betoa!eJrF3B1dBkOd7k~6gDaZFR@{&AlOwH~e(MaQ`D)4zt-n5ud zS=jeHtV{O3AW~RRJ(de-r_cz$^{*Q=BgsRCNS2?K*kv)6qrGEoYL<1{-shL?6+?PJ zsv5s7bPI>xhhaBPqT2COTNTax$;K!pgw9B&u2{uw*m{W)lW?7k3-txum}nronxApg z2VPk{$klwzbl*EHq#*S5oiKql#*ccTaYm{jYjjyR!Mu=T#MFs571=e*#EH{z0&A*H0JTkw4-3 z1d?;-vt~ZQs*ZajHpUBBoL2S29`0=L3mguJkxTv$>Lu>m-&GlmgO zAAd36xL8C6_-$ATMui^I-k*038Q^O4!`kUeT&*yAu*0?jQz5|1( zI9EO#cb9yUEJ;4j)jrOZBA_G12&$iZ$&bN|`7tA8#9aQm&p3x4`n*veePjxKhCwXa z+R03i%1Q>*{d5SLJM&IAHZ(+7dNRGFB7PIhE$AzV^vf9#QGUtVb+o6aH9+ zx*OrW5e@OdaKfbX2X^F|iC@{9mtUyJLx)Z;q9(0h1COzo`n@x8dOm3J!y}(7?J?Ci zm*`{cykhLG==q)4a0FuyXWX%*dZ6^w%S7B??}dHL?WgYST+T)q?_qaBZ^Ge_@|&ne z;Y2;A{BdESdYw3zHdUYcmm_9FjM?vqQZ_!$biyS*uVt(1hC$U9?;oR#?GR<$%WRJA zu{SGos=^g+3sn_fFn>;PTpEVmcd-t1-&>pqm}O zfI&LbGZ)OsH)ipGa_dB#gJJYfMZf{b{SNrqiBY?+m3Y2xpu7IS%$cET6j#mdrgNYB z-a_l5>d&75v+3=6B3-KeP>{t%U6|f>?%a3Y?K|?UY8MTUgnJX}^VvI143EZ3FS4_X zNau+MNp=~A4oF)~AO`uDbgOUHPY=;$yPwaKB;Wbbk!qXo4lL*KkFTw|3}#4TzO*<< zRcA^shmNr;zXyRYzv*)f?63GCTQ7Wm!nD>sa6<-`h&KM073UmJr>XwcudtLSBC z&MA`5Hzp6ff%5)?yJ{DQupWebc}rS(!;+5_5DB#Z%2RQw+A)ama4KH!37beZV!Doo zb_f8eOB+9K)3bd|_8{{%WCEm0gs>TbDmB^mtU`9_bEycY-4FVNJs&+)IknVJam+;J z&J~tM4P7c=Hmm_X891}^pN+onEABephi4Q*x0cdr3skR(j^@P+?k5jLj|9Id2)F=4 zZz1}*#*AOQ_;@+<8zN4GcZKd*56W_{tK+~R7@3p_SVE}~CptJMfcT6IOYueFl!9@J zar`r>N@1TyE;op5(Xh5p35Tk5-~Ldv_{!tg?W$3pv&nnb>UG~Oq)_g8> z9Rc*EXY(~bXxiN-HrstI=lN!4G`uY?{t2Bbkvw%)IKQBfSHy|ltZNuOy_GbzcRinp z4R4^T)hjB0i%CwaHz{|>(rmx3a?X3{a?-2YOx1vbb>X_r0?mM0*i5_b*>1MBZnD^) zRv@*>J!TKA!qAK`#govoZdx?(2d>3G{7AQ&vHp{rxwD~Ui^X;+=D4np<^zxV;g2`a z=Ov37gG2VHb(X00UopqCPwPu)*331CPe$n%C$&7+bJ($uHSyu9J{_laxAT*eWy|Yd z{QPm-Ydt3`WOrLBXJ7kqH2to>?Hmjr!9>-+^zg9JMBBN ztT?OYVfFi)@T%8vHsd{C!j5l}4{h4hf(Ot0!v%_uO;?9bK6ardUo(gi+XE)du!QT0 z%WrAywoL9U-0V!?Pmt}}1c{=^4RVs#pWSbh&W~59Qw{aa-5%Np#U~VrR>iaM4q}d< zL3$N%GZZOw*MnvDdEB;8*2gbWEe_7RiNk2tiJAHdzxsgXYR}5ciYX)NLnDlA+N~(B zvOT1Zx2+d}A*#q&?}ZPY(Xx)^!P4boW?_0}sF3EW9}-%ly87XbL^P7$tMZ_+i;~Uy zmC!Ul2}gsbtz_rlbrLLM=XE3@Vy68 zhHm19Vq;z>UgOyIh09X4lxaD&bt;*&X~I%cPiMVuV2NB)-5A|@8h75eY@&|3ZP%hJ z%_iBHZ`$a(<~mfZ;q3XMVl}+~_Hkp}OP#ljxFUtqr|^ni1Vi}uN;hg#(YRk0UxK9h zoT^q^Sw*r>ke9_S@r>~%t~E33#7wTX2q_ol{`M0pbD#ISV5(ys!+3S%^mW;UDLieI zdhz4LA=L=9aoVgN$D963xLZti^)PW?XsVbWFMXW=hm$xfg$Vk-3E0*oEKkSf;M--9 zQa7m4ulRAdDAr{NoSkvYAA!blU7z-AcAWezg!L`U;M=#zw1YIJCQ$2ZsI(aq?99Ps zO=bIWuVp12s3+VYd8epeylLhKb>Dtprjui9)l$(x2?KmiXz4|x&~ z*v+GWyi%HncCjVawMOeQL@U#!x;Hk}!z$vjvH4=Nl)f0rh`AvS;|hZ>%F_OlP{5aRp87JaspKgRLtzlA`?Qgo_?DZ5>iynR z^A^k-PuKb@58b=V%IlLye$FOdx;n_1{il4dXeVB8$?X$=d}%^zLPZ}s>-!gK+9->6 zX+*hrJYStq}T+Zr8C@Cp2^`jikzM zSMxp6VwD@wKNEu}a>u`AX7lHk|9xEnfu7i1VP^YuT4=BD*~>V%u6I=J$Y4{dtnw?) z;Z)Q^-f%BKIa_wLsWmK;$EUa3*X+1K7Z{PxR;ckyXV;EmJmqF#DSlMQi7};^3ornL zu6_uW0AflKH3Jii`Dz01zw}@I+=ZosA6Uyw99c8W=RVA|S*SV;Zjk2lY7E(sQH)6* zSmPC4zviQJEfiP0v!B5Av9X}ybg)iZ0l}HMwf-fm9Dx<`qQ&~GB7dF0&$ZzFaPw}) za-g^I@7vpT)T*yHt^5glx5lrnq^)y@y(I=BWI?qK*pm^}wg>$Mml``Zpz4qz@aL?{ z?1-<-kGp1v@T3O@Fk_cXPyiNguK_>3_29CJ+AW%+CKPU^%g@V{mNuK`71rVXSbFa7 z(zML$2*N#g8d^<+45s|+6=-J%c3m9`|G9u-i=Zz5dd@lKd{G!bzo!C4nfpulR}$5L zKi!!ghMG$;jkGbJsZ-xs%|*iani9oKZ3zi9alM)-B`0dr8J@Gl>K*#hLCDlJacCTg z9A}xecI_Tr1EB3oDB*r^{ME(*4GrjGg~yc7TPMl89M1W&i0!*m9|0XnRaOJ?F};Pj*UH6$6y)J?aazs>2-8=zD$W7G3Ir z#4Ng7E=W}`g63U2kc`?=?kwsDjMA$q+d6RxCu=#c8WOOU z2a5f*+|cKBVkB@6824AY7Z4n~%|V`rF(mvFd%CwR#8HVBf=_X^g;qrW(ED@Z;454B zyo%v+LpH>>{@QWo?`sb6OyO$aMc!#b@P|Wsq--Dx{(z}g6FPUU`bo^Ts$%%me+thOYlDs&320>RcZ=&BBEtd&Z_+$mj}W_l?M7hmd*p7t?&Q; zH$sRR)Lt=at37IqT{Ww<+ERN2rMA-8TccF9R*bf2t9B{1sV&rAHTyxWmZEh0Prtwa z<8eJ6lH8ngZ*uOY-j>Y{tl7b3l>$L%OrXbjHmjCc+7gxaX=52OmG?{CIFzU7c; zXd^A+^%Y%B-ac?i5qC60QN6{vddY)ezVs%gIG92u0O>sJJh>k=IEh7skBO$qex1Fo z7YRL;wrXU%4$q1oN``AL_NPe(Kzgw!Gm4Ids&Bw`=TD~?=98Ef1WQ$-4Z}CubFhAn zlypFU@X{I&@h-WxW0m`U)Gsb2)hOeV`A&j~h3r~+%kJfJPp;q93FTXQKfk{0V^%KG zFaaQRyVAY}tz>Mi;b6*5qm141@V5kwkpo`c2HwE^uz`^6r6R_&wb(z6`1irBU`SFu3t^Icc&f*TA z$1y!ttm>sHoQ^3>-eb2wT!gjrMZYO14t7_kO3rJ5=&XN1%%9UgD?LG!)d5Ar7wjjJ zcw=47qnl>yb;jB4tMqCQA)V3Ff>43Zfgx%Ko#--QXj7E9J;j;E(q8kSug@DwX8{|z z((QlYoB%S7ijOb#%N_#*fih)?)eDmP133t`bIQPRNRkM6R>aj(*YZpEwMg#9zcqk- zH0>`mzaz5H9O+K#?{i0(A5{`rB*s{F&y>WxatvVTaVo1@D6F?=XY z>JNEN<`A@*PkO&y^-|}}A{z2I34ySe%Xd4Nb_&9`vG1lp08trIn2J{}{Azw1qKN@I z%9UiQn|(hhTB@fe)g0`6bK&skn*iz{AZ!!duIL@@qC=eu5 zUXlHn2Y0=L>GH*3kR8CwG%CRU3aarp@9I8{Yr;g3^fCAUXz2X~ zu`gBjl|xYduXn(ZBx7z94{m8cQI_oQ%76f1IiRO*og6P2)N_P?Rjw|J3lrKJ2MbE1 zN#?R8xusVmn6+EsEP&?Qj(Ahg6-wcH=2j_H3T?Ahk`BZJ-dWXHr9mMSy#sS!G&9#X zwW`y2nl*ABy<=={ji2}vFZQUVUCOHJ)w179vGt;V^{w6(aWw7267OP&FoJ@ClDj3n zZBew8Rig)fIpC(&w2Rtv91;23uaBm1*>cz=wyE9YT`5yGTl+#`Sje|A z6~WODaEseXD*kb@z>EHh5?0tidjySA#>Z1jqqu*!dh1OM|F*grbE&$q_COvN_Zm1j z7>dW!ihhf6xW4b{Hjk4HHGRKY=C;m^jo|RW)L}D6Y6`~hol>6tj*aAL${s(oxH6ji z{76+=I(4KnlreZE`L(zYC>4}j$GL;hQ_ypf=l^x*Hy7uxDK-}0b3F>^xj=^M7NENA zd6Zs0x;w;FZ#k2V?r=8Rx*S$JiMr+_-*_rIM z|AKWZXsjBsOVnuLcw+&;m*&!JO>>we>lqlP$|rqw_wReYaSVBfD3(u!0;+<_+)j!z z9exlP=vb?TN~kueW#PC~sSKsY+iODmCEiXe@2jrkv6|TS}w`;+!nT*BL3i6II z#^NyEJf3#_DWsqMID)ZqNrgcUI#B(G?prPpMKj{< zm(A(^a}nU!7~Fon<8+i79XQ;(*YK(&ok4G1@F+Hy$hfC<6k8q6rM41u6w77k3bkC# z`vBnVc*6^4qUD2r@;$m*gJ>9frRX*p67pCs8liJ|zegGCHWNruJ+2R3c?aRDq>QIv zgk=N74}PPEIv=S3Qo5OPA5M#hwlBSi@(X(KKJBzx0W`#S0s>$LxZ)+syG2SFsv zDh8fvq&LIS&D*rAGqXMMCIQ;#)&bhz&Pf8aLDdzJ<_$Mz4`t9X$)Z_|Wb0*xxJx6O z%?+0oa=)cI9Nj_?lj-j1{>|9uk^(=S=Zvm8rLN4WfNNKYcbDg7&F1D>9W$o>o zYD}7^+pi#f@kM3m4?E4c8tlQFL(ktYusP6cvveHn2 z4>Lv|_q)tl-txbzo}O*LU7M*UW?MUXp;>XZ`E}=$9WJ5p>BR)v<3BsMo{XtD?<;@D z2!%g5uH5W>6Q&MJfj!q3`+MsVEC; zT1MVY(0&-SOMyKsqMg zXTt?P3YL#erCOIf=rwKA>$>8JNj|Q{xk!d1ldstfnqw+ZNqS$}Ac&!=C70z0^e{k! z78CFDD$X3}migyD&A}90)5hjEzB66MUh5qYl-jqw;ar06i+k~qJ-mCyQ@eNA9*)*o zp&~}jUC2zuNpa5X%mptD32d1I;GxH-&IDsBo@zVn{nWIF9*Z@MC&-$jg_A1__n)|^ z7F7_DgdnKwmO)tsdBvK+0>46DS)qAx7j*qvmHqeQ1A9Fqhh9Xy=Pf(ll(6iACrzmtdp037Lr*z3`BoZiuBDyG=diKVNV-Pon895-xnd zf6Y6|@M(+oDAq`ksG7Aet`vYNV?~KRiM{wm1by=EiI?@qxgs*?r{sg%F2eV(Y&iFE zfhm7&<%Lu*b$Di4rDm{XCNO9AjH!--K?DBq9l2$r@Esi=(&k#2+2|7a#3!-OMv5jc zXAQF((ieKY-BXY~|5Eo^6@Ty*kw3tcw}PkHpNzuP65_|nPim48EodxFPM^t7zA0}g z`m_N1RZlN){kMe0q;F#MwCVK+Nj+FD_D^W9a^h+4TvVZ4J6XtuJ7i{PA^r-dXAXy@)?YrW_dn_B{%=6u{hXv0b?Tn_Yry#YGy&wf= z)idOg1TjWYgB=Bf3tOv+>)jF!L#+kjB4PJA?oEW^_96hR4M#Sv1=o}y6zo6@9Tt}; z7*uS?iNxCFZ)R-FnExoMXC1{j3Z%Lcu)=-!3+IxaeLxuQJ6W0e1r3?`--TVvGaba2gbT;6;*Dr zG70fBnFDGQ=JQ-PPFBNUidTWESI}Bl(tFQsz0UAWmms|E-Z~~)YBZ^})y5&wxTOIp z34=VnF%znqyPbm8YKhTYvvqIH2VV5u;m=JNF1JO_l}kQT7Ym~g+w*E&o=N?@mwd7a zuMGL@I;7IxIa1B?_7Gmh(#)qol0%tXzj7p=f9Eh8xYE-g@Qdr?`E2c1@&mo02NsbS z)5pz2V7Y6a6`p4E4>d^--uf)39I)D(*C^d(b+yEoovVpU@e6lHn$5%) z6l189w%pVG3!KV#5@`KHiZbs^>ugLrjX4*^)OA)Y6Z?04ig|Kj))5G;#Y!wUbMqoQ zp@qKHfr$YZ$hkA}On3GTM(<7vu->S25UrYFV&Ycr*u%n`;X!Vsnpa3_;!QLHEWT3W z2r9}6FDj)q3^+>~%7h?ZdC4dgho>Mao4q#1xe%i#X%G z=BnQ=Zwx@m8w!?h#yV1uCn$OOBYyhe%^!z$Ll--3>NgL63_# zSZN;%@U}gEL_5&*@VkN~RQ7^){8OgoL1XVWZI1g7sdxH#VbWKl)XS$SMal+e;^S_k z;AkFg+QWs@W)sV4+eF|}HxP!uer<_??`=%U0L8d!DaLPL!mj1N`k3j3*dANVWruEJ zl%}W#R9Y-{8x7&u#g=@kyOeQr*bfjyaadCfs>8E(jk0zD`ZWABnQ7nEYIFL+nmed; zk~-8BBZu@#2SKgxE9T!6Cy%rXyeS|VAd-t;OWPDtF$*QPvw-?)A&2l^(gXb*FtazP zI=Wx|E802=Yc222uWNQS=?Z0Ps6}QJCTVH^~vK6co4*4$bf67 zi@LR`)1si2$@AsIlU6d?2^CK}&My(+Q1mDGkIIgg{e2Cki2%v8>%`E^5vAbzdrt^m2A;!a=JGiol1z9$rY2@1EAtjb=9`U1llHs|@8;4?Pl$Ra31fWct0K2UY38dx-%;<>1gbr_^F|O> zGq)n>^uw7|dGbauN^_M4dQg2x*|((;JvIKw?~!zd4A_TD!iLeq4%I3f3a{l2_#%F4 zbwbri5vxVu>*|iBK83Twkewpk@yZCZBicumF==?;jAua5rFqqZasHdH;R8Vfi(;+u zlkR3w>4`svBY(^`h_)Xd<{Q;o-W5nWjo=V?g0vNr#U--!^)Ly1`>J{YP;@VYr+g9M zhU%yQU-pdQbT5wwUQx7&em(=&b6B5r+%bo;rcb5TB}LE6{Lp$k?~`CttOB%tAfUjd zoS0J|0$CJ(l@L!(UlQqyViFhwzR#Dd=-1nSk#bx@+Z<8Up9+iMSOXw>*{?N z4LZd1fP38^0GO2NyzuZ)S!f-qo(<%PT-9KIy^Z-#R$^Z8+Uq#vdcrFuji_H#jDKNP z)%$~O*g<)c?-0uI1KBN|=Ev6@5|K>uuxy>j zqJK%1)B8Lyj4zPJ6lh8ZlErPxM?WL93W>3gkpUN;iH~nFi}6FVz(xw4=^7dY)dUyi zksDGi#%?HH^}(|acXNWsr5x2$5yq5?+B~$hS3(Xc4WptUq5$n-qR~aDcfMP|?8QQy znEob)#*G|hxf-0}nZpv1xi8o3G&j*#0OspGaIk+s!o~j*Y0N4pcPH7VIquacE&7G9 z#1TZDD}w}UoOJysp_FRhrM;%@gO(x|rWCGyiq$n{M7?9UwobA9&>8bOy?rT@848FD zSS>_X&{iDppo{3}5A#3P-_Ai-%#kGi)T3qm%BGp4?-PD)Q=7`MwGds`E3&_8x}v?Q z?Zp_YVCqw&pmjh-iuz-Z`cnuRi9=#iZa;G`0@_FuT+L4gPIR&T$$51t5B2$ry;tuf zcOlKT4>EMd4dMI38uULlm{H2^k$u!AQ=|2u%HUcwx@anwXd%s@FL_lbA89PC7%*N- zAzf4~lQu*rUF708Ma$6j6q$$}iq?Z}xiUI32uKv77*QU4Mm)7aFi>OpGN-cZWzOg5 z?qyTUEorY{b%`HHF>%@Z$y>_MIC5-w0qt=&(Iz}+X8j5!JM4hsD&iDgFfHWaauHRMGN%&D zam@T6HH4=c;>D@ZR}C-^QiJejYTJmL#WgdCbo`Et;>)WQym+wev)(rQ2Cw?qVe8co z%4Mn^A^qPTLC+@mp-p+IDac^K;PC(rh{v(l|2|W4>{AJd`N6r++(+!V8K8uT782f6 z5cMCt9(=-jwE*h$|M+mud>wJxQ3Q`XAc?$dekgE!uEF1SPd7Ty#Q2lhBu^Wbt?lLW z`>h|%i%7T%9X@R%p*eL*&L>8;R5>>7L;qYgz=YqXsU^&5vWAw>q*xr>{v|XRTM*p+ zMLM7+l-6O^2SXb+_kK=W>m4xFBuYb6li3$Q=nZ-gNuf$9v@E1P^XOnt$cE6>@7s;3 zK(#l{d9BE8#~$fi`uwYC8~&B&K8piMv|idnEJWIg;!vhD(YPPwc~j8imb?Bf3+Sj9 zBE&d&+Ep2jbhe4R#?wCXu}gIIR<#&sr_!LdItYb9s`|jEJonP{$K9yNbN6QvvG*~? zVO7dGy_c}@IR_ey=7l^02yR9nNr|Z)v^33_7&We0+S$?C`Dk3g&_r;arjWz2*fC>s zL+x5o{g8mOCzC*?C!^EEo%+ZwkkG6)c-8_l$kD#4^8wc@3&*F7yD)EeQ==czc(hC{ zpctQNUO*cZd=spBakhYdT8a!524e^y05xAKcgJQwGvKm9ZIdlBy{fcPJEmf+LY@^ zT<(69Mkrsqd({qv&|Zas8JYmnmDI_1(?Lq^fbl3*ehbF;9Yan+EycfbZ2$qgKfK}p zDc=oo&`;W+cxAN7Y5fXey+#Gu4qM3hMd{@G>4mUbfW(F5^0@XRSyKxj}?Ld*|j=LWPxc+B-#s)*pblv1-Dz*6+IS$|87A@O|OyBl; zXWH^i`>KPx58m2ACsOxYHC@pH%C1u@r&2e)Jg3nY% zr(y5cMyk@-UmYBX5Ej5j4$7^ie^6gl%bp{_iB33}|3$&~kMIGS z{G70g&)#m&6fxgss z?GY7&gD})q%Tw3}|Q@rLwXVQ{(8QG2-f*8yQ{czTxjCJNjtHb)~Ad^$ctiB%M6ITO@Mb>GjuEG$h7eFN5ACDW@BZYVYv)kDb41JfA)E%yzN zX>FTY50-i8%A?$|O;Z(CvSl=?GCA$jahuS?12Cp$dV(4OL&SKZKs~ zibLBrcSdI-c`k{Kj3szV>P^qOs71teHjpP-T+j2A_=Xl7pe76s@`Xu^o2Y3cFjlsA|C zV@Qqp9H%fWrhTrwj#KDwRn#`0>olD#tqt(6eP2jm9?5Sr-I?|uSiI!Ukfa%8vin)j zMg428E+nbI(UZ#~;B_}wff-jOWq?rt8YIidTmrNr>EA{v?kcXne)}suf^YN72nCZqzs6>p-vU4Dg3+3D&CVtBG1mv+Jm3qv2Wg zT@a){5{hmO|E7rOckGEj;Pv-7L65CWT@XmFhK63#rAJ8A_bi~398xM(Aq}AycQT~N zk;T7;I-5UQFT$ttgT;++jr27YpJ1%58NQFuKI#!E5$XL2Q|KJjg9+ zKrEokyPNfwCT@mPz=)gUlOlbt78%R2#ouuHA3Vr;jcc=o$4AD&P+Y+XZE^XlVQSpB zhcBcJ4jzIsWg*-3q!)hirXqJp2_9LPkjy9fT(~%+M)7M04`ux{pdzUbjfTl=Th}8X zq0;jaqIw@CzA3EiPh~@V ztDNpjoT~D`7|BI40-DOf5!b2?qP}JJcz%s;y@dIyI%7j3|gun?oS0%;Sh>MNo zY9uV+fkXBDs||Lku$MD*R&E;9`OpOf6vx&CJ6}QIt7u~L0){HpEnI8RO zH{&^&K*qE>{i{K|qUylPTKO`Oj*C#E7ka0%aR+*Ktuh1$`B0k{c^T(4o2IGzkw9ZV zgafY{-v%1s&&=~7=)Dh+o}AX|*X6oQ9>-4)UEB*epvT<`m%k^rj^E&V9yilF3&oqO z4#lI#2dS#74|o+CXB3dJGiR|$f@j^-TrRR%8qwV!SR4-pf&8bvTGC+YGG9#IPu_-p zonkHCh7HS`r)lOy0BbGH`_}dH^~LDYuLCo$vr+TKPfkuFryo7qxL&~FSgRJ2L*_sY zDi5LOf~8mfl^C^S;WPXEHBTC~WZ}@*x66adK6B4nWyj*VKZTwS?|oo&f9(H6e}p0* zFH3$p+$XV&tx3;og4&wm^XNao`<`axqTPI=^2~1?jiB9z4#?J1k(c?y$nmm4R3n0s z_T-oE@gPTlWTp+3!d{u05omEP&wzC{g0<7dp{yqw>xch{kw%iVZ{)4|-&+s5!1l6l zMlE?zyW^cDP=-Jnu?}X${GH=n!kthVGQu?u2OEy!gV4c=2p-Mm4=5;-xrM>%JN(B{ z$rU=M!5bk~-*;KMXFq4+Z2;8O5v_BpLk-wR7*|nhRtGu9=;GyUx)S7Uf^pq)-Fgh! z+?ru07e1)m(N(0~P|+3=eqa`P%fm?i*Xj`hMBvn}u0`&fy?f+u0W_E&gX+mldF}j; zXw6iIuBnQf^^Nq=2y-`-gy0TmKM{A|D&zE2t<5iozMNg8-yy=v+-S<&%mF*nx)*E+ z2R38-Az)l8W($cuD`G4IVw18@q}z2YcV9o>r&Bx-ms~wbI^fVZA0#5XB0H--Q>fJG zV~xlabI)w2GIGc8kAv82h=zkQ_8=fSJokIjdu!FaTWo(qHX$Z`Z5m02>#rZ5vOaNsN~xtqv@bx%oz zdq@WY%_@NpN&yHQniT+}0y`Im+G^X{x6EYk5og3f!TBE#iP;^p5zP zd_e$s7a{K7n@fcL@r>a_%vXgwJ!HPhK(iD!P6}`Y{{s&IJ&V_-A&&W3=#5+J)SxlO zO+%_pL)id~DLXMUM=yBzjrj&edz5VDVik||j*KiAS$E3yptF8h_6r=F01F*H8349p zrGGvNa*QG-S^M$b5a^TXZi2GK-|L>Qt zuDvk^w~Vp`0+#cuzI8J#=J?S&-upbIFqsOo(x^Cz(fiCBamZQLG8%vTmrs?8fBJSU zlUb;Zjs6cCn5cbJD4o6Lj|}fHEv*`3d&jFHLcR#J0{l?D=qy%}J~xhT_QiZ`Gi^1D z3R#T|zSgkyZ?~w>x6-}{TqwDYUu%p!;XCjA(PsW?)ROT0QTj`!-1igc*%yU5;Zgf& zsM-c1*}22Gr=a;GiBn<4hfTfv=Vkg_d99AGZn>=hGTMat&+U|QNX4>nGk+zDHlH=E zb2{hw!)-=oDI-(OjW?4AC6Ayo^%bu&b+6pJ@5IW~o00j6?1rNwar)kDkz4Xj`kA~`pvR@8m8&_e-C**2VQH-xq0=2jBDYG!VxO31|tOVq-K>cV| z=F!mNr+L*!J*|I<@g?zZK(O#YLF`YB*nz_NR?>$f`{BbR<2{YER}aEYq59t)VV^4^ z+=F+yY{-`k>a*zuoX^m_gGh5rgDQ*wdy^K1m6604kFSgkcsLWz+$Lgh{MT;dM|Ifo zUoWU0hI_11&?_49V@G=m@+^$#`vRZv!AJB}_ruNA?`RhX(-4?7y;&B=9zWKgrEJnm7eI8*)QeF@ z+^{=6WBl5h?e+thZvVZaGL`mLq2;Up;BPs+KI zmQ!@P$;Ib7!|NDN-$XARBi2Da7OCNW95`h)8FI|47GZ4rpSWwRDe~}YkrMWuM{@Xl z?6n|V5l+|f$G8H; zaaF*Rm+tsMiCC1I*j8?3U7(oF2Es566Y^2}AP>N&jvtIy=ELf|gziMY5ckkCVRX36 zCH)H)`%_!!=O?W{PLKY&Cm_U}*#tPQAP@gFD$!rd%+{)NqYh8A;d+UJhQ8@>koVE} z3y~3Mu3o{oI-~0)R=751U9Z1K1{d@O^qY$nJ`v)yaNBPu0Z_Xyuf+T>p8s|G%cBgN z06eS=s@cDEvw!z*AOBtJrmhYLIx}v_EVuc=(%hGasd_hcd~}A)+TRKvG2!Oo#3+By zCj6sl!8N@j^{wrr}@c44Jv)PAyug`-Zf4wb+EhYR%Y+ zpD65O$+YL3Ipsa0235u@VH3Ukuny6Ezg)-WSAF$)n+bWF90GwFc!|f0x~Ey!x;hoU zOgEV-cz*oK*!Mz+h|6H8g-MyJp2I^nYh zNpeoExCSN{7JaI8qQC5o1i8R!Ar5aOv7!^y?CRkqO!BFnsepo`lPcrp16c>fIm({& znj$ORc+;peankKWWZ*mnAt=14D0A{-mZ&qNlZ7tF%$0r6W4+ES+m(=oiJvJI@KL|$ z(@IyBG#$Yg5NE8kc7k)yNMT#i&bjTyIp=nqTFg9b?QUDX&#?eH#qI*LUGzc zxH%YMO0VYxtvFnf%*UTFtp4;7Wwo@>E9g|rzjwciqjj_I`OL}_8JD!1eOZBhS@qj| zT?tohUZ&02Rh`YmZ~FjIQlLB*xIjoGgZ@0@uU#Rp_Oep_NWoxNltnAb`MJ37;394g zq{ZnS86D$kZf><~vn7T12}(Ug5d{iPe|o^V4lI@Obw^Im9Yzb&lftT zE8XiVUov_gJ_EXfql=}5XxE)B7j3JRQ&#Kfj9Q)ki3IFM;!u29}X z_*{mYl(8f4l)U`l9UV(;p@&DQM#lySI3Gm2;_-K4soB0zKV#{1>3U2r5Zi_3b)qa+ z!F|iYtJ+qKfX2H2qb{XnkSWGzfQA_aV)l zZ4Gl|t5k>BmUpQuBKnlhNq99$k5@Mc-G1M&YRmr0 z2Tfm=b`3p>1=wjF=xRa>^M$_ihqmW#{nj(vk`{2PN1N1UC>f_B&>pQD<%q{#A4HUhVDp9DElWPyz^X8X^^n7Taxk#iZ|O-aqb*Cwl}VPMdRG4pK4 zfF9;XpbjZFTrMgFz%~#DD)7@hn2@)%+35v~G<>-z@*W~2{xZBc4+aArK5&DsI&C13 zVSy8n7mYSpbM7^S&$U>+0 zopURkM!8Q zU%Lby4*9sAUP!GYd@o~vIL2h_`AvVAMI3~mA5u&oRkG{3^n}h$Srz*J%0ieC7 zDi2m!*&kduNHUwjExaM!zDxzXvfEUS9$El>QeO7im9gf7tB_ z9>?+98oWXoU8NsPGHIKnw(x3mi+83^`VIG~m6xX8G~($U9W&!XfGd_pl5Sion)h~2 z-CK{&HoZjTUrOmMykIjprnsD{+PEY$DSFD1qr6-dNm70ZRu9IYsjdb3^y7$-kH$A2 zkkRQW`#RmElOy$>^~PBCP}zbSeCCoeFmv*AjPJX%n)5_3P5l0q zL4B!lFrTAfk}=&M{;90;=0K#oGlqxxNej<4ib_ma%F-p$>E237jUhHvJL9SwYIcsT zTR4`UmrV{7LLyFG$sJOeYaHwWh!o&kNakk}kY5_n!V#DuHR|F!u z74@RP=(gf@Uq>MQ%n~(6pdJ!%sgPi#3NZmbXL=RViUt%Zm<3t}3=N&H8>Ajz1Cc&W z1NWV!9q9fXhCp!-k*EwO%(tz8TcF$}ATZ~>p>d8Mw*CknTZ;=MqIuhq-)>M?(pV24`;FqzRIG9rgL6v>HgpU^+$9z?llJkKxPY17H2Y-B}h9e za73Nyca&si{Xiz&HRgg`3>X7%Kmj}JmdK~JzWO?4tLThB-O>R!xx$*$Zg{5t1GH54 z3*M3KcIK4smGXe|3KpR(DsSS9W1|f}?bE8X((Y#ZO_0#Y0cZ-?u~HmRSf1wnKrtq` zb++*(7;YBXD_zBm0v3izrk=u8fXBa`D_0X|$S>x_*1TAn;VtFiEGYCrzlLA+ zT1XK$)>xQ#WWIL~b{n|BIcNIS;i(P~nVEl(Dqde-u!DO~P3K1;w}?BAnZ~i5v{#?4 zQ#_)o0w?v1B2G~9|2HEG4kTig^|;lLpQEsAn_~TMm862p3fz43=CYzQ3M`oR2j=QRHNf=-Q&>*`r_y0S zZdkkE%=xscw!Yucx8+QKc9bkc8+86+-nX+2d^}Rs{e?>L=?!q7lHNDIS(!Wn(Nc`O zZp9376)rOA#VmrxpLK+DK;bHULVMtS!l@>_F%$yxif=uWI41c`Oi9%XcF71tN)EPq66*KH0uH?Jx41>m$> z=nX6MerUKI&LdvF9}{&{H2JA+?~d;`0Ca1&wrQAVRki`lKW~-Ies)$Ksi_)TcSShi zr7x}^^5{splLgwPb!P#=4Ryjx764A1GsXpx*ZuREvDY+}W`p=8nlUl2(OUT0ubxCR`8Q{O`t*KdQSk#NP;7dlIhP6~H%yY1#`(wYETnb4HxS7BFqu zWFhhrfPWi-i}>55{09eb0EsuS6S1X$+`-D4Y%>z1U0HBJxSBz3a%98r2K`zQ+hDGaK`{cWxx2v!3Avm1 z)2hQcdwOYs6m3$}mQUMX?S6!9akdPcf_0(u9vu`Hhj_vzkf#ncF~;8gWMw_W7IZ>I z;rQ@k@Kn9-69ITeCIbEU8DJBk!~FVF^Qn}Can1pDmj5$gYj8`Au_4|!DX0x`63p*uKSI9o5>CwuAJ zxdpG1QvQ)%(uGX~da5FAi#?mzCXz?Din#MyZTe+|Ui4}@~1AYT7ro{ylH z4Iuf=qxqNa%pOoa?Ju`mU23=5E2KMW(`^vkdkM!kWda^Hv_UdJ2W64>QJZOr$vMk6 zkMNM!*~PqFpe346a2(E5pBr_p3SWeV1ED`y-cRrBWS<1`zG8#egQy6tg9dNjA{xT2 z%6@)JIdQt;ayJxtL^4foa~rSu8FKz|fOKTO4BkXDqcxk$4GexJXs71LOzA zXbJ}W@y=79-@Rh0_XqYI`u3J*xd62-;*D7ZS^u7cNOR28E7kjbd+7grm5}Ndj8Zm_ zps}dY4&C8XI8aIG9Iyvd&*O|4M5)>5BnnwHH_FQ$-^^X#3AA8s;*no*Sg*^m^^@b7R8UPjN zsGA5Ny})lPmXRxII0Y&^V7$k*X*8wvY6@3F*K2mHM8p8ll~j~; z>|2-wh*R%Ctlz0Mfv;)<%d$VaS_#+O_mDaXdB75oyh=JFRWwoC2db>fS@3riaww{P z-xegnl0v;(oDbKgP_@6F269fzbG~EZoZhXHaEnS=Yph&uWMXf{ttqcGa(|Q$==8Je z^kYo8f7w>seY4SCvFywgonQR!^@_Fjb!C$eQ|JdLQbzGqC1s6(k{T)l$ zxcR1^)=3+A5rldDv3T;~ZcP!ruc5WcRQ0VXaimrBLz}Lk**Ki5@9fgR@C{H!v-uV3 zRn``gnu=+C4aXJ0Y@zqcgU>FLFD}rk(X)P~hUU1T0ESH~h!{a2-<`9DX`0f$|IpMP zDuv(Ge5VM(ksCX1^`-Sl4<}^K-PIZToB=aE^@|e*6A6S z02u|!QH=sd9iHB3(V0!u;tNorek=3eMa;DRO`As)-W>x}G+Y807Ny210gT&}bjuBt z6|+=}C?}w4#Iqz34fz7}rCRV*iXr_X=MN}Eme{fYw~<`a`)3^IZPzxrMotiKdWQML z+)AM-RHG^Mhz%0vkaC1N=`hU&8!)6q|sqLeq+(d(p}@pHujm(BUVw+Y73d`!`r#Yt0NCp; zohMc`GfMNoe%SEcU&^sR*Zbi*M|8}`?EzQf~#B2|^UkH`IIC#7Va9Yz_fZByT6!3ze@$qyhfE zoq$2frn5|qq31iKzK75n2KzSS&&ni5v~&00(sZ`Cz}q)SktK($-Wyno_QlYh9{JRU z-Ac21dd)X~4AyhkpU-*7oB17f#I(o6w(nA7nE7B#kN1jW+`o3E%RByReQbBFV_wpw z2~ug$_Ax#$Mu&1_)R4-sK^-0w%#ej[^wj?$rK4#;>msDj9|>}w~Oan1MqfEh_r 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

    DXn41v4`8*ed~N> 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 z%0A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
    ", _("Mining address to use when special address of 'x' is sent by miner (default: none)")); + strUsage += HelpMessageOpt("-stratumbind=", _("Bind to given address to listen for Stratum work requests. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); strUsage += HelpMessageOpt("-stratumport=", strprintf(_("Listen for Stratum work requests on (default: %u or testnet: %u)"), BaseParams().StratumPort(), BaseParams().StratumPort())); strUsage += HelpMessageOpt("-stratumallowip=", _("Allow Stratum work requests from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); + // "ac" stands for "affects consensus" strUsage += HelpMessageGroup(_("Hush Smart Chain options:")); strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash (200,9)")); strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60")); diff --git a/src/stratum.cpp b/src/stratum.cpp index 233277520..4dd30f524 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -681,15 +681,21 @@ std::string GetWorkUnit(StratumClient& client) if (Params().MiningRequiresPeers() && fvNodesEmpty) { + const std::string msg = strprintf("%s: Unable to get work unit, Hush is not connected!", __func__); + LogPrint("stratum", "%s\n", msg); throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Hush is not connected!"); } if (IsInitialBlockDownload()) { + const std::string msg = strprintf("%s: Unable to get work unit, Hush is still downloading blocks!", __func__); + LogPrint("stratum", "%s\n", msg); throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Hush is downloading blocks..."); } if (!client.m_authorized && client.m_aux_addr.empty()) { - throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a Hush R.. address as the username."); + const std::string msg = strprintf("%s: Unable to get work unit, client not authorized! Use address 'x' to mine to the default address", __func__); + LogPrint("stratum", "%s\n", msg); + throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a Hush R.. address as the username or 'x' to mine to the default address."); } static CBlockIndex* tip = NULL; // pindexPrev @@ -706,7 +712,7 @@ std::string GetWorkUnit(StratumClient& client) /** * We will check script later inside CustomizeWork, if it will be == CScript() << OP_FALSE it will mean - * that work need to be customized, and in that case cb.vout[0],scriptPubKey will be set to GetScriptForDestination(addr.Get()) . + * that work need to be customized, and in that case cb.vout[0].scriptPubKey will be set to GetScriptForDestination(addr.Get()) . * In other words to the address with which stratum client is authorized. */ const CScript scriptDummy = CScript() << OP_FALSE; @@ -721,6 +727,8 @@ std::string GetWorkUnit(StratumClient& client) // DecodeHexTx(new_work->block.vtx[0], "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff01aa2ce73b0000000023210325b4ca6736f90679f712be1454c5302050aae6edb51b0d2a051156bc868fec16ac4aabc560"); if (!new_work) { + const std::string msg = strprintf("%s: Out of memory!", __func__); + LogPrint("stratum", "%s\n", msg); throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); } @@ -1244,15 +1252,27 @@ UniValue stratum_mining_authorize(StratumClient& client, const UniValue& params) CBitcoinAddress addr(get_stripped_username(username)); + // If given the special address "x", mine to the default address given by -stratumaddress + // This means a miner can run a private pool without TLS and not + // worry about MITM attacks that change addresses, and leaks less metadata. + // It also means many miners can be used and updating their mining address does not + // require any changes on each miner, just restart hushd with a new -stratumaddress + if(addr.ToString() == "x") { + addr = CBitcoinAddress(GetArg("-stratumaddress", "")); + const std::string msg = strprintf("%s: Authorized client with default stratum address=%s", __func__, addr.ToString()); + LogPrint("stratum", "%s\n", msg); + } + if (!addr.IsValid()) { + const std::string msg = strprintf("%s: Invalid Hush address=%s", __func__, addr.ToString()); + LogPrint("stratum", "%s\n", msg); throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid Hush address: %s", username)); } - client.m_addr = addr; - client.m_mindiff = mindiff; + client.m_addr = addr; + client.m_mindiff = mindiff; client.m_authorized = true; - - client.m_send_work = true; + client.m_send_work = true; LogPrintf("Authorized stratum miner %s from %s, mindiff=%f\n", addr.ToString(), client.GetPeer().ToString(), mindiff); From 120219d5406e11bd3c97d265e232ff3ae8fabe89 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 10:36:23 -0400 Subject: [PATCH 063/115] It is called getaddressesbyaccount, ugh --- src/rpc/server.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index e999cc423..3e9d17cd2 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -831,7 +831,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // few RPCs means we can see our addresses and make private key backups // while a very long wallet rescan is happening if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && - pcmd->name != "listaddresses" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { + pcmd->name != "getaddressesbyaccount" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } } @@ -856,12 +856,10 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms std::string HelpExampleCli(const std::string& methodname, const std::string& args) { - if ( SMART_CHAIN_SYMBOL[0] == 0 ) { - return "> komodo-cli " + methodname + " " + args + "\n"; - } else if ((strncmp(SMART_CHAIN_SYMBOL, "HUSH3", 5) == 0) ) { + if ((strncmp(SMART_CHAIN_SYMBOL, "HUSH3", 5) == 0) ) { return "> hush-cli " + methodname + " " + args + "\n"; } else { - return "> komodo-cli -ac_name=" + strprintf("%s", SMART_CHAIN_SYMBOL) + " " + methodname + " " + args + "\n"; + return "> hush-cli -ac_name=" + strprintf("%s", SMART_CHAIN_SYMBOL) + " " + methodname + " " + args + "\n"; } } From 5c83c1b4e7a2a7344314785c7848ee5b4c92841b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 11:02:19 -0400 Subject: [PATCH 064/115] Cleanup --- src/assetchains_stop | 5 ++-- src/cc/CC_made_easy.md | 6 +---- src/cc/dapps/dappstd.c | 2 +- src/cc/dapps/sendmany | 3 --- src/cc/dapps/sendmany100 | 2 -- src/cc/dapps/zmigrate.c | 32 +++++++++-------------- src/cc/dice.cpp | 2 +- src/cc/gamescc.cpp | 2 +- src/cc/gateways.cpp | 8 +++--- src/cc/payments.cpp | 2 +- src/cc/rogue/rogue.c | 2 +- src/cc/rogue_rpc.cpp | 16 ++++++------ src/hush-cli-testnet | 2 +- src/main.cpp | 2 +- src/revs | 2 -- src/rpc/crosschain.cpp | 2 +- src/test-hush/test_parse_notarization.cpp | 5 +--- src/zush | 7 +---- 18 files changed, 39 insertions(+), 63 deletions(-) delete mode 100755 src/cc/dapps/sendmany delete mode 100755 src/cc/dapps/sendmany100 delete mode 100755 src/revs diff --git a/src/assetchains_stop b/src/assetchains_stop index dfdfed0c9..a44e3c403 100755 --- a/src/assetchains_stop +++ b/src/assetchains_stop @@ -1,8 +1,9 @@ #!/bin/bash +# Copyright (c) 2016-2021 The Hush developers set -eo pipefail -komodo_cli='./komodo-cli' +hush_cli='./hush-cli' ./listassetchains | while read chain; do - $komodo_cli --ac_name=$chain stop + $hush_cli --ac_name=$chain stop done diff --git a/src/cc/CC_made_easy.md b/src/cc/CC_made_easy.md index 30a45e173..ada471a8e 100644 --- a/src/cc/CC_made_easy.md +++ b/src/cc/CC_made_easy.md @@ -1,3 +1,4 @@ +// Copyright (c) 2016-2021 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -712,8 +713,3 @@ gatewayswithdraw bindtxid coin withdrawpub amount And with a bit more magic in the oraclefeed, this is achieved. To be continued... - - - - - diff --git a/src/cc/dapps/dappstd.c b/src/cc/dapps/dappstd.c index 286aea5f6..1d897196b 100644 --- a/src/cc/dapps/dappstd.c +++ b/src/cc/dapps/dappstd.c @@ -970,7 +970,7 @@ int32_t games_setplayerdata(struct games_state *rs,char *gametxidstr) if ( 0 ) { sprintf(fname,"%s.gameinfo",gametxidstr); - sprintf(cmd,"./komodo-cli -ac_name=%s cclib gameinfo 17 \\\"[%%22%s%%22]\\\" > %s",ASSETCHAINS_SYMBOL,gametxidstr,fname); + sprintf(cmd,"./hush-cli -ac_name=%s cclib gameinfo 17 \\\"[%%22%s%%22]\\\" > %s",ASSETCHAINS_SYMBOL,gametxidstr,fname); if ( system(cmd) != 0 ) fprintf(stderr,"error issuing (%s)\n",cmd); else filestr = (char *)OS_fileptr(&allocsize,fname); diff --git a/src/cc/dapps/sendmany b/src/cc/dapps/sendmany deleted file mode 100755 index 45560b505..000000000 --- a/src/cc/dapps/sendmany +++ /dev/null @@ -1,3 +0,0 @@ -export addr="RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo" -./komodo-cli -ac_name=KMDICE sendmany "" "{\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023,\"$addr\":0.023}" - diff --git a/src/cc/dapps/sendmany100 b/src/cc/dapps/sendmany100 deleted file mode 100755 index 9638766ab..000000000 --- a/src/cc/dapps/sendmany100 +++ /dev/null @@ -1,2 +0,0 @@ -./komodo-cli -ac_name=KMDICE sendmany "" "{\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002,\"RXgCPfi6wccRr3Eai3X9duTTkAirhcQLNo\":0.0002}" - diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index 057c2b374..bc5f8e869 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -322,12 +322,12 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char // acname = refcoin; if ( acname[0] != 0 ) { - if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) + if ( refcoin[0] != 0 && strcmp(refcoin,"HUSH3") != 0 ) printf("unexpected: refcoin.(%s) acname.(%s)\n",refcoin,acname); - sprintf(cmdstr,"./komodo-cli -ac_name=%s %s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,arg3,fname); + sprintf(cmdstr,"./hush-cli -ac_name=%s %s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,arg3,fname); } - else if ( strcmp(refcoin,"KMD") == 0 ) - sprintf(cmdstr,"./komodo-cli %s %s %s %s %s > %s\n",method,arg0,arg1,arg2,arg3,fname); + else if ( strcmp(refcoin,"HUSH3") == 0 ) + sprintf(cmdstr,"./hush-cli %s %s %s %s %s > %s\n",method,arg0,arg1,arg2,arg3,fname); else if ( REFCOIN_CLI != 0 && REFCOIN_CLI[0] != 0 ) { sprintf(cmdstr,"%s %s %s %s %s %s > %s\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,fname); @@ -1310,26 +1310,20 @@ int32_t main(int32_t argc,char **argv) printf("argc needs to be 2: coin\n"); return(-1); } - if ( strcmp(argv[1],"KMD") == 0 ) + if ( strcmp(argv[1],"HUSH3") == 0 ) { - REFCOIN_CLI = "./komodo-cli"; - coinstr = clonestr("KMD"); - acstr = ""; - } - else if ( strcmp(argv[1],"CHIPS") == 0 ) - { - REFCOIN_CLI = "./chips-cli"; - coinstr = clonestr("CHIPS"); + REFCOIN_CLI = "./hush-cli"; + coinstr = clonestr("HUSH3"); acstr = ""; } else { - sprintf(buf,"./komodo-cli -ac_name=%s",argv[1]); + sprintf(buf,"./hush-cli -ac_name=%s",argv[1]); REFCOIN_CLI = clonestr(buf); coinstr = clonestr(argv[1]); acstr = coinstr; } - if ( 1 )//strcmp(coinstr,"KMD") == 0 ) + if ( 1 ) { sprintf(buf,"%s-Claims.csv",coinstr); reconcile_claims(coinstr,buf); @@ -1452,14 +1446,14 @@ int32_t zmigratemain(int32_t argc,char **argv) printf("argc needs to be 3\n"); return(-1); } - if ( strcmp(argv[1],"KMD") == 0 ) + if ( strcmp(argv[1],"HUSH3") == 0 ) { - REFCOIN_CLI = "./komodo-cli"; - coinstr = clonestr("KMD"); + REFCOIN_CLI = "./hush-cli"; + coinstr = clonestr("HUSH3"); } else { - sprintf(buf,"./komodo-cli -ac_name=%s",argv[1]); + sprintf(buf,"./hush-cli -ac_name=%s",argv[1]); REFCOIN_CLI = clonestr(buf); coinstr = clonestr(argv[1]); } diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 4dd519b8d..67e5ff1bf 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1732,7 +1732,7 @@ void *dealer0_loop(void *_arg) if ( num < DICE_MINUTXOS ) // this deadlocks, need to put it in a different thread { char *cmd = (char *)malloc(100 * 128); - sprintf(cmd,"./komodo-cli -ac_name=%s sendmany \"\" \"{\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002}\"",SMART_CHAIN_SYMBOL,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr); + sprintf(cmd,"./hush-cli -ac_name=%s sendmany \"\" \"{\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002,\\\"%s\\\":0.0002}\"",SMART_CHAIN_SYMBOL,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr,coinaddr); n = sqrt((DICE_MINUTXOS - num) / 100)*2 + 1; fprintf(stderr,"num normal 0.0002 utxos.%d < %d -> n.%d\n",num,DICE_MINUTXOS,n); for (i=0; i 0 ) sprintf(cmd,"cc/%s %llu %s",GAMENAME,(long long)seed,gametxid.ToString().c_str()); - else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",SMART_CHAIN_SYMBOL,EVAL_GAMES,gametxid.ToString().c_str()); + else sprintf(cmd,"./hush-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",SMART_CHAIN_SYMBOL,EVAL_GAMES,gametxid.ToString().c_str()); obj.push_back(Pair("run",cmd)); } } diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index fdd304a05..d62760820 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -102,17 +102,17 @@ To make a gateway deposit, send the funds to the "deposit" address, along with any amount to the same pubkey address you want to get the assetized KMD to appear in. 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 pubkey for RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha - ./komodo-cli z_sendmany "" '[{"address":"RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha","amount":0.0001},{"address":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","amount":7.6999}]' + ./hush-cli z_sendmany "" '[{"address":"RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha","amount":0.0001},{"address":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","amount":7.6999}]' bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 height.1003776 merkle.90aedc2f19200afc9aca2e351438d011ebae8264a58469bf225883045f61917f - ./komodo-cli gettxoutproof '["bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009"]' + ./hush-cli gettxoutproof '["bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009"]' 04000000232524ea04b54489eb222f8b3f566ed35504e3050488a63f0ab7b1c2030000007f91615f04835822bf6984a56482aeeb11d03814352eca9afc0a20192fdcae900000000000000000000000000000000000000000000000000000000000000000268e965ba608071d0800038e16762900000000000000000000000000000000000000000042008dd6fd4005016b4292b05df6dfd316c458c53e28fb2befb96e4870a40c6c04e733d75d8a7a18cce34fe326005efdc403bfa4644e30eeafdaeff34419edc591299e6cc5933cb2eeecbab5c4dfe97cd413b75215999a3dd02b540373581e81d8512bff1640590a6b4da4aaa9b8adc0102c38ca0022daed997b53ed192ba326e212fba5e505ce29e3ad149cef7f48d0e00948a1acd81731d84008760759211eb4abbc7b037939a7964182edb59cf9065357e864188ee5fc7316e8796963036bb99eeb9f06c95d64f78749ecec7181c12eb5d83a3b9b1c1e8a0aae9a20ce04a250b28216620bfc99bb81a6de4db80b93a5aea916de97c1a272e26644abdd683f19c5e3174a2e4513ed767d8f11a4c3074295f697839c5d9139676a813451cc7da38f68cbae5d990a79075f98903233ca04fe1b4b099e433585e5adcc45d41d54a9c648179297359c75950a5e574f13f70b728bbbf552770256315cd0a00139d6ab6934cb5ed70a4fc01a92611b096dd0028f17f4cc687b75f37dca530aa47a18321c50528dbd9272eabb3e13a87021a05918a6d2627e2caba6d7cf1a9f0b831ea3337b9a6af92746d83140078d60c72b6beacf91c9e68a34cee209e08670be1d17ff8d80b7a2285b1325461a2e33f2ee675593f1900e066a5d212615cd8da18749b0e684eee73edcc9031709be715b889c6d015cf4bd4ad5ab7e21bd3492c208930a54d353ef36a437f507ead38855633c1b88d060d9e4221ca8ce2f698e8a6ae0d41e9ace3cbd401f1e0f07650e9c126d4ef20278c8be6e85c7637513643f8d02d7ad64c09da11c16429d60e5160c345844b8158ece62794e8ad280d4e4664150e74978609ece431e51a9f9e1ce8aa49c16f36c7fd12b71acc42d893e18476b8b1e144a8175519612efc93e0aecc61f3b21212c958b0e2331d76aaa62faf11a58fe2bd91ab9ab01b906406c9bbc02df2a106e67182aae0a20b538bf19f09c57f9de5e198ba254580fb1b11e22ad526550093420cb7c68628d4c3ad329c8acc6e219093d277810ed016b6099b7e3781de412a22dacedaa2acf29e8062debcd85c7b9529a20b2782a2470763ac27cf89611a527d43ac89b8063ffb93b6ed993425194f8ee821a8493a563072c896f9584f95db28e3f2fc5fb4a6f3c39d615cd563641717cd50afb73ed3989cbf504b2043882993ce9575f56402534173b1396fbc13df80920b46788ae340ad5a91f25177cc74aa69024d76f56166199d2e4d50a053555256c4e3137ea1cee1130e916a88b6ee5cf2c85652fb8824d5dacfa485e3ef6190591ac0c2fcacc4fc7deb65aca4b0b89b76e35a46b0627e2e967cc63a5d606a984c8e63eabb98fde3e69114340ae524c974cb936e57690e98a7a74533f6f7d1d0496976496b54d14a8163efb32b70dfbb79d80a3022c4f53571c08bf044270565716b435084376714b224ab23e9817c05af8223723afc0577af5c8fc28f71036ca82528aaa4ca9bcd18a50e25d2a528f183d3a2074d968d170876d8dce434c5937261b55173ab87e03d5632ca0834fdc5387c15ab3a17d75c0f274004f289ff1bf7d14e97fdf4172eb49adfb418cc2f4794806ae7c0111c97df4d65d38679ec93fea3ef738ed565e8906a8fe1861cafe3938c772fedcfab40159938e06ef414fd299f2355c6d3369bc1bd3c4db64ce205f0a1b70a40030f505b736e28230de82e97776b5ee7b10708bb3020d28cec7a8e124549ec80c547ac4e7b52bf397c72bcfce30820554ab8fb4d1f73b209bc32a0e7e878843cdbf5f01222728ccea7e6ab7cb5e3fee3234f5b85d1985f91492f6ceaa6454a658dab5074f163ce26ed753137fa61c940679de13bd7b212cd3cf2b334f5201cecbc7473342bd7a239e09169bccd56d03000000037a9068df0625e548e71263c8361b4e904c998378f6b9e32729c3f19b10ad752e093013788222f5c26bfc5da4eeb7d32f01486a54179f19c341b79d420ea041bc8878d22fad4692b2d609c3cf190903874d3682a714c7483518c9392e07c25035010b - ./komodo-cli getrawtransaction bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 + ./hush-cli getrawtransaction bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b gatewaysdeposit bindtxid height coin cointxid claimvout deposithex proof destpub amount - ./komodo-cli -ac_name=AT5 gatewaysdeposit e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e 1003776 KMD bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 0 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b 04000000232524ea04b54489eb222f8b3f566ed35504e3050488a63f0ab7b1c2030000007f91615f04835822bf6984a56482aeeb11d03814352eca9afc0a20192fdcae900000000000000000000000000000000000000000000000000000000000000000268e965ba608071d0800038e16762900000000000000000000000000000000000000000042008dd6fd4005016b4292b05df6dfd316c458c53e28fb2befb96e4870a40c6c04e733d75d8a7a18cce34fe326005efdc403bfa4644e30eeafdaeff34419edc591299e6cc5933cb2eeecbab5c4dfe97cd413b75215999a3dd02b540373581e81d8512bff1640590a6b4da4aaa9b8adc0102c38ca0022daed997b53ed192ba326e212fba5e505ce29e3ad149cef7f48d0e00948a1acd81731d84008760759211eb4abbc7b037939a7964182edb59cf9065357e864188ee5fc7316e8796963036bb99eeb9f06c95d64f78749ecec7181c12eb5d83a3b9b1c1e8a0aae9a20ce04a250b28216620bfc99bb81a6de4db80b93a5aea916de97c1a272e26644abdd683f19c5e3174a2e4513ed767d8f11a4c3074295f697839c5d9139676a813451cc7da38f68cbae5d990a79075f98903233ca04fe1b4b099e433585e5adcc45d41d54a9c648179297359c75950a5e574f13f70b728bbbf552770256315cd0a00139d6ab6934cb5ed70a4fc01a92611b096dd0028f17f4cc687b75f37dca530aa47a18321c50528dbd9272eabb3e13a87021a05918a6d2627e2caba6d7cf1a9f0b831ea3337b9a6af92746d83140078d60c72b6beacf91c9e68a34cee209e08670be1d17ff8d80b7a2285b1325461a2e33f2ee675593f1900e066a5d212615cd8da18749b0e684eee73edcc9031709be715b889c6d015cf4bd4ad5ab7e21bd3492c208930a54d353ef36a437f507ead38855633c1b88d060d9e4221ca8ce2f698e8a6ae0d41e9ace3cbd401f1e0f07650e9c126d4ef20278c8be6e85c7637513643f8d02d7ad64c09da11c16429d60e5160c345844b8158ece62794e8ad280d4e4664150e74978609ece431e51a9f9e1ce8aa49c16f36c7fd12b71acc42d893e18476b8b1e144a8175519612efc93e0aecc61f3b21212c958b0e2331d76aaa62faf11a58fe2bd91ab9ab01b906406c9bbc02df2a106e67182aae0a20b538bf19f09c57f9de5e198ba254580fb1b11e22ad526550093420cb7c68628d4c3ad329c8acc6e219093d277810ed016b6099b7e3781de412a22dacedaa2acf29e8062debcd85c7b9529a20b2782a2470763ac27cf89611a527d43ac89b8063ffb93b6ed993425194f8ee821a8493a563072c896f9584f95db28e3f2fc5fb4a6f3c39d615cd563641717cd50afb73ed3989cbf504b2043882993ce9575f56402534173b1396fbc13df80920b46788ae340ad5a91f25177cc74aa69024d76f56166199d2e4d50a053555256c4e3137ea1cee1130e916a88b6ee5cf2c85652fb8824d5dacfa485e3ef6190591ac0c2fcacc4fc7deb65aca4b0b89b76e35a46b0627e2e967cc63a5d606a984c8e63eabb98fde3e69114340ae524c974cb936e57690e98a7a74533f6f7d1d0496976496b54d14a8163efb32b70dfbb79d80a3022c4f53571c08bf044270565716b435084376714b224ab23e9817c05af8223723afc0577af5c8fc28f71036ca82528aaa4ca9bcd18a50e25d2a528f183d3a2074d968d170876d8dce434c5937261b55173ab87e03d5632ca0834fdc5387c15ab3a17d75c0f274004f289ff1bf7d14e97fdf4172eb49adfb418cc2f4794806ae7c0111c97df4d65d38679ec93fea3ef738ed565e8906a8fe1861cafe3938c772fedcfab40159938e06ef414fd299f2355c6d3369bc1bd3c4db64ce205f0a1b70a40030f505b736e28230de82e97776b5ee7b10708bb3020d28cec7a8e124549ec80c547ac4e7b52bf397c72bcfce30820554ab8fb4d1f73b209bc32a0e7e878843cdbf5f01222728ccea7e6ab7cb5e3fee3234f5b85d1985f91492f6ceaa6454a658dab5074f163ce26ed753137fa61c940679de13bd7b212cd3cf2b334f5201cecbc7473342bd7a239e09169bccd56d03000000037a9068df0625e548e71263c8361b4e904c998378f6b9e32729c3f19b10ad752e093013788222f5c26bfc5da4eeb7d32f01486a54179f19c341b79d420ea041bc8878d22fad4692b2d609c3cf190903874d3682a714c7483518c9392e07c25035010b 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 + ./hush-cli -ac_name=AT5 gatewaysdeposit e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e 1003776 KMD bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 0 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b 04000000232524ea04b54489eb222f8b3f566ed35504e3050488a63f0ab7b1c2030000007f91615f04835822bf6984a56482aeeb11d03814352eca9afc0a20192fdcae900000000000000000000000000000000000000000000000000000000000000000268e965ba608071d0800038e16762900000000000000000000000000000000000000000042008dd6fd4005016b4292b05df6dfd316c458c53e28fb2befb96e4870a40c6c04e733d75d8a7a18cce34fe326005efdc403bfa4644e30eeafdaeff34419edc591299e6cc5933cb2eeecbab5c4dfe97cd413b75215999a3dd02b540373581e81d8512bff1640590a6b4da4aaa9b8adc0102c38ca0022daed997b53ed192ba326e212fba5e505ce29e3ad149cef7f48d0e00948a1acd81731d84008760759211eb4abbc7b037939a7964182edb59cf9065357e864188ee5fc7316e8796963036bb99eeb9f06c95d64f78749ecec7181c12eb5d83a3b9b1c1e8a0aae9a20ce04a250b28216620bfc99bb81a6de4db80b93a5aea916de97c1a272e26644abdd683f19c5e3174a2e4513ed767d8f11a4c3074295f697839c5d9139676a813451cc7da38f68cbae5d990a79075f98903233ca04fe1b4b099e433585e5adcc45d41d54a9c648179297359c75950a5e574f13f70b728bbbf552770256315cd0a00139d6ab6934cb5ed70a4fc01a92611b096dd0028f17f4cc687b75f37dca530aa47a18321c50528dbd9272eabb3e13a87021a05918a6d2627e2caba6d7cf1a9f0b831ea3337b9a6af92746d83140078d60c72b6beacf91c9e68a34cee209e08670be1d17ff8d80b7a2285b1325461a2e33f2ee675593f1900e066a5d212615cd8da18749b0e684eee73edcc9031709be715b889c6d015cf4bd4ad5ab7e21bd3492c208930a54d353ef36a437f507ead38855633c1b88d060d9e4221ca8ce2f698e8a6ae0d41e9ace3cbd401f1e0f07650e9c126d4ef20278c8be6e85c7637513643f8d02d7ad64c09da11c16429d60e5160c345844b8158ece62794e8ad280d4e4664150e74978609ece431e51a9f9e1ce8aa49c16f36c7fd12b71acc42d893e18476b8b1e144a8175519612efc93e0aecc61f3b21212c958b0e2331d76aaa62faf11a58fe2bd91ab9ab01b906406c9bbc02df2a106e67182aae0a20b538bf19f09c57f9de5e198ba254580fb1b11e22ad526550093420cb7c68628d4c3ad329c8acc6e219093d277810ed016b6099b7e3781de412a22dacedaa2acf29e8062debcd85c7b9529a20b2782a2470763ac27cf89611a527d43ac89b8063ffb93b6ed993425194f8ee821a8493a563072c896f9584f95db28e3f2fc5fb4a6f3c39d615cd563641717cd50afb73ed3989cbf504b2043882993ce9575f56402534173b1396fbc13df80920b46788ae340ad5a91f25177cc74aa69024d76f56166199d2e4d50a053555256c4e3137ea1cee1130e916a88b6ee5cf2c85652fb8824d5dacfa485e3ef6190591ac0c2fcacc4fc7deb65aca4b0b89b76e35a46b0627e2e967cc63a5d606a984c8e63eabb98fde3e69114340ae524c974cb936e57690e98a7a74533f6f7d1d0496976496b54d14a8163efb32b70dfbb79d80a3022c4f53571c08bf044270565716b435084376714b224ab23e9817c05af8223723afc0577af5c8fc28f71036ca82528aaa4ca9bcd18a50e25d2a528f183d3a2074d968d170876d8dce434c5937261b55173ab87e03d5632ca0834fdc5387c15ab3a17d75c0f274004f289ff1bf7d14e97fdf4172eb49adfb418cc2f4794806ae7c0111c97df4d65d38679ec93fea3ef738ed565e8906a8fe1861cafe3938c772fedcfab40159938e06ef414fd299f2355c6d3369bc1bd3c4db64ce205f0a1b70a40030f505b736e28230de82e97776b5ee7b10708bb3020d28cec7a8e124549ec80c547ac4e7b52bf397c72bcfce30820554ab8fb4d1f73b209bc32a0e7e878843cdbf5f01222728ccea7e6ab7cb5e3fee3234f5b85d1985f91492f6ceaa6454a658dab5074f163ce26ed753137fa61c940679de13bd7b212cd3cf2b334f5201cecbc7473342bd7a239e09169bccd56d03000000037a9068df0625e548e71263c8361b4e904c998378f6b9e32729c3f19b10ad752e093013788222f5c26bfc5da4eeb7d32f01486a54179f19c341b79d420ea041bc8878d22fad4692b2d609c3cf190903874d3682a714c7483518c9392e07c25035010b 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 -> 9d80ea79a65aaa0d464f8b762356fa01047e16e9793505a22ca04559f81a6eb6 to get the merkleroots onchain, from the multisig signers nodes run the oraclefeed program with acname oracletxid pubkey Ihh diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 5f541a95e..4fd071fd6 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -31,7 +31,7 @@ First step is to create txids with the info needed in their opreturns. this info is the weight, scriptPubKey and opret if needed. To do that txidopret is used: - ./c is a script that invokes komodo-cli with the correct -ac_name + ./c is a script that invokes hush-cli with the correct -ac_name ./c paymentstxidopret \"[9,%222102d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388dac%22]\" -> rawhex with txid 95d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def diff --git a/src/cc/rogue/rogue.c b/src/cc/rogue/rogue.c index d1d42f449..9f135f894 100644 --- a/src/cc/rogue/rogue.c +++ b/src/cc/rogue/rogue.c @@ -191,7 +191,7 @@ void rogue_bailout(struct rogue_state *rs) //sleep(5); return; /*fprintf(stderr,"bailing out\n"); - sprintf(cmd,"./komodo-cli -ac_name=ROGUE cclib bailout 17 \\\"[%%22%s%%22]\\\" >> bailout.log",Gametxidstr); + sprintf(cmd,"./hush-cli -ac_name=ROGUE cclib bailout 17 \\\"[%%22%s%%22]\\\" >> bailout.log",Gametxidstr); if ( system(cmd) != 0 ) fprintf(stderr,"error issuing (%s)\n",cmd);*/ } diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index 1caedbe45..83b2f8097 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -52,29 +52,29 @@ std::string Rogue_pname = ""; Here is how to play: - ./komodo-cli -ac_name=ROGUE cclib newgame 17 \"[3,10]\" -> this will create a hex transaction that when broadcast with sendrawtransaction will get a gametxid onto the blockchain. This specific command was for 3 players and a buyin of 10 ROGUE. Lets assume the gametxid is 4fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a, most all the other commands will need the gametxid. + ./hush-cli -ac_name=ROGUE cclib newgame 17 \"[3,10]\" -> this will create a hex transaction that when broadcast with sendrawtransaction will get a gametxid onto the blockchain. This specific command was for 3 players and a buyin of 10 ROGUE. Lets assume the gametxid is 4fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a, most all the other commands will need the gametxid. you can always find all the existing games with: - ./komodo-cli -ac_name=ROGUE cclib pending 17 + ./hush-cli -ac_name=ROGUE cclib pending 17 and info about a specific game with: - ./komodo-cli -ac_name=ROGUE cclib gameinfo 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" + ./hush-cli -ac_name=ROGUE cclib gameinfo 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" due to quirks of various parsing at the shell, rpc and internal level, the above convention is used where %22 is added where " should be. also all fields are separated by , without any space. When you do a gameinfo command it will show a "run" field and that will tell you if you are registered for the game or not. If not, the "run" field shows the register syntax you need to do, if you are registered, it will show the command line to start the rogue game that is playing the registered game. -./komodo-cli -ac_name=ROGUE cclib register 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22,%22playerdata_txid%22]\" +./hush-cli -ac_name=ROGUE cclib register 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22,%22playerdata_txid%22]\" If you want to cash in your ingame gold and preserve your character for another battle, do the bailout: -./komodo-cli -ac_name=ROGUE cclib bailout 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" +./hush-cli -ac_name=ROGUE cclib bailout 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" If you won your game before anybody else did or if you are the last one left who didnt bailout, you can claim the prize: - ./komodo-cli -ac_name=ROGUE cclib highlander 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" + ./hush-cli -ac_name=ROGUE cclib highlander 17 \"[%224fd6f5cad0fac455e5989ca6eef111b00292845447075a802e9335879146ad5a%22]\" The txid you get from the bailout or highlander transactions is the "playerdata_txid" that you can use in future games. @@ -138,7 +138,7 @@ std::string Rogue_pname = ""; // ./rogue gui -> creates keystroke files // ./c cclib register 17 \"[%226d3243c6e5ab383898b28a87e01f6c00b5bdd9687020f17f5caacc8a61febd19%22,%222475182f9d5169d8a3249d17640e4eccd90f4ee43ab04791129b0fa3f177b14a%22]\" // ./c cclib bailout 17 \"[%226d3243c6e5ab383898b28a87e01f6c00b5bdd9687020f17f5caacc8a61febd19%22]\" -// ./komodo-cli -ac_name=ROGUE cclib register 17 \"[%22a898f4ceef7647ba113b9f3c24ef045f5d134935a3b09bdd1a997b9d474f4c1b%22,%22f11d0cb4e2e4c21f029a1146f8e5926f11456885b7ab7d665096f5efedec8ea0%22]\" +// ./hush-cli -ac_name=ROGUE cclib register 17 \"[%22a898f4ceef7647ba113b9f3c24ef045f5d134935a3b09bdd1a997b9d474f4c1b%22,%22f11d0cb4e2e4c21f029a1146f8e5926f11456885b7ab7d665096f5efedec8ea0%22]\" CScript rogue_newgameopret(int64_t buyin,int32_t maxplayers) @@ -704,7 +704,7 @@ uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 obj.push_back(Pair("seed",(int64_t)seed)); if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 ) sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str()); - else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",SMART_CHAIN_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str()); + else sprintf(cmd,"./hush-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",SMART_CHAIN_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str()); obj.push_back(Pair("run",cmd)); } } diff --git a/src/hush-cli-testnet b/src/hush-cli-testnet index eb98bc2ea..81cf1b05a 100755 --- a/src/hush-cli-testnet +++ b/src/hush-cli-testnet @@ -7,5 +7,5 @@ cd $DIR NAME=HUSH3T -CLI=${KOMODOCLI:-./komodo-cli} +CLI=${KOMODOCLI:-./hush-cli} $CLI -ac_name=$NAME "$@" diff --git a/src/main.cpp b/src/main.cpp index 26ffff8ce..fe08fe6b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4247,7 +4247,7 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc if ( !DisconnectTip(state) ) break; } - fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",HUSH_REWIND,SMART_CHAIN_SYMBOL); + fprintf(stderr,"reached rewind.%d, best to do: ./hush-cli -ac_name=%s stop\n",HUSH_REWIND,SMART_CHAIN_SYMBOL); sleep(20); fprintf(stderr,"resuming normal operations\n"); HUSH_REWIND = 0; diff --git a/src/revs b/src/revs deleted file mode 100755 index 5c8782ae5..000000000 --- a/src/revs +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./komodo-cli -ac_name=REVS $1 $2 $3 $4 diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 0ac6fd46b..0b084b896 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -670,7 +670,7 @@ UniValue migrate_createnotaryapprovaltransaction(const UniValue& params, bool fH if (fHelp || params.size() != 2) throw runtime_error("migrate_createnotaryapprovaltransaction burntxid txoutproof\n\n" "Creates a tx for destination chain with burn tx proof\n" - "txoutproof should be retrieved by komodo-cli migrate_checkburntransactionsource call on the source chain\n" ); + "txoutproof should be retrieved by hush-cli migrate_checkburntransactionsource call on the source chain\n" ); if (SMART_CHAIN_SYMBOL[0] == 0) throw runtime_error("Must be called on asset chain"); diff --git a/src/test-hush/test_parse_notarization.cpp b/src/test-hush/test_parse_notarization.cpp index 5f7549071..655c6d5b6 100644 --- a/src/test-hush/test_parse_notarization.cpp +++ b/src/test-hush/test_parse_notarization.cpp @@ -2,14 +2,11 @@ // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #include - #include "cc/eval.h" #include "core_io.h" #include "key.h" - #include "testutils.h" - namespace TestParseNotarization { class TestParseNotarization : public ::testing::Test, public Eval {}; @@ -52,6 +49,6 @@ TEST(TestParseNotarization, test__b) -// for l in `g 'parse notarisation' ~/.komodo/debug.log | pyline 'l.split()[8]'`; do hoek decodeTx '{"hex":"'`src/komodo-cli getrawtransaction "$l"`'"}' | jq '.outputs[1].script.op_return' | pyline 'import base64; print base64.b64decode(l).encode("hex")'; done +// for l in `g 'parse notarisation' ~/.hush/HUSH3/debug.log | pyline 'l.split()[8]'`; do hoek decodeTx '{"hex":"'`src/hush-cli getrawtransaction "$l"`'"}' | jq '.outputs[1].script.op_return' | pyline 'import base64; print base64.b64decode(l).encode("hex")'; done } diff --git a/src/zush b/src/zush index e6da90523..5aefa7a9e 100755 --- a/src/zush +++ b/src/zush @@ -10,12 +10,7 @@ cd $DIR NAME=ZUSH -CLI=${KOMODOCLI:-./komodo-cli} +CLI=${HUSHCLI:-./hush-cli} if [ -f $CLI ]; then $CLI -ac_name=$NAME "$@" -else - # We prefix our binary when installed - # system wide on Debain system, to prevent clashes - CLI=hush-komodo-cli - $CLI -ac_name=$NAME "$@" fi From b30fae823861f0f555bfb0eafff4b574dd7066c3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 11:13:08 -0400 Subject: [PATCH 065/115] clean up some more --- src/cc/CC_made_easy.md | 12 +++---- src/cc/customcc.cpp | 2 +- src/cc/customcc.h | 2 +- src/cc/rogue_rpc.cpp | 2 +- src/cc/sudoku.cpp | 2 +- src/hushd-testnet | 60 ---------------------------------- src/main.cpp | 6 ++-- src/rpc/misc.cpp | 4 +-- src/test-hush/test_addrman.cpp | 5 +-- src/txdb.cpp | 19 ++--------- 10 files changed, 18 insertions(+), 96 deletions(-) delete mode 100755 src/hushd-testnet diff --git a/src/cc/CC_made_easy.md b/src/cc/CC_made_easy.md index ada471a8e..354e99ab2 100644 --- a/src/cc/CC_made_easy.md +++ b/src/cc/CC_made_easy.md @@ -25,7 +25,7 @@ Since CC contracts run native C/C++ code, it is turing complete and that means t utxo based contracts are a bit harder to start writing than for balance based contracts. However, they are much more secure as they leverage the existing bitcoin utxo system. That makes it much harder to have bugs that issue a zillion new coins from a bug, since all the CC contract operations needs to also obey the existing bitcoin utxo protocol. -This document will be heavily example based so it will utilize many of the existing reference CC contracts. After understanding this document, you should be in a good position to start creating either a new CC contract to be integrated into komodod or to make rpc based dapps directly. +This document will be heavily example based so it will utilize many of the existing reference CC contracts. After understanding this document, you should be in a good position to start creating either a new CC contract to be integrated into hushd or to make rpc based dapps directly. Chapter 0 - Bitcoin Protocol Basics There are many aspects of the bitcoin protocol that isnt needed to understand the CC contracts dependence on it. Such details will not be discussed. The primary aspect is the utxo, unspent transaction output. Just a fancy name for txid/vout, so when you sendtoaddress some coins, it creates a txid and the first output is vout.0, combine it and txid/0 is a specific utxo. @@ -152,7 +152,7 @@ Ultimately the CC contract is all about how it constrains its inputs, but before Chapter 4 - CC rpc extensions Currently, CC contracts need to be integrated at the source level. This limits who is able to create and add new CC contracts, which at first is good, but eventually will be a too strict limitation. The runtime bindings chapter will touch on how to break out of the source based limitation, but there is another key interface level, the RPC. -By convention, each CC contract adds an associated set of rpc calls to the komodo-cli. This not only simplifies the creation of the CC contract transactions, it further will allow dapps to be created just via rpc calls. That will require there being enough foundational CC contracts already in place. As we find new usecases that cannot be implemented via rpc, then a new CC contract is made that can handle that (and more) and the power of the rpc level increases. This is a long term process. +By convention, each CC contract adds an associated set of rpc calls to the hush-cli. This not only simplifies the creation of the CC contract transactions, it further will allow dapps to be created just via rpc calls. That will require there being enough foundational CC contracts already in place. As we find new usecases that cannot be implemented via rpc, then a new CC contract is made that can handle that (and more) and the power of the rpc level increases. This is a long term process. The typical rpc calls that are added address, , return the various special CC addresses, the list of CC contract instances and info about each CC contract instance. Along with an rpc that creates a CC instance and of course the calls to invoke a CC instance. @@ -228,9 +228,9 @@ faucetfund calls FaucetFund faucetget calls FaucetGet faucetinfo calls FaucetInfo -Now you might not be a programmer, but I hope you are able to understand the above sequence. user types in a cli call, komodo-cli processes it by calling the rpc function, which in turn calls the function inside faucet.cpp +Now you might not be a programmer, but I hope you are able to understand the above sequence. user types in a cli call, hush-cli processes it by calling the rpc function, which in turn calls the function inside faucet.cpp -No magic, just simple conversion of a user command line call that runs code inside the komodod. Both the faucetfund and faucetget create properly signed rawtransaction that is ready to be broadcast to the network using the standard sendrawtransaction rpc. It doesnt automatically do this to allow the GUI to have a confirmation step with all the details before doing an irrevocable CC contract transaction. +No magic, just simple conversion of a user command line call that runs code inside the hushd. Both the faucetfund and faucetget create properly signed rawtransaction that is ready to be broadcast to the network using the standard sendrawtransaction rpc. It doesnt automatically do this to allow the GUI to have a confirmation step with all the details before doing an irrevocable CC contract transaction. faucetfund allows anybody to add funds to the faucet faucetget allows anybody to get 0.1 coins from the faucet as long as they dont violate the rules. @@ -239,7 +239,7 @@ And we come to what it is all about. The rules of the faucet. Initially it was m To make it much harder to leech, it was made so each faucetget returned only 0.1 coins (down from 1.0) so it was worth 90% less. It was also made so that it had to be to a fresh address with less than 3 transactions. Finally each txid was constrained to start and end with 00! This is a cool trick to force usage of precious CPU time (20 to 60 seconds depending on system) to generate a valid txid. Like PoW mining for the txid and I expect other CC contracts to use a similar mechanism if they want to rate limit usage. -Combined, it became such a pain to get 0.1 coins, the faucet leeching problem was solved. It might not seem like too much trouble to change an address to get another 0.1 coins, but the way things are setup you need to launch the komodod -pubkey= to change the pubkey that is active for a node. That means to change the pubkey being used, the komodod needs to be restarted and this creates a lot of issues for any automation trying to do this. Combined with the PoW required, only when 0.1 coins becomes worth a significant effort will faucet leeching return. In that case, the PoW requirement can be increased and coin amount decreased, likely with a faucet2 CC contract as I dont expect many such variations to be needed. +Combined, it became such a pain to get 0.1 coins, the faucet leeching problem was solved. It might not seem like too much trouble to change an address to get another 0.1 coins, but the way things are setup you need to launch the hushd -pubkey= to change the pubkey that is active for a node. That means to change the pubkey being used, the hushd needs to be restarted and this creates a lot of issues for any automation trying to do this. Combined with the PoW required, only when 0.1 coins becomes worth a significant effort will faucet leeching return. In that case, the PoW requirement can be increased and coin amount decreased, likely with a faucet2 CC contract as I dont expect many such variations to be needed. Chapter 7 - rewards example The next CC contract in complexity is the rewards CC contract. This is designed to capture what most people like about masternodes, without anything else, ie. the rewards! @@ -653,7 +653,7 @@ Our testing cycle went a lot faster than expected as the bugs found were few and Yes, blockchains are complicated. Chapter 13 - different languages -The current codebase is integrated into the komodod codebase, which is C/C++. However, it is possible to use different languages and integrate into the C/C++ as zcash has shown by using the rust language for some parts of the zcashd. +The current codebase is integrated into the hushd codebase, which is C/C++. However, it is possible to use different languages and integrate into the C/C++ as zcash has shown by using the rust language for some parts of the zcashd. I think any language that is compiled and can create a linkable library while being able to call and be called by C/C++ functions can be used. If you are able to make such a language binding for a simple CC contract like faucet, this will be good for a 777 KMD bounty. Of course, you need to be the first to submit a properly working pull request. diff --git a/src/cc/customcc.cpp b/src/cc/customcc.cpp index 343195dfe..c1b1c9028 100644 --- a/src/cc/customcc.cpp +++ b/src/cc/customcc.cpp @@ -10,7 +10,7 @@ ./makecustom ../hush-smart-chain -ac_name=CUSTOM -ac_cclib=custom -ac_cc=2 ... - The above will rebuild komodod and get it running again + The above will rebuild hushd and get it running again */ CScript custom_opret(uint8_t funcid,CPubKey pk) diff --git a/src/cc/customcc.h b/src/cc/customcc.h index c3614d2af..c88f6333d 100644 --- a/src/cc/customcc.h +++ b/src/cc/customcc.h @@ -10,7 +10,7 @@ 3. write the actual custom_func0, custom_func1 and custom_validate in customcc.cpp - 4. ./makecustom, which builds cclib.cpp with -DBUILD_CUSTOMCC and puts the libcc.so in ~/komodo/src and rebuilds komodod + 4. ./makecustom, which builds cclib.cpp with -DBUILD_CUSTOMCC and puts the libcc.so in ~/hush3/src and rebuilds hushd 5. launch your chain with -ac_cclib=customcc -ac_cc=2 diff --git a/src/cc/rogue_rpc.cpp b/src/cc/rogue_rpc.cpp index 83b2f8097..b1fd8635d 100644 --- a/src/cc/rogue_rpc.cpp +++ b/src/cc/rogue_rpc.cpp @@ -129,7 +129,7 @@ std::string Rogue_pname = ""; // keystrokes retry //////////////////////// start of CClib interface -//./komodod -ac_name=ROGUE -ac_supply=1000000 -pubkey=03951a6f7967ad784453116bc55cd30c54f91ea8a5b1e9b04d6b29cfd6b395ba6c -addnode=5.9.102.210 -ac_cclib=rogue -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60001 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc > /dev/null & +//./hushd -ac_name=ROGUE -ac_supply=1000000 -pubkey=03951a6f7967ad784453116bc55cd30c54f91ea8a5b1e9b04d6b29cfd6b395ba6c -addnode=5.9.102.210 -ac_cclib=rogue -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60001 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc > /dev/null & // cclib newgame 17 \"[3,10]\" // cclib pending 17 diff --git a/src/cc/sudoku.cpp b/src/cc/sudoku.cpp index 6edd868b2..4feda6701 100644 --- a/src/cc/sudoku.cpp +++ b/src/cc/sudoku.cpp @@ -2480,7 +2480,7 @@ void sudoku_gen(uint8_t key32[32],uint8_t unsolved[9][9],uint32_t srandi) } //////////////////////// start of CClib interface -// ./komodod -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & +// ./hushd -ac_name=SUDOKU -ac_supply=1000000 -pubkey= -addnode=5.9.102.210 -gen -genproclimit=1 -ac_cclib=sudoku -ac_perc=10000000 -ac_reward=100000000 -ac_cc=60000 -ac_script=2ea22c80203d1579313abe7d8ea85f48c65ea66fc512c878c0d0e6f6d54036669de940febf8103120c008203000401cc & /* cclib "gen" 17 \"10\" 5d13c1ad80daf37215c74809a36720c2ada90bacadb2e10bf0866092ce558432 */ diff --git a/src/hushd-testnet b/src/hushd-testnet deleted file mode 100755 index 3e36b81f7..000000000 --- a/src/hushd-testnet +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# Copyright (c) 2016-2021 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 - -# set working directory to the location of this script -DIR="$( cd "$( dirname "$( readlink -f "${BASH_SOURCE[0]}" )" )" && pwd )" -cd $DIR -DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" -cd $DIR - -# TESTING VALUES, DO NOT USE EXCEPT FOR DEVELOPMENT -NAME=HUSH3T -# this corresponds to FR address RHushEyeDm7XwtaTWtyCbjGQumYyV8vMjn -SCRIPT=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac - -# Hush was and will always be: -# The First Pure Sapling Zcash Protocol chain! -SAPLING=1 - -# Chain parameters -ERAS=3 -BLOCKTIME=150 -# 6250000 - (sprout pool at block 500,000) -SUPPLY=6178674 -FOUNDERS=1 -REWARD=0,1125000000,562500000 -PERC=11111111 -HALVING=129,340000,840000 -END=128,340000,5422111 -CLIENTNAME=GoldenSandtrout -SEEDNODE=1.2.3.4 -CCLIB=hush3 - -# CryptoConditions/Custom Consensus params -FAUCET=228 -HEIR=234 -CHANNEL=235 -ORACLE=236 -GATEWAY=241 -CCENABLE=$FAUCET,$HEIR,$CHANNEL,$ORACLE,$GATEWAY - -# jl777 dishonored his village and so Duke The Elder journeys on -# with the True Extreme Privacy Cypherpunks -KMD=${KOMODOD:-./komodod} -$KMD -ac_name=$NAME \ - -ac_sapling=$SAPLING \ - -ac_reward=$REWARD \ - -ac_halving=$HALVING \ - -ac_end=$END \ - -ac_eras=$ERAS \ - -ac_blocktime=$BLOCKTIME \ - -ac_cc=2 \ - -ac_ccenable=$CCENABLE \ - -ac_founders=$FOUNDERS \ - -ac_supply=$SUPPLY \ - -ac_perc=$PERC \ - -clientname=$CLIENTNAME \ - -ac_cclib=$CCLIB \ - -ac_script=$SCRIPT "$@" diff --git a/src/main.cpp b/src/main.cpp index fe08fe6b4..42dd82efd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -727,7 +727,7 @@ CBlockTreeDB *pblocktree = NULL; #define HUSH_ZCASH #include "hush.h" -UniValue komodo_snapshot(int top) +UniValue hush_snapshot(int top) { LOCK(cs_main); int64_t total = -1; @@ -745,7 +745,7 @@ UniValue komodo_snapshot(int top) return(result); } -bool komodo_snapshot2(std::map &addressAmounts) +bool hush_snapshot2(std::map &addressAmounts) { if ( fAddressIndex && pblocktree != 0 ) { @@ -787,7 +787,7 @@ bool hush_dailysnapshot(int32_t height) if ( undo_height == lastSnapShotHeight ) return true; std::map addressAmounts; - if ( !komodo_snapshot2(addressAmounts) ) + if ( !hush_snapshot2(addressAmounts) ) return false; // undo blocks in reverse order diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0d48071b7..91b012b13 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1287,7 +1287,7 @@ UniValue getaddressbalance(const UniValue& params, bool fHelp, const CPubKey& my } -UniValue komodo_snapshot(int top); +UniValue hush_snapshot(int top); UniValue getsnapshot(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -1337,7 +1337,7 @@ UniValue getsnapshot(const UniValue& params, bool fHelp, const CPubKey& mypk) + HelpExampleRpc("getsnapshot", "1000") ); } - result = komodo_snapshot(top); + result = hush_snapshot(top); if ( result.size() > 0 ) { result.push_back(Pair("end_time", (int) time(NULL))); } else { diff --git a/src/test-hush/test_addrman.cpp b/src/test-hush/test_addrman.cpp index afded7393..29d5fc319 100644 --- a/src/test-hush/test_addrman.cpp +++ b/src/test-hush/test_addrman.cpp @@ -2,16 +2,13 @@ // Distributed under the GPLv3 software license, see the accompanying // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #include - #include "addrman.h" #include #include #include - #include "hash.h" #include "random.h" #include "util/asmap.h" - #include "netbase.h" #include "chainparams.h" #include "tinyformat.h" @@ -51,7 +48,7 @@ class TestCout : public std::stringstream using namespace std; -/* xxd -i est-komodo/data/asmap.raw | sed 's/unsigned char/static unsigned const char/g' */ +/* xxd -i test-hush/data/asmap.raw | sed 's/unsigned char/static unsigned const char/g' */ static unsigned const char asmap_raw[] = { 0xfb, 0x03, 0xec, 0x0f, 0xb0, 0x3f, 0xc0, 0xfe, 0x00, 0xfb, 0x03, 0xec, 0x0f, 0xb0, 0x3f, 0xc0, 0xfe, 0x00, 0xfb, 0x03, 0xec, 0x0f, 0xb0, 0xff, diff --git a/src/txdb.cpp b/src/txdb.cpp index e6b82332a..74901bdf4 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -429,23 +429,8 @@ bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &addr uint32_t hush_segid32(char *coinaddr); #define DECLARE_IGNORELIST std::map ignoredMap = { \ - {"RReUxSs5hGE39ELU23DfydX8riUuzdrHAE", 1}, \ - {"RMUF3UDmzWFLSKV82iFbMaqzJpUnrWjcT4", 1}, \ - {"RA5imhVyJa7yHhggmBytWuDr923j2P1bxx", 1}, \ - {"RBM5LofZFodMeewUzoMWcxedm3L3hYRaWg", 1}, \ - {"RAdcko2d94TQUcJhtFHZZjMyWBKEVfgn4J", 1}, \ - {"RLzUaZ934k2EFCsAiVjrJqM8uU1vmMRFzk", 1}, \ - {"RMSZMWZXv4FhUgWhEo4R3AQXmRDJ6rsGyt", 1}, \ - {"RUDrX1v5toCsJMUgtvBmScKjwCB5NaR8py", 1}, \ - {"RMSZMWZXv4FhUgWhEo4R3AQXmRDJ6rsGyt", 1}, \ - {"RRvwmbkxR5YRzPGL5kMFHMe1AH33MeD8rN", 1}, \ - {"RQLQvSgpPAJNPgnpc8MrYsbBhep95nCS8L", 1}, \ - {"RK8JtBV78HdvEPvtV5ckeMPSTojZPzHUTe", 1}, \ - {"RHVs2KaCTGUMNv3cyWiG1jkEvZjigbCnD2", 1}, \ - {"RE3SVaDgdjkRPYA6TRobbthsfCmxQedVgF", 1}, \ - {"RW6S5Lw5ZCCvDyq4QV9vVy7jDHfnynr5mn", 1}, \ - {"RTkJwAYtdXXhVsS3JXBAJPnKaBfMDEswF8", 1}, \ - {"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} \ + {"RUeUxSs5hGE39ELU23DfydX8riUuzdrHAE", 1}, \ + {"R2d2gnrMpPaTSMn8vai6yiGA7mN4QGPVMY", 1} \ }; bool CBlockTreeDB::Snapshot2(std::map &addressAmounts, UniValue *ret) From fde2dd7c8f14c7c8c5d97052d668d813084a3602 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 11:14:51 -0400 Subject: [PATCH 066/115] update test include --- src/Makefile.gtest.include | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index e3468a6f8..457ef6bdf 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -1,10 +1,10 @@ # Copyright (c) 2016-2021 The Hush developers # Released under the GPLv3 -TESTS += komodo-gtest -bin_PROGRAMS += komodo-gtest +TESTS += hush-gtest +bin_PROGRAMS += hush-gtest # tool for generating our public parameters -komodo_gtest_SOURCES = \ +hush_gtest_SOURCES = \ gtest/main.cpp \ gtest/utils.cpp \ gtest/test_checktransaction.cpp \ @@ -22,7 +22,6 @@ zcash_gtest_SOURCES += \ gtest/test_deprecation.cpp \ gtest/test_equihash.cpp \ gtest/test_httprpc.cpp \ - gtest/test_joinsplit.cpp \ gtest/test_keys.cpp \ gtest/test_keystore.cpp \ gtest/test_noteencryption.cpp \ @@ -51,23 +50,23 @@ zcash_gtest_SOURCES += \ wallet/gtest/test_wallet.cpp endif -komodo_gtest_CPPFLAGS = $(AM_CPPFLAGS) -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC $(BITCOIN_INCLUDES) -komodo_gtest_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +hush_gtest_CPPFLAGS = $(AM_CPPFLAGS) -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC $(BITCOIN_INCLUDES) +hush_gtest_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -komodo_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ +hush_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) if ENABLE_ZMQ zcash_gtest_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif if ENABLE_WALLET -komodo_gtest_LDADD += $(LIBBITCOIN_WALLET) +hush_gtest_LDADD += $(LIBBITCOIN_WALLET) endif -komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) +hush_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) -komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static +hush_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static -komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static +hush_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static -komodo-gtest-expected-failures: komodo-gtest FORCE - ./komodo-gtest --gtest_filter=*DISABLED_* --gtest_also_run_disabled_tests +hush-gtest-expected-failures: hush-gtest FORCE + ./hush-gtest --gtest_filter=*DISABLED_* --gtest_also_run_disabled_tests From 3641ca27f4b7abb77662e909c5fb89bd3ad371fb Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 11:16:18 -0400 Subject: [PATCH 067/115] update purge script --- src/purge | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/purge b/src/purge index 1480c40a8..df6624596 100755 --- a/src/purge +++ b/src/purge @@ -4,7 +4,7 @@ echo "Purging $1" -rm -rf ~/.komodo/$1/chainstate -rm -rf ~/.komodo/$1/database -rm -rf ~/.komodo/$1/blocks -rm -rf ~/.komodo/$1/komodostate +rm -rf ~/.hush/$1/chainstate +rm -rf ~/.hush/$1/database +rm -rf ~/.hush/$1/blocks +rm -rf ~/.hush/$1/hushstate From 5c2293336a250c52be407064166088c0d352af42 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 11:16:46 -0400 Subject: [PATCH 068/115] remove clearassets script --- src/clearassets | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100755 src/clearassets diff --git a/src/clearassets b/src/clearassets deleted file mode 100755 index 6c37fb95d..000000000 --- a/src/clearassets +++ /dev/null @@ -1,32 +0,0 @@ -rm -rf ~/.komodo/USD -rm -rf ~/.komodo/EUR -rm -rf ~/.komodo/JPY -rm -rf ~/.komodo/GBP -rm -rf ~/.komodo/AUD -rm -rf ~/.komodo/CAD -rm -rf ~/.komodo/CHF -rm -rf ~/.komodo/NZD -rm -rf ~/.komodo/CNY -rm -rf ~/.komodo/RUB -rm -rf ~/.komodo/MXN -rm -rf ~/.komodo/BRL -rm -rf ~/.komodo/INR -rm -rf ~/.komodo/HKD -rm -rf ~/.komodo/TRY -rm -rf ~/.komodo/ZAR -rm -rf ~/.komodo/PLN -rm -rf ~/.komodo/NOK -rm -rf ~/.komodo/SEK -rm -rf ~/.komodo/DKK -rm -rf ~/.komodo/CZK -rm -rf ~/.komodo/HUF -rm -rf ~/.komodo/ILS -rm -rf ~/.komodo/KRW -rm -rf ~/.komodo/MYR -rm -rf ~/.komodo/PHP -rm -rf ~/.komodo/RON -rm -rf ~/.komodo/SGD -rm -rf ~/.komodo/THB -rm -rf ~/.komodo/BGN -rm -rf ~/.komodo/IDR -rm -rf ~/.komodo/HRK From b713f43487e2171b700dfa85ccd1428d33c3a712 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 14:46:53 -0400 Subject: [PATCH 069/115] Clean up dead code and cruft --- src/crypto/equihash.h | 2 +- src/hush.h | 76 +++++++++++----------------------------- src/hush_bitcoind.h | 7 ++-- src/hush_ccdata.h | 2 +- src/hush_events.h | 2 +- src/hush_gateway.h | 2 +- src/hush_pax.h | 2 +- src/hush_utils.h | 2 +- src/wallet/rpcwallet.cpp | 8 ++--- 9 files changed, 35 insertions(+), 68 deletions(-) diff --git a/src/crypto/equihash.h b/src/crypto/equihash.h index 3b977dffc..968fbdd79 100644 --- a/src/crypto/equihash.h +++ b/src/crypto/equihash.h @@ -204,7 +204,7 @@ public: #include "equihash.tcc" /* -* Equihash 200,9 (KMD/Zcash) +* Equihash 200,9 (HUSH/ZEC and other ASIC coins) * Equihash 150,5 (beam) * Equihash 144,5 (SnowGem) * Equihash 96,5 (Minex) diff --git a/src/hush.h b/src/hush.h index cb8a60a6c..c09d2eea6 100644 --- a/src/hush.h +++ b/src/hush.h @@ -82,9 +82,7 @@ int32_t hush_parsestatefile(struct hush_state *sp,FILE *fp,char *symbol,char *de int32_t func,ht,notarized_height,num,matched=0,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; if ( (func= fgetc(fp)) != EOF ) { - if ( SMART_CHAIN_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) - matched = 1; - else matched = (strcmp(symbol,SMART_CHAIN_SYMBOL) == 0); + matched = (strcmp(symbol,SMART_CHAIN_SYMBOL) == 0); if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) errs++; if ( 0 && SMART_CHAIN_SYMBOL[0] != 0 && func != 'T' ) @@ -98,7 +96,7 @@ int32_t hush_parsestatefile(struct hush_state *sp,FILE *fp,char *symbol,char *de else { //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); - if ( (HUSH_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && HUSH_EXTERNAL_NOTARIES == 0) ) + if ( (HUSH_EXTERNAL_NOTARIES != 0 && matched != 0) ) hush_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); } } else printf("illegal num.%d\n",num); @@ -228,10 +226,9 @@ int32_t hush_parsestatefiledata(struct hush_state *sp,uint8_t *filedata,long *fp int32_t func= -1,ht,notarized_height,MoMdepth,num,matched=0; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; long fpos = *fposp; if ( fpos < datalen ) { - func = filedata[fpos++]; - if ( SMART_CHAIN_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) - matched = 1; - else matched = (strcmp(symbol,SMART_CHAIN_SYMBOL) == 0); + func = filedata[fpos++]; + matched = (strcmp(symbol,SMART_CHAIN_SYMBOL) == 0); + if ( memread(&ht,sizeof(ht),filedata,&fpos,datalen) != sizeof(ht) ) errs++; if ( func == 'P' ) @@ -243,7 +240,7 @@ int32_t hush_parsestatefiledata(struct hush_state *sp,uint8_t *filedata,long *fp else { //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); - if ( (HUSH_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && HUSH_EXTERNAL_NOTARIES == 0) ) + if ( (HUSH_EXTERNAL_NOTARIES != 0 && matched != 0) ) hush_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); } } else printf("illegal num.%d\n",num); @@ -353,7 +350,7 @@ int32_t hush_parsestatefiledata(struct hush_state *sp,uint8_t *filedata,long *fp return(-1); } -void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) +void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t HUSHheight,uint32_t HUSHtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { static FILE *fp; static int32_t errs,didinit; static uint256 zero; struct hush_state *sp; char fname[512],symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; int32_t retval,ht,func; uint8_t num,pubkeys[64][33]; @@ -394,30 +391,26 @@ void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotarie if ( fp != 0 ) // write out funcid, height, other fields, call side effect function { //printf("fpos.%ld ",ftell(fp)); - if ( KMDheight != 0 ) + if ( HUSHheight != 0 ) { - if ( KMDtimestamp != 0 ) + if ( HUSHtimestamp != 0 ) { fputc('T',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) errs++; - if ( fwrite(&KMDheight,1,sizeof(KMDheight),fp) != sizeof(KMDheight) ) + if ( fwrite(&HUSHheight,1,sizeof(HUSHheight),fp) != sizeof(HUSHheight) ) errs++; - if ( fwrite(&KMDtimestamp,1,sizeof(KMDtimestamp),fp) != sizeof(KMDtimestamp) ) + if ( fwrite(&HUSHtimestamp,1,sizeof(HUSHtimestamp),fp) != sizeof(HUSHtimestamp) ) errs++; - } - else - { + } else { fputc('K',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) errs++; - if ( fwrite(&KMDheight,1,sizeof(KMDheight),fp) != sizeof(KMDheight) ) + if ( fwrite(&HUSHheight,1,sizeof(HUSHheight),fp) != sizeof(HUSHheight) ) errs++; } - hush_eventadd_kmdheight(sp,symbol,height,KMDheight,KMDtimestamp); - } - else if ( opretbuf != 0 && opretlen > 0 ) - { + hush_eventadd_kmdheight(sp,symbol,height,HUSHheight,HUSHtimestamp); + } else if ( opretbuf != 0 && opretlen > 0 ) { uint16_t olen = opretlen; fputc('R',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) @@ -432,8 +425,7 @@ void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotarie errs++; if ( fwrite(opretbuf,1,olen,fp) != olen ) errs++; -//printf("create ht.%d R opret[%d] sp.%p\n",height,olen,sp); - //komodo_opreturn(height,opretvalue,opretbuf,olen,txhash,vout); + //printf("create ht.%d R opret[%d] sp.%p\n",height,olen,sp); hush_eventadd_opreturn(sp,symbol,height,txhash,opretvalue,vout,opretbuf,olen); } else if ( notarypubs != 0 && numnotaries > 0 ) @@ -687,7 +679,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi } else { - komodo_rwccdata(SMART_CHAIN_SYMBOL,1,&ccdata,&MoMoMdata); + hush_rwccdata(SMART_CHAIN_SYMBOL,1,&ccdata,&MoMoMdata); if ( matched != 0 ) printf("[%s] matched.%d VALID (%s) MoM.%s [%d] CCid.%u\n",SMART_CHAIN_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth&0xffff,(MoMdepth>>16)&0xffff); } @@ -696,8 +688,6 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi memset(&ccdata,0,sizeof(ccdata)); memset(&MoMoMdata,0,sizeof(MoMoMdata)); } - else if ( SMART_CHAIN_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 ) - komodo_rwccdata((char *)"KMD",1,&ccdata,0); if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height ) { @@ -711,36 +701,12 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi } hush_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); //if ( SMART_CHAIN_SYMBOL[0] != 0 ) - printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",SMART_CHAIN_SYMBOL,height,sp->NOTARIZED_HEIGHT,SMART_CHAIN_SYMBOL[0]==0?"KMD":SMART_CHAIN_SYMBOL,srchash.ToString().c_str(),SMART_CHAIN_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); + printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",SMART_CHAIN_SYMBOL,height,sp->NOTARIZED_HEIGHT,SMART_CHAIN_SYMBOL,srchash.ToString().c_str(),"HUSH",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); - if ( SMART_CHAIN_SYMBOL[0] == 0 ) - { - if ( signedfp == 0 ) - { - char fname[512]; - hush_statefname(fname,SMART_CHAIN_SYMBOL,(char *)"hushsignedmasks"); - if ( (signedfp= fopen(fname,"rb+")) == 0 ) - signedfp = fopen(fname,"wb"); - else fseek(signedfp,0,SEEK_END); - } - if ( signedfp != 0 ) - { - fwrite(&height,1,sizeof(height),signedfp); - fwrite(&signedmask,1,sizeof(signedmask),signedfp); - fflush(signedfp); - } - if ( opretlen > len && scriptbuf[len] == 'A' ) - { - //for (i=0; i 600000 && matched != 0 ) - printf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n",ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,SMART_CHAIN_SYMBOL[0]==0?"KMD":SMART_CHAIN_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen); + printf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n",ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,SMART_CHAIN_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen); } else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) { @@ -752,7 +718,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi //int32_t k; for (k=0; k= 32*2+4 && strcmp(SMART_CHAIN_SYMBOL[0]==0?"KMD":SMART_CHAIN_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) + if ( opretlen >= 32*2+4 && strcmp(SMART_CHAIN_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) { for (k=0; k<32; k++) if ( scriptbuf[len+k] != 0 ) @@ -985,7 +951,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) } } if ( !fJustCheck && IS_HUSH_NOTARY != 0 && SMART_CHAIN_SYMBOL[0] == 0 ) - printf("%s ht.%d\n",SMART_CHAIN_SYMBOL[0] == 0 ? "KMD" : SMART_CHAIN_SYMBOL,height); + printf("%s ht.%d\n",SMART_CHAIN_SYMBOL,height); if ( !fJustCheck && pindex->GetHeight() == hwmheight ) hush_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); } diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 4fa823997..69ace9a3a 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -15,7 +15,7 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ -// Hush functions that interact with bitcoind C++ +// Hush functions that interact with hushd C++ #include #include #include "consensus/params.h" @@ -408,6 +408,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_hei if ( (item= jobj(json,(char *)"result")) != 0 ) { height = jint(item,(char *)"blocks"); + //TODO: which key to use? *hushnotarized_heightp = strcmp(dest,"KMD") == 0 ? jint(item,(char *)"notarized") : height; } free_json(json); @@ -570,7 +571,7 @@ CScript hush_makeopret(CBlock *pblock, bool fNew) } free_json(result); } - printf("KMD hash.%d (%s) %x\n",height,jsonstr,*(uint32_t *)&hash); + printf("HUSH3 hash.%d (%s) %x\n",height,jsonstr,*(uint32_t *)&hash); free(jsonstr); } return(hash); @@ -1032,7 +1033,7 @@ int32_t hush_nextheight() int32_t komodo_isrealtime(int32_t *kmdheightp) { struct hush_state *sp; CBlockIndex *pindex; - if ( (sp= hush_stateptrget((char *)"KMD")) != 0 ) + if ( (sp= hush_stateptrget((char *)"HUSH3")) != 0 ) *kmdheightp = sp->CURRENT_HEIGHT; else *kmdheightp = 0; if ( (pindex= chainActive.LastTip()) != 0 && pindex->GetHeight() >= (int32_t)hush_longestchain() ) diff --git a/src/hush_ccdata.h b/src/hush_ccdata.h index c45cd3c62..edfb70c2c 100644 --- a/src/hush_ccdata.h +++ b/src/hush_ccdata.h @@ -203,7 +203,7 @@ void komodo_purge_ccdata(int32_t height) } // this is just a demo of ccdata processing to create example data for the MoMoM and allMoMs calls -int32_t komodo_rwccdata(char *thischain,int32_t rwflag,struct hush_ccdata *ccdata,struct hush_ccdataMoMoM *MoMoMdata) +int32_t hush_rwccdata(char *thischain,int32_t rwflag,struct hush_ccdata *ccdata,struct hush_ccdataMoMoM *MoMoMdata) { uint256 hash,zero; bits256 tmp; int32_t i,nonz; struct hush_ccdata *ptr; struct notarized_checkpoint *np; return(0); // disable this path as libscott method is much better diff --git a/src/hush_events.h b/src/hush_events.h index 18553e143..ab92521ec 100644 --- a/src/hush_events.h +++ b/src/hush_events.h @@ -69,7 +69,7 @@ void hush_eventadd_notarized(struct hush_state *sp,char *symbol,int32_t height,c void hush_eventadd_pubkeys(struct hush_state *sp,char *symbol,int32_t height,uint8_t num,uint8_t pubkeys[64][33]) { struct hush_event_pubkeys P; - //printf("eventadd pubkeys ht.%d\n",height); + fprintf(stderr, "%s: eventadd pubkeys height=%d\n",__func__,height); memset(&P,0,sizeof(P)); P.num = num; memcpy(P.pubkeys,pubkeys,33 * num); diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 8b28c9b8c..7eb0bd8b3 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -610,7 +610,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to for (i=0; ivout.resize(numvouts+1); txNew->vout[numvouts].nValue = 0; txNew->vout[numvouts].scriptPubKey.resize(opretlen); diff --git a/src/hush_pax.h b/src/hush_pax.h index 3ccbc2d74..d953bdcc2 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -267,7 +267,7 @@ int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize) } if ( timestamp > time(NULL)-600 ) { - n = komodo_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); + n = hush_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); if ( 0 && lastcrc != crc32 ) { for (i=0; i Date: Wed, 1 Sep 2021 14:53:12 -0400 Subject: [PATCH 070/115] All coins are HSCs with their own subdir --- src/hush_globals.h | 2 +- src/hush_utils.h | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/hush_globals.h b/src/hush_globals.h index 295f848b1..5e88aa19f 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -109,7 +109,7 @@ pthread_mutex_t HUSH_KV_mutex,HUSH_CC_mutex; #define MAX_CURRENCIES 32 char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", - "KMD" }; + "HUSH" }; int32_t hush_baseid(char *origbase) { diff --git a/src/hush_utils.h b/src/hush_utils.h index 9e6de541e..6e3edfc0e 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1343,16 +1343,14 @@ void hush_statefname(char *fname,char *symbol,char *str) printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,SMART_CHAIN_SYMBOL,n,len,&fname[len - n]); return; } - } - else - { + } else { #ifdef _WIN32 strcat(fname,"\\"); #else strcat(fname,"/"); #endif } - if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 ) + if ( symbol != 0 && symbol[0] != 0) { strcat(fname,symbol); //printf("statefname.(%s) -> (%s)\n",symbol,fname); @@ -1515,7 +1513,6 @@ int32_t hush_whoami(char *pubkeystr,int32_t height,uint32_t timestamp) return(notaryid); } -// TODO: clean up this smoking bath-salts shite from KMD char *argv0suffix[] = { (char *)"fuckjl777d", (char *)"fuckjl777-cli", (char *)"fuckjl777d.exe", (char *)"fuckjl777-cli.exe", (char *)"btchd", (char *)"btch-cli", (char *)"btchd.exe", (char *)"btch-cli.exe" }; From 0c6e5945a654ecf516f09bc4057543493cf26dc9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 20:26:59 -0400 Subject: [PATCH 071/115] Add listaddresses as a new replacement for getaddressesbyaccount; cleanup --- src/cc/CC_made_easy.md | 6 +++--- src/cc/betprotocol.h | 2 +- src/cc/dapps/dappinc.h | 2 +- src/cc/dapps/zmigrate.c | 12 +++++------ src/cc/eval.h | 2 +- src/cc/gateways.cpp | 46 ++++++++++++++++++++-------------------- src/cc/importgateway.cpp | 22 +++++++++---------- src/cc/importpayout.cpp | 2 +- src/cc/makerogue | 6 ++++-- src/cc/pegs.cpp | 26 +++++++++++------------ src/hush_events.h | 4 ++-- src/hush_structs.h | 2 +- src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 36 +++++++++++++++++++++++++++++-- src/wallet/walletdb.cpp | 2 +- 15 files changed, 102 insertions(+), 69 deletions(-) diff --git a/src/cc/CC_made_easy.md b/src/cc/CC_made_easy.md index 354e99ab2..daf7cbedd 100644 --- a/src/cc/CC_made_easy.md +++ b/src/cc/CC_made_easy.md @@ -14,12 +14,12 @@ * * ******************************************************************************/ -How to write utxo based CryptoConditions contracts for KMD chains +How to write utxo based CryptoConditions contracts for HUSH chains by jl777 This is not the only smart contracts methodology that is possible to build on top of OP_CHECKCRYPTOCONDITION, just the first one. All the credit for getting OP_CHECKCRYPTOCONDITION working in the Komodo codebase goes to @libscott. I am just hooking into the code that he made and tried to make it just a little easier to make new contracts. -There is probably some fancy marketing name to use, but for now, I will just call it "CC contract" for short, knowing that it is not 100% technically accurate as the CryptoConditions aspect is not really the main attribute. However, the KMD contracts were built to make the CryptoConditions codebase that was integrated into it to be more accessible. +There is probably some fancy marketing name to use, but for now, I will just call it "CC contract" for short, knowing that it is not 100% technically accurate as the CryptoConditions aspect is not really the main attribute. However, the HUSH contracts were built to make the CryptoConditions codebase that was integrated into it to be more accessible. Since CC contracts run native C/C++ code, it is turing complete and that means that any contract that is possible to do on any other platform will be possible to create via CC contract. @@ -655,7 +655,7 @@ Yes, blockchains are complicated. Chapter 13 - different languages The current codebase is integrated into the hushd codebase, which is C/C++. However, it is possible to use different languages and integrate into the C/C++ as zcash has shown by using the rust language for some parts of the zcashd. -I think any language that is compiled and can create a linkable library while being able to call and be called by C/C++ functions can be used. If you are able to make such a language binding for a simple CC contract like faucet, this will be good for a 777 KMD bounty. Of course, you need to be the first to submit a properly working pull request. +I think any language that is compiled and can create a linkable library while being able to call and be called by C/C++ functions can be used. If you are able to make such a language binding for a simple CC contract like faucet, this will be good for a 777 HUSH bounty. Of course, you need to be the first to submit a properly working pull request. Chapter 14 - runtime bindings diff --git a/src/cc/betprotocol.h b/src/cc/betprotocol.h index 02c0000f2..6694cb331 100644 --- a/src/cc/betprotocol.h +++ b/src/cc/betprotocol.h @@ -62,7 +62,7 @@ public: CMutableTransaction MakePostEvidenceTx(uint256 signedSessionTxHash, int playerIndex, std::vector state); - // on KMD + // on HUSH CC* MakePayoutCond(uint256 signedSessionTxHash); CMutableTransaction MakeStakeTx(CAmount totalPayout, uint256 signedSessionTx); CMutableTransaction MakeAgreePayoutTx(std::vector payouts, uint256 signedStakeTxHash); diff --git a/src/cc/dapps/dappinc.h b/src/cc/dapps/dappinc.h index 29c15f111..c89658e72 100644 --- a/src/cc/dapps/dappinc.h +++ b/src/cc/dapps/dappinc.h @@ -639,7 +639,7 @@ cJSON *get_rawmempool(char *refcoin,char *acname) cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) { cJSON *retjson; char *retstr,jsonbuf[256]; - if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) + if ( refcoin[0] != 0 && strcmp(refcoin,"HUSH3") != 0 ) printf("warning: assumes %s has addressindex enabled\n",refcoin); sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr); if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","","","","")) != 0 ) diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index bc5f8e869..0e9d08112 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -23,6 +23,8 @@ #include "cJSON.c" /* +NOTE: HUSH nor any Hush Smart Chain has any sprout outputs. This code is kept for historical and educational purposes. + z_migrate: the purpose of z_migrate is to make converting of all sprout outputs into sapling. the usage would be for the user to specify a sapling address and call z_migrate zsaddr, until it returns that there is nothing left to be done. its main functionality is quite similar to a z_mergetoaddress ANY_ZADDR -> onetime_taddr followed by a z_sendmany onetime_taddr -> zsaddr @@ -318,8 +320,6 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char { long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[256]; sprintf(fname,"/tmp/zmigrate.%s",method); - //if ( (acname == 0 || acname[0] == 0) && strcmp(refcoin,"KMD") != 0 ) - // acname = refcoin; if ( acname[0] != 0 ) { if ( refcoin[0] != 0 && strcmp(refcoin,"HUSH3") != 0 ) @@ -490,7 +490,7 @@ cJSON *get_rawmempool(char *refcoin,char *acname) cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) { cJSON *retjson; char *retstr,jsonbuf[256]; - if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) + if ( refcoin[0] != 0 && strcmp(refcoin,"HUSH3") != 0 ) printf("warning: assumes %s has addressindex enabled\n",refcoin); sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr); if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 ) @@ -1294,7 +1294,7 @@ void reconcile_claims(char *refcoin,char *fname) else fields[n][i++] = *str++; } printf("%s\n",fields[1]); - total += update_claimstats(fields[1],fields[3],fields[5 + (strcmp("KMD",refcoin)==0)],atof(fields[4])*SATOSHIDEN + 0.0000000049); + total += update_claimstats(fields[1],fields[3],fields[5 + (strcmp("HUSH3",refcoin)==0)],atof(fields[4])*SATOSHIDEN + 0.0000000049); numlines++; } fclose(fp); @@ -1358,12 +1358,12 @@ int32_t main(int32_t argc,char **argv) } continue; } - if ( strcmp(coinstr,"KMD") == 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9JCEd6xnCxNUSpLrHEWvzPSh7CNXm7z75") < 0 ) + if ( strcmp(coinstr,"HUSH3") == 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9JCEd6xnCxNUSpLrHEWvzPSh7CNXm7z75") < 0 ) { printf("WARNING: imposter dust detected! %s\n",bits256_str(str,jbits256(item,"txid"))); continue; } - else if ( strcmp(coinstr,"KMD") != 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9MUnxXijovvSeT9sFuUX23TiFtVvZEGjT") < 0 ) + else if ( strcmp(coinstr,"HUSH3") != 0 && verify_vin(coinstr,jbits256(item,"txid"),0,"R9MUnxXijovvSeT9sFuUX23TiFtVvZEGjT") < 0 ) { printf("WARNING: imposter dust detected! %s\n",bits256_str(str,jbits256(item,"txid"))); continue; diff --git a/src/cc/eval.h b/src/cc/eval.h index b1049e7cd..d4581e8ef 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -224,7 +224,7 @@ public: if (SMART_CHAIN_SYMBOL[0]) return 1; if (s.size() >= 72) { if (strcmp("BTC", &s[68]) == 0) return 1; - if (strcmp("KMD", &s[68]) == 0) return 1; + if (strcmp("HUSH3", &s[68]) == 0) return 1; } return 0; } diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index d62760820..c8036e5f2 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -33,8 +33,8 @@ the potential pubkeys to be used would be based on active oracle data providers with recent activity. - bind asset <-> KMD gateway deposit address - KMD deposit -> globally spendable marker utxo + bind asset <-> HUSH gateway deposit address + HUSH deposit -> globally spendable marker utxo spend marker utxo and spend linked/locked asset to user's CC address redeem -> asset to global CC address with withdraw address -> gateway spendable marker utxo @@ -57,19 +57,19 @@ In order to create a new gateway it is necessary to follow some strict steps. 1. create a token with the max possible supply that will be issued 2. transfer 100% of them to the gateways CC's global pubkey's asset CC address. (yes it is a bit confusing) - 3. create an oracle with the identical name, ie. KMD and format must start with Ihh (height, blockhash, merkleroot) + 3. create an oracle with the identical name, ie. HUSH and format must start with Ihh (height, blockhash, merkleroot) 4. register a publisher and fund it with a subscribe. there will be a special client app that will automatically publish the merkleroots. 5. Now a gatewaysbind can bind an external coin to an asset, along with the oracle for the merkleroots. the txid from the bind is used in most of the other gateways CC calls usage: - ./c tokencreate KMD 1000000 KMD_equivalent_token_for_gatewaysCC + ./c tokencreate HUSH 1000000 HUSH_equivalent_token_for_gatewaysCC a7398a8748354dd0a3f8d07d70e65294928ecc3674674bb2d9483011ccaa9a7a transfer to gateways pubkey: 03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40 RDMqGyREkP1Gwub1Nr5Ye8a325LGZsWBCb ./c tokentransfer a7398a8748354dd0a3f8d07d70e65294928ecc3674674bb2d9483011ccaa9a7a 03ea9c062b9652d8eff34879b504eda0717895d27597aaeb60347d65eed96ccb40 100000000000000 2206fc39c0f384ca79819eb491ddbf889642cbfe4d0796bb6a8010ed53064a56 - ./c oraclescreate KMD blockheaders Ihh + ./c oraclescreate HUSH blockheaders Ihh 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 ./c oraclesregister 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 1000000 @@ -79,7 +79,7 @@ f9499d8bb04ffb511fcec4838d72e642ec832558824a2ce5aed87f1f686f8102 gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s) - ./c gatewaysbind a7398a8748354dd0a3f8d07d70e65294928ecc3674674bb2d9483011ccaa9a7a 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 KMD 100000000000000 1 1 02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92 + ./c gatewaysbind a7398a8748354dd0a3f8d07d70e65294928ecc3674674bb2d9483011ccaa9a7a 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 HUSH 100000000000000 1 1 02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92 e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e ./c gatewaysinfo e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e @@ -87,7 +87,7 @@ "result": "success", "name": "Gateways", "pubkey": "02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92", - "coin": "KMD", + "coin": "HUSH", "oracletxid": "1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808", "taddr": 0, "prefix": 60, @@ -99,7 +99,7 @@ "issued": "0.00000000" } - To make a gateway deposit, send the funds to the "deposit" address, along with any amount to the same pubkey address you want to get the assetized KMD to appear in. + To make a gateway deposit, send the funds to the "deposit" address, along with any amount to the same pubkey address you want to get the assetized HUSH to appear in. 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 pubkey for RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha ./hush-cli z_sendmany "" '[{"address":"RFpxgqff7FDHFuHa3jSX5NzqqWCcELz8ha","amount":0.0001},{"address":"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj","amount":7.6999}]' @@ -112,27 +112,27 @@ 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b gatewaysdeposit bindtxid height coin cointxid claimvout deposithex proof destpub amount - ./hush-cli -ac_name=AT5 gatewaysdeposit e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e 1003776 KMD bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 0 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b 04000000232524ea04b54489eb222f8b3f566ed35504e3050488a63f0ab7b1c2030000007f91615f04835822bf6984a56482aeeb11d03814352eca9afc0a20192fdcae900000000000000000000000000000000000000000000000000000000000000000268e965ba608071d0800038e16762900000000000000000000000000000000000000000042008dd6fd4005016b4292b05df6dfd316c458c53e28fb2befb96e4870a40c6c04e733d75d8a7a18cce34fe326005efdc403bfa4644e30eeafdaeff34419edc591299e6cc5933cb2eeecbab5c4dfe97cd413b75215999a3dd02b540373581e81d8512bff1640590a6b4da4aaa9b8adc0102c38ca0022daed997b53ed192ba326e212fba5e505ce29e3ad149cef7f48d0e00948a1acd81731d84008760759211eb4abbc7b037939a7964182edb59cf9065357e864188ee5fc7316e8796963036bb99eeb9f06c95d64f78749ecec7181c12eb5d83a3b9b1c1e8a0aae9a20ce04a250b28216620bfc99bb81a6de4db80b93a5aea916de97c1a272e26644abdd683f19c5e3174a2e4513ed767d8f11a4c3074295f697839c5d9139676a813451cc7da38f68cbae5d990a79075f98903233ca04fe1b4b099e433585e5adcc45d41d54a9c648179297359c75950a5e574f13f70b728bbbf552770256315cd0a00139d6ab6934cb5ed70a4fc01a92611b096dd0028f17f4cc687b75f37dca530aa47a18321c50528dbd9272eabb3e13a87021a05918a6d2627e2caba6d7cf1a9f0b831ea3337b9a6af92746d83140078d60c72b6beacf91c9e68a34cee209e08670be1d17ff8d80b7a2285b1325461a2e33f2ee675593f1900e066a5d212615cd8da18749b0e684eee73edcc9031709be715b889c6d015cf4bd4ad5ab7e21bd3492c208930a54d353ef36a437f507ead38855633c1b88d060d9e4221ca8ce2f698e8a6ae0d41e9ace3cbd401f1e0f07650e9c126d4ef20278c8be6e85c7637513643f8d02d7ad64c09da11c16429d60e5160c345844b8158ece62794e8ad280d4e4664150e74978609ece431e51a9f9e1ce8aa49c16f36c7fd12b71acc42d893e18476b8b1e144a8175519612efc93e0aecc61f3b21212c958b0e2331d76aaa62faf11a58fe2bd91ab9ab01b906406c9bbc02df2a106e67182aae0a20b538bf19f09c57f9de5e198ba254580fb1b11e22ad526550093420cb7c68628d4c3ad329c8acc6e219093d277810ed016b6099b7e3781de412a22dacedaa2acf29e8062debcd85c7b9529a20b2782a2470763ac27cf89611a527d43ac89b8063ffb93b6ed993425194f8ee821a8493a563072c896f9584f95db28e3f2fc5fb4a6f3c39d615cd563641717cd50afb73ed3989cbf504b2043882993ce9575f56402534173b1396fbc13df80920b46788ae340ad5a91f25177cc74aa69024d76f56166199d2e4d50a053555256c4e3137ea1cee1130e916a88b6ee5cf2c85652fb8824d5dacfa485e3ef6190591ac0c2fcacc4fc7deb65aca4b0b89b76e35a46b0627e2e967cc63a5d606a984c8e63eabb98fde3e69114340ae524c974cb936e57690e98a7a74533f6f7d1d0496976496b54d14a8163efb32b70dfbb79d80a3022c4f53571c08bf044270565716b435084376714b224ab23e9817c05af8223723afc0577af5c8fc28f71036ca82528aaa4ca9bcd18a50e25d2a528f183d3a2074d968d170876d8dce434c5937261b55173ab87e03d5632ca0834fdc5387c15ab3a17d75c0f274004f289ff1bf7d14e97fdf4172eb49adfb418cc2f4794806ae7c0111c97df4d65d38679ec93fea3ef738ed565e8906a8fe1861cafe3938c772fedcfab40159938e06ef414fd299f2355c6d3369bc1bd3c4db64ce205f0a1b70a40030f505b736e28230de82e97776b5ee7b10708bb3020d28cec7a8e124549ec80c547ac4e7b52bf397c72bcfce30820554ab8fb4d1f73b209bc32a0e7e878843cdbf5f01222728ccea7e6ab7cb5e3fee3234f5b85d1985f91492f6ceaa6454a658dab5074f163ce26ed753137fa61c940679de13bd7b212cd3cf2b334f5201cecbc7473342bd7a239e09169bccd56d03000000037a9068df0625e548e71263c8361b4e904c998378f6b9e32729c3f19b10ad752e093013788222f5c26bfc5da4eeb7d32f01486a54179f19c341b79d420ea041bc8878d22fad4692b2d609c3cf190903874d3682a714c7483518c9392e07c25035010b 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 + ./hush-cli -ac_name=AT5 gatewaysdeposit e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e 1003776 HUSH bc41a00e429db741c3199f17546a48012fd3b7eea45dfc6bc2f5228278133009 0 010000000149964cdcd17fe9b1cae4d0f3b5f5db301d9b4f54099fdf4d34498df281757094010000006a4730440220594f3a630dd73c123f44621aa8bb9968ab86734833453dd479af6d79ae6f584202207bb5e35f13b337ccc8a88d9a006c8c5ddb016c0a6f4f2dc44357a8128623d85d01210223154bf53cd3a75e64d86697070d6437c8f0010a09c1df35b659e31ce3d79b5dffffffff0310270000000000001976a91447d2e323a14b0c3be08698aa46a9b91489b189d688ac701de52d000000001976a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688acb0a86a00000000001976a914f9a9daf5519dae38b8b61d945f075da895df441d88ace18d965b 04000000232524ea04b54489eb222f8b3f566ed35504e3050488a63f0ab7b1c2030000007f91615f04835822bf6984a56482aeeb11d03814352eca9afc0a20192fdcae900000000000000000000000000000000000000000000000000000000000000000268e965ba608071d0800038e16762900000000000000000000000000000000000000000042008dd6fd4005016b4292b05df6dfd316c458c53e28fb2befb96e4870a40c6c04e733d75d8a7a18cce34fe326005efdc403bfa4644e30eeafdaeff34419edc591299e6cc5933cb2eeecbab5c4dfe97cd413b75215999a3dd02b540373581e81d8512bff1640590a6b4da4aaa9b8adc0102c38ca0022daed997b53ed192ba326e212fba5e505ce29e3ad149cef7f48d0e00948a1acd81731d84008760759211eb4abbc7b037939a7964182edb59cf9065357e864188ee5fc7316e8796963036bb99eeb9f06c95d64f78749ecec7181c12eb5d83a3b9b1c1e8a0aae9a20ce04a250b28216620bfc99bb81a6de4db80b93a5aea916de97c1a272e26644abdd683f19c5e3174a2e4513ed767d8f11a4c3074295f697839c5d9139676a813451cc7da38f68cbae5d990a79075f98903233ca04fe1b4b099e433585e5adcc45d41d54a9c648179297359c75950a5e574f13f70b728bbbf552770256315cd0a00139d6ab6934cb5ed70a4fc01a92611b096dd0028f17f4cc687b75f37dca530aa47a18321c50528dbd9272eabb3e13a87021a05918a6d2627e2caba6d7cf1a9f0b831ea3337b9a6af92746d83140078d60c72b6beacf91c9e68a34cee209e08670be1d17ff8d80b7a2285b1325461a2e33f2ee675593f1900e066a5d212615cd8da18749b0e684eee73edcc9031709be715b889c6d015cf4bd4ad5ab7e21bd3492c208930a54d353ef36a437f507ead38855633c1b88d060d9e4221ca8ce2f698e8a6ae0d41e9ace3cbd401f1e0f07650e9c126d4ef20278c8be6e85c7637513643f8d02d7ad64c09da11c16429d60e5160c345844b8158ece62794e8ad280d4e4664150e74978609ece431e51a9f9e1ce8aa49c16f36c7fd12b71acc42d893e18476b8b1e144a8175519612efc93e0aecc61f3b21212c958b0e2331d76aaa62faf11a58fe2bd91ab9ab01b906406c9bbc02df2a106e67182aae0a20b538bf19f09c57f9de5e198ba254580fb1b11e22ad526550093420cb7c68628d4c3ad329c8acc6e219093d277810ed016b6099b7e3781de412a22dacedaa2acf29e8062debcd85c7b9529a20b2782a2470763ac27cf89611a527d43ac89b8063ffb93b6ed993425194f8ee821a8493a563072c896f9584f95db28e3f2fc5fb4a6f3c39d615cd563641717cd50afb73ed3989cbf504b2043882993ce9575f56402534173b1396fbc13df80920b46788ae340ad5a91f25177cc74aa69024d76f56166199d2e4d50a053555256c4e3137ea1cee1130e916a88b6ee5cf2c85652fb8824d5dacfa485e3ef6190591ac0c2fcacc4fc7deb65aca4b0b89b76e35a46b0627e2e967cc63a5d606a984c8e63eabb98fde3e69114340ae524c974cb936e57690e98a7a74533f6f7d1d0496976496b54d14a8163efb32b70dfbb79d80a3022c4f53571c08bf044270565716b435084376714b224ab23e9817c05af8223723afc0577af5c8fc28f71036ca82528aaa4ca9bcd18a50e25d2a528f183d3a2074d968d170876d8dce434c5937261b55173ab87e03d5632ca0834fdc5387c15ab3a17d75c0f274004f289ff1bf7d14e97fdf4172eb49adfb418cc2f4794806ae7c0111c97df4d65d38679ec93fea3ef738ed565e8906a8fe1861cafe3938c772fedcfab40159938e06ef414fd299f2355c6d3369bc1bd3c4db64ce205f0a1b70a40030f505b736e28230de82e97776b5ee7b10708bb3020d28cec7a8e124549ec80c547ac4e7b52bf397c72bcfce30820554ab8fb4d1f73b209bc32a0e7e878843cdbf5f01222728ccea7e6ab7cb5e3fee3234f5b85d1985f91492f6ceaa6454a658dab5074f163ce26ed753137fa61c940679de13bd7b212cd3cf2b334f5201cecbc7473342bd7a239e09169bccd56d03000000037a9068df0625e548e71263c8361b4e904c998378f6b9e32729c3f19b10ad752e093013788222f5c26bfc5da4eeb7d32f01486a54179f19c341b79d420ea041bc8878d22fad4692b2d609c3cf190903874d3682a714c7483518c9392e07c25035010b 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 -> 9d80ea79a65aaa0d464f8b762356fa01047e16e9793505a22ca04559f81a6eb6 to get the merkleroots onchain, from the multisig signers nodes run the oraclefeed program with acname oracletxid pubkey Ihh ./oraclefeed AT5 1f1aefcca2bdea8196cfd77337fb21de22d200ddea977c2f9e8742c55829d808 02ebc786cb83de8dc3922ab83c21f3f8a2f3216940c3bf9da43ce39e2a3a882c92 Ihh gatewaysclaim bindtxid coin deposittxid destpub amount - ./c gatewaysclaim e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD 9d80ea79a65aaa0d464f8b762356fa01047e16e9793505a22ca04559f81a6eb6 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 + ./c gatewaysclaim e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e HUSH 9d80ea79a65aaa0d464f8b762356fa01047e16e9793505a22ca04559f81a6eb6 0223d114dededb04f253816d6ad0ce78dd08c617c94ce3c53bf50dc74a5157bef8 7.6999 now the asset is in the pubkey's asset address! it can be used, traded freely and any node who has the asset can do a gatewayswithdraw gatewayswithdraw bindtxid coin withdrawpub amount - ./c gatewayswithdraw e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD 03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828 1 + ./c gatewayswithdraw e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e HUSH 03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828 1 ef3cc452da006eb2edda6b6ed3d3347664be51260f3e91f59ec44ec9701367f0 - Now there is a withdraw pending, so it needs to be processed by the signing nodes on the KMD side + Now there is a withdraw pending, so it needs to be processed by the signing nodes on the HUSH side gatewayspending bindtxid coin gatewayspending will display all pending withdraws and if it is done on one of the msigpubkeys, then it will queue it for processing - ./c gatewayspending e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD + ./c gatewayspending e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e HUSH Implementation Issues: @@ -151,10 +151,10 @@ */ // start of consensus code -#define KMD_PUBTYPE 60 -#define KMD_P2SHTYPE 85 -#define KMD_WIFTYPE 188 -#define KMD_TADDR 0 +#define HUSH_PUBTYPE 60 +#define HUSH_P2SHTYPE 85 +#define HUSH_WIFTYPE 188 +#define HUSH_TADDR 0 #define CC_MARKER_VALUE 10000 CScript EncodeGatewaysBindOpRet(uint8_t funcid,uint256 tokenid,std::string coin,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector gatewaypubkeys,uint8_t taddr,uint8_t prefix,uint8_t prefix2,uint8_t wiftype) @@ -184,7 +184,7 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,ui depositaddr[0] = 0; if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> coin; ss >> totalsupply; ss >> oracletxid; ss >> M; ss >> N; ss >> gatewaypubkeys; ss >> taddr; ss >> prefix; ss >> prefix2; ss >> wiftype) != 0 ) { - if ( prefix == KMD_PUBTYPE && prefix2 == KMD_P2SHTYPE ) + if ( prefix == HUSH_PUBTYPE && prefix2 == HUSH_P2SHTYPE ) { if ( N > 1 ) { @@ -874,12 +874,12 @@ UniValue GatewaysBind(const CPubKey& pk, uint64_t txfee,std::string coin,uint256 cp = CCinit(&C,EVAL_GATEWAYS); cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if (coin=="KMD") + if (coin=="HUSH") { - prefix = KMD_PUBTYPE; - prefix2 = KMD_P2SHTYPE; - wiftype = KMD_WIFTYPE; - taddr = KMD_TADDR; + prefix = HUSH_PUBTYPE; + prefix2 = HUSH_P2SHTYPE; + wiftype = HUSH_WIFTYPE; + taddr = HUSH_TADDR; } else { diff --git a/src/cc/importgateway.cpp b/src/cc/importgateway.cpp index 499721909..1afaeec94 100644 --- a/src/cc/importgateway.cpp +++ b/src/cc/importgateway.cpp @@ -19,13 +19,11 @@ #include "CCImportGateway.h" #include "key_io.h" #include "../importcoin.h" - // start of consensus code - -#define KMD_PUBTYPE 60 -#define KMD_P2SHTYPE 85 -#define KMD_WIFTYPE 188 -#define KMD_TADDR 0 +#define HUSH_PUBTYPE 60 +#define HUSH_P2SHTYPE 85 +#define HUSH_WIFTYPE 188 +#define HUSH_TADDR 0 #define CC_MARKER_VALUE 10000 extern uint256 HUSH_EARLYTXID; @@ -46,7 +44,7 @@ uint8_t DecodeImportGatewayBindOpRet(char *burnaddr,const CScript &scriptPubKey, burnaddr[0] = 0; if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> coin; ss >> oracletxid; ss >> M; ss >> N; ss >> importgatewaypubkeys; ss >> taddr; ss >> prefix; ss >> prefix2; ss >> wiftype) != 0 ) { - if ( prefix == KMD_PUBTYPE && prefix2 == KMD_P2SHTYPE ) + if ( prefix == HUSH_PUBTYPE && prefix2 == HUSH_P2SHTYPE ) { if ( N > 1 ) { @@ -481,12 +479,12 @@ std::string ImportGatewayBind(uint64_t txfee,std::string coin,uint256 oracletxid cp = CCinit(&C,EVAL_IMPORTGATEWAY); cpTokens = CCinit(&CTokens,EVAL_TOKENS); - if (coin=="KMD") + if (coin=="HUSH") { - prefix = KMD_PUBTYPE; - prefix2 = KMD_P2SHTYPE; - wiftype = KMD_WIFTYPE; - taddr = KMD_TADDR; + prefix = HUSH_PUBTYPE; + prefix2 = HUSH_P2SHTYPE; + wiftype = HUSH_WIFTYPE; + taddr = HUSH_TADDR; } else { diff --git a/src/cc/importpayout.cpp b/src/cc/importpayout.cpp index 2740d8ef2..a3fd90394 100644 --- a/src/cc/importpayout.cpp +++ b/src/cc/importpayout.cpp @@ -31,7 +31,7 @@ * notarised on another chain. * * IN: params - condition params - * IN: importTx - Payout transaction on value chain (KMD) + * IN: importTx - Payout transaction on value chain (HUSH) * IN: nIn - index of input of stake * * importTx: Spends stakeTx with payouts from asset chain diff --git a/src/cc/makerogue b/src/cc/makerogue index ff16cbb16..408b35c77 100755 --- a/src/cc/makerogue +++ b/src/cc/makerogue @@ -1,12 +1,14 @@ #!/bin/sh +# Copyright 2016-2021 The Hush developers cd rogue; make clean; if [ "$HOST" = "x86_64-w64-mingw32" ]; then - echo building rogue.exe... + echo "Not supported" + exit 1 ./configure --host=x86_64-w64-mingw32 echo $PWD - wget https://github.com/KomodoPlatform/rogue/releases/download/0.3.3b-01/x86_64-w64-mingw32.tar.gz + # wget ... tar xvfz x86_64-w64-mingw32.tar.gz && rm x86_64-w64-mingw32.tar.gz echo lib archive cleaned echo $PWD diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp index 7ee5c815b..47570fe05 100644 --- a/src/cc/pegs.cpp +++ b/src/cc/pegs.cpp @@ -31,45 +31,45 @@ pegs CC is able to create a coin backed (by any supported coin with gateways CC - OK, now we are ready to describe the pegs CC. Let us imagine an -ac_import sidechain with KMD gateways CC. Now we have each native coin fungible with the real KMD via the gateways deposit/withdraw mechanism. Let us start with that and make a pegged and backed USD chain. + OK, now we are ready to describe the pegs CC. Let us imagine an -ac_import sidechain with HUSH gateways CC. Now we have each native coin fungible with the real HUSH via the gateways deposit/withdraw mechanism. Let us start with that and make a pegged and backed USD chain. - Here the native coin is KMD, but we want USD, so there needs to be a way to convert the KMD amounts into USD amounts. Something like "KMDBTC, BTCUSD, *, 1" which is the prices CC syntax to calculate KMD/USD, which is exactly what we need. So now we can assume that we have a block by block usable KMD/USD price. implementationwise, there can be an -ac option like -ac_peg="KMDBTC, BTCUSD, *, 1" and in conjunction with -ac_import=KMD gateways CC sidechain, we now have a chain where deposit of KMD issues the correct USD coins and redeem of USD coins releases the correct number of KMD coins. + Here the native coin is HUSH, but we want USD, so there needs to be a way to convert the HUSH amounts into USD amounts. Something like "HUSHBTC, BTCUSD, *, 1" which is the prices CC syntax to calculate HUSH/USD, which is exactly what we need. So now we can assume that we have a block by block usable HUSH/USD price. implementationwise, there can be an -ac option like -ac_peg="HUSHBTC, BTCUSD, *, 1" and in conjunction with -ac_import=HUSH gateways CC sidechain, we now have a chain where deposit of HUSH issues the correct USD coins and redeem of USD coins releases the correct number of HUSH coins. Are we done yet? - Not quite, as the prices of KMD will be quite volatile relative to USD, which is good during bull markets, not so happy during bear markets. There are 2 halves to this problem, how to deal with massive price increase (easy to solve), how to solve 90% price drop (a lot harder). + Not quite, as the prices of HUSH will be quite volatile relative to USD, which is good during bull markets, not so happy during bear markets. There are 2 halves to this problem, how to deal with massive price increase (easy to solve), how to solve 90% price drop (a lot harder). In order to solve both, what is needed is an "account" based tracking which updates based on both price change, coins issued, payments made. So let us create an account that is based on a specific pubkey, where all relevant deposits, issuances, withdraws are tracked via appropriate vin/vout markers. - Let us modify the USD chain above so that only 80% of the possible USD is issued and 20% held in reserve. This 80% should be at least some easily changeable #define, or even an -ac parameter. We want the issued coins to be released without any encumberances, but the residual 20% value is still controlled (owned) but the depositor. This account has the amount of KMD deposited and USD issued. At the moment of deposit, there will still be 20% equity left. Let us start with 1000 KMD deposit, $1.5 per KMD -> 800 KMD converted to 1200 USD into depositor pubkey and the account of (1000 KMD, -1200 USD) = 200 KMD or $300 equity. + Let us modify the USD chain above so that only 80% of the possible USD is issued and 20% held in reserve. This 80% should be at least some easily changeable #define, or even an -ac parameter. We want the issued coins to be released without any encumberances, but the residual 20% value is still controlled (owned) but the depositor. This account has the amount of HUSH deposited and USD issued. At the moment of deposit, there will still be 20% equity left. Let us start with 1000 HUSH deposit, $1.5 per HUSH -> 800 HUSH converted to 1200 USD into depositor pubkey and the account of (1000 HUSH, -1200 USD) = 200 HUSH or $300 equity. - Now it becomes easy for the bull market case, which is to allow (for a fee like 1%) issuance of more USD as the equity increases, so let us imagine KMD at $10: + Now it becomes easy for the bull market case, which is to allow (for a fee like 1%) issuance of more USD as the equity increases, so let us imagine HUSH at $10: - (1000 KMD, -1200 USD, 200KMD reserve) -> $2000 equity, issue 80% -> $1600 using 160 KMD - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) + (1000 HUSH, -1200 USD, 200HUSH reserve) -> $2000 equity, issue 80% -> $1600 using 160 HUSH + (1000 HUSH, -1200 USD, 200HUSH reserve, -160HUSH, issue $1600 USD, 40 HUSH reserve) - we have $2800 USD in circulation, 40 KMD reserve left against $10000 marketcap of the original deposit. It it easy to see that there are never any problems with lack of KMD to redeem the issued USD in a world where prices only go up. Total USD issuance can be limited by using a decentralized account tracking based on each deposit. + we have $2800 USD in circulation, 40 HUSH reserve left against $10000 marketcap of the original deposit. It it easy to see that there are never any problems with lack of HUSH to redeem the issued USD in a world where prices only go up. Total USD issuance can be limited by using a decentralized account tracking based on each deposit. What is evident though is that with the constantly changing price and the various times that all the various deposits issue USD, the global reserves are something that will be hard to predict and in fact needs to be specifically tracked. Let us combine all accounts exposure in to a global reserves factor. This factor will control various max/min/ allowed and fee percentages. Now we are prepared to handle the price goes down scenario. We can rely on the global equity/reserve ratio to be changing relatively slowly as the reference price is the smooted trustless oracles price. This means there will be enough blocks to adjust the global reserves percentage. What we need to do is liquidate specific positions that have the least reserves. - What does liquidation mean? It means a specific account will be purchased at below its current value and the KMD withdrawn. Let us assume the price drops to $5: + What does liquidation mean? It means a specific account will be purchased at below its current value and the HUSH withdrawn. Let us assume the price drops to $5: - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) 1000 KMD with 2800 USD issued so $2200 reserves. Let us assume it can be liquidated at a 10% discount, so for $2000 in addition to the $2800, the 5000 KMD is able to be withdrawn. This removes 4800 USD coins for 1000 KMD, which is a very low reserve amount of 4%. If a low reserve amount is removed from the system, then the global reserve amount must be improved. + (1000 HUSH, -1200 USD, 200HUSH reserve, -160HUSH, issue $1600 USD, 40 HUSH reserve) 1000 HUSH with 2800 USD issued so $2200 reserves. Let us assume it can be liquidated at a 10% discount, so for $2000 in addition to the $2800, the 5000 HUSH is able to be withdrawn. This removes 4800 USD coins for 1000 HUSH, which is a very low reserve amount of 4%. If a low reserve amount is removed from the system, then the global reserve amount must be improved. In addition to the global reserves calculation, there needs to be a trigger percentage that enables positions to be liquidated. We also want to liquidate the worst positions, so in addition to the trigger percentage, there should be a liquidation threshold, and the liquidator would need to find 3 or more better positions that are beyond the liquidation threshold, to be able to liquidate. This will get us to at most 3 accounts that could be liquidated but are not able to, so some method to allow those to also be liquidated. The liquidating nodes are making instant profits, so they should be expected to do whatever blockchain scanning and proving to make things easy for the rest of the nodes. One last issue is the normal redemption case where we are not liquidating. In this case, it should be done at the current marketprice, should improve the global reserves metrics and not cause anybody whose position was modified to have cause for complaint. Ideally, there would be an account that has the identical to the global reserve percentage and also at the same price as current marketprice, but this is not realistic, so we need to identify classes of accounts and consider which ones can be fully or partially liquidated to satisfy the constraints. looking at our example account: - (1000 KMD, -1200 USD, 200KMD reserve, -160KMD, issue $1600 USD, 40 KMD reserve) + (1000 HUSH, -1200 USD, 200HUSH reserve, -160HUSH, issue $1600 USD, 40 HUSH reserve) - what sort of non-liquidation withdraw would be acceptable? if the base amount 1000 KMD is reduced along with USD owed, then the reserve status will go up for the account. but that would seem to allow extra USD to be able to be issued. there should be no disadvantage from funding a withdraw, but also not any large advantage. it needs to be a neutral event.... + what sort of non-liquidation withdraw would be acceptable? if the base amount 1000 HUSH is reduced along with USD owed, then the reserve status will go up for the account. but that would seem to allow extra USD to be able to be issued. there should be no disadvantage from funding a withdraw, but also not any large advantage. it needs to be a neutral event.... - One solution is to allow for the chance for any account to be liquidated, but the equity compensated for with a premium based on the account reserves. So in the above case, a premium of 5% on the 40KMD reserve is paid to liquidate its account. Instead of 5% premium, a lower 1% can be done if based on the MAX(correlated[daywindow],smoothed) so we get something that is close to the current marketprice. To prevent people taking advantage of the slowness of the smoothed price to adjust, there would need to be a one day delay in the withdraw. + One solution is to allow for the chance for any account to be liquidated, but the equity compensated for with a premium based on the account reserves. So in the above case, a premium of 5% on the 40HUSH reserve is paid to liquidate its account. Instead of 5% premium, a lower 1% can be done if based on the MAX(correlated[daywindow],smoothed) so we get something that is close to the current marketprice. To prevent people taking advantage of the slowness of the smoothed price to adjust, there would need to be a one day delay in the withdraw. From a practical sense, it seems a day is a long time, so maybe having a way to pay a premium like 10%, or wait a day to get the MAX(correlated[daywindow],smoothed) price. This price "jumping" might also be taken advantage of in the deposit side, so similar to prices CC it seems good to have the MAX(correlated[daywindow],smoothed) method. diff --git a/src/hush_events.h b/src/hush_events.h index ab92521ec..6d733483d 100644 --- a/src/hush_events.h +++ b/src/hush_events.h @@ -117,7 +117,7 @@ void hush_event_undo(struct hush_state *sp,struct hush_event *ep) { case HUSH_EVENT_RATIFY: printf("rewind of ratify, needs to be coded.%d\n",ep->height); break; case HUSH_EVENT_NOTARIZED: break; - case HUSH_EVENT_KMDHEIGHT: + case HUSH_EVENT_HUSHHEIGHT: if ( ep->height <= sp->SAVEDHEIGHT ) sp->SAVEDHEIGHT = ep->height; break; @@ -175,7 +175,7 @@ void hush_eventadd_kmdheight(struct hush_state *sp,char *symbol,int32_t height,i if ( kmdheight > 0 ) { buf[0] = (uint32_t)kmdheight; buf[1] = timestamp; - hush_eventadd(sp,height,symbol,HUSH_EVENT_KMDHEIGHT,(uint8_t *)buf,sizeof(buf)); + hush_eventadd(sp,height,symbol,HUSH_EVENT_HUSHHEIGHT,(uint8_t *)buf,sizeof(buf)); if ( sp != 0 ) komodo_setkmdheight(sp,kmdheight,timestamp); } else { diff --git a/src/hush_structs.h b/src/hush_structs.h index 1dda55a08..fde010d7b 100644 --- a/src/hush_structs.h +++ b/src/hush_structs.h @@ -33,7 +33,7 @@ #define HUSH_MAXBLOCKS 250000 // DONT CHANGE #define HUSH_EVENT_RATIFY 'P' #define HUSH_EVENT_NOTARIZED 'N' -#define HUSH_EVENT_KMDHEIGHT 'K' +#define HUSH_EVENT_HUSHHEIGHT 'K' #define HUSH_EVENT_REWIND 'B' #define HUSH_EVENT_PRICEFEED 'V' #define HUSH_EVENT_OPRETURN 'R' diff --git a/src/rpc/server.h b/src/rpc/server.h index d809597f1..4e301ea8c 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -351,6 +351,7 @@ extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp, const CP extern UniValue setaccount(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue getaccount(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp, const CPubKey& mypk); +extern UniValue listaddresses(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue signmessage(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue verifymessage(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e1dd4e8e9..55af77ce2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -423,6 +423,37 @@ UniValue getaccount(const UniValue& params, bool fHelp, const CPubKey& mypk) return strAccount; } +UniValue listaddresses(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "listaddresses\n" + "\nResult:\n" + "[ (json array of string)\n" + " \"" + strprintf("%s",hush_chainname()) + "_address\" (string) a " + strprintf("%s",hush_chainname()) + " address associated with the given account\n" + " ,...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("listaddresses", "") + + HelpExampleRpc("listaddresses", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount = AccountFromValue(params[0]); + + // Find all taddrs + UniValue ret(UniValue::VARR); + for (const std::pair& item : pwalletMain->mapAddressBook) { + const CTxDestination& dest = item.first; + const std::string& strName = item.second.name; + ret.push_back(EncodeDestination(dest)); + } + return ret; +} UniValue getaddressesbyaccount(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -441,8 +472,8 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp, const CPubKey " ,...\n" "]\n" "\nExamples:\n" - + HelpExampleCli("getaddressesbyaccount", "\"tabby\"") - + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"") + + HelpExampleCli("getaddressesbyaccount", "\"\"") + + HelpExampleRpc("getaddressesbyaccount", "\"\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -8277,6 +8308,7 @@ static const CRPCCommand commands[] = { "wallet", "getaccount", &getaccount, true }, { "wallet", "getalldata", &getalldata, true }, { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, + { "wallet", "listaddresses", &listaddresses , true }, { "wallet", "getbalance", &getbalance, false }, { "wallet", "getnewaddress", &getnewaddress, true }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 937d3b15c..7b286c2c7 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -441,7 +441,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> wtx; CValidationState state; auto verifier = libzcash::ProofVerifier::Strict(); - // ac_public chains set at height like KMD and ZEX, will force a rescan if we dont ignore this error: bad-txns-acpublic-chain + // ac_public chains which enable at a certain height instead of from genesis, this will force a rescan if we dont ignore this error: bad-txns-acpublic-chain // there cannot be any ztx in the wallet on ac_public chains that started from block 1, so this wont affect those. // ac_private chains fail this check for notary nodes, need exception. Triggers full rescan without it. if ( !(CheckTransaction(0,wtx, state, verifier, 0, 0) && (wtx.GetHash() == hash) && state.IsValid()) && (state.GetRejectReason() != "bad-txns-acpublic-chain" && state.GetRejectReason() != "bad-txns-acprivacy-chain" && state.GetRejectReason() != "bad-txns-stakingtx") ) From 54fd44756f9b89f9322604b6da4ba9c1b84b3773 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 20:41:20 -0400 Subject: [PATCH 072/115] clean up dead code --- src/cc/betprotocol.cpp | 2 +- src/cc/dapps/diceloop | 6 ------ src/cc/rogue/main.c | 37 -------------------------------- src/hush_gateway.h | 48 +++++++++++++++++++++--------------------- 4 files changed, 25 insertions(+), 68 deletions(-) delete mode 100755 src/cc/dapps/diceloop diff --git a/src/cc/betprotocol.cpp b/src/cc/betprotocol.cpp index d5959b707..d8e904287 100644 --- a/src/cc/betprotocol.cpp +++ b/src/cc/betprotocol.cpp @@ -167,7 +167,7 @@ bool GetOpReturnHash(CScript script, uint256 &hash) * notarised on another chain. * * IN: params - condition params - * IN: importTx - Payout transaction on value chain (KMD) + * IN: importTx - Payout transaction on value chain (HUSH) * IN: nIn - index of input of stake * * importTx: Spends stakeTx with payouts from asset chain diff --git a/src/cc/dapps/diceloop b/src/cc/dapps/diceloop deleted file mode 100755 index 44550b46a..000000000 --- a/src/cc/dapps/diceloop +++ /dev/null @@ -1,6 +0,0 @@ -while true -do -./c dicestatus KMDICE 5be49570c56d036abb08b6d084da93a8a86f58fc48db4a1086be95540d752d6f - -sleep 10 -done diff --git a/src/cc/rogue/main.c b/src/cc/rogue/main.c index e627f751f..5ded26d56 100644 --- a/src/cc/rogue/main.c +++ b/src/cc/rogue/main.c @@ -658,43 +658,6 @@ uint16_t _hush_userpass(char *username, char *password, FILE *fp) return(port); } -/*void hush_statefname(char *fname,char *symbol,char *str) -{ - int32_t n,len; - sprintf(fname,"%s",getDataDir()); - if ( (n= (int32_t)strlen(ASSETCHAINS_SYMBOL)) != 0 ) - { - len = (int32_t)strlen(fname); - if ( strcmp(ASSETCHAINS_SYMBOL,&fname[len - n]) == 0 ) - fname[len - n] = 0; - else - { - printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]); - return; - } - } - else - { -#ifdef _WIN32 - strcat(fname,"\\"); -#else - strcat(fname,"/"); -#endif - } - if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 ) - { - strcat(fname,symbol); - //printf("statefname.(%s) -> (%s)\n",symbol,fname); -#ifdef _WIN32 - strcat(fname,"\\"); -#else - strcat(fname,"/"); -#endif - } - strcat(fname,str); - //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname); -}*/ - uint16_t hush_userpass(char *userpass,char *symbol) { FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[HUSH_SMART_CHAIN_MAXLEN]; diff --git a/src/hush_gateway.h b/src/hush_gateway.h index 7eb0bd8b3..fbc5b6748 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -236,8 +236,8 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t { txids[n] = p.txid; vouts[n] = p.vout; - values[n] = (strcmp("KMD",base) == 0) ? p.komodoshis : p.fiatoshis; - srcvalues[n] = (strcmp("KMD",base) == 0) ? p.fiatoshis : p.komodoshis; + values[n] = (strcmp("HUSH3",base) == 0) ? p.komodoshis : p.fiatoshis; + srcvalues[n] = (strcmp("HUSH3",base) == 0) ? p.fiatoshis : p.komodoshis; kmdheights[n] = p.height; otherheights[n] = p.otherheight; memcpy(&rmd160s[n * 20],p.rmd160,20); @@ -264,8 +264,8 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t baseids[n] = hush_baseid(base); if ( (pax= komodo_paxfinds(txids[n],vouts[n])) != 0 ) { - values[n] = (strcmp("KMD",base) == 0) ? pax->komodoshis : pax->fiatoshis; - srcvalues[n] = (strcmp("KMD",base) == 0) ? pax->fiatoshis : pax->komodoshis; + values[n] = (strcmp("HUSH3",base) == 0) ? pax->komodoshis : pax->fiatoshis; + srcvalues[n] = (strcmp("HUSH3",base) == 0) ? pax->fiatoshis : pax->komodoshis; kmdheights[n] = pax->height; otherheights[n] = pax->otherheight; memcpy(&rmd160s[n * 20],pax->rmd160,20); @@ -337,7 +337,7 @@ uint64_t komodo_paxtotal() else if ( pax->type == 'W' ) { //bitcoin_address(coinaddr,addrtype,rmd160,20); - if ( (checktoshis= komodo_paxprice(&seed,pax->height,pax->source,(char *)"KMD",(uint64_t)pax->fiatoshis)) != 0 ) + if ( (checktoshis= komodo_paxprice(&seed,pax->height,pax->source,(char *)"HUSH3",(uint64_t)pax->fiatoshis)) != 0 ) { if ( komodo_paxcmp(pax->source,pax->height,pax->komodoshis,checktoshis,seed) != 0 ) { @@ -387,8 +387,8 @@ uint64_t komodo_paxtotal() else { seed = 0; - checktoshis = komodo_paxprice(&seed,pax->height,pax->source,(char *)"KMD",(uint64_t)pax->fiatoshis); - //printf("paxtotal PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f vs %.8f\n",pax->height,pax->symbol,(double)pax->fiatoshis/COIN,(double)pax->komodoshis/COIN,(double)checktoshis/COIN); + checktoshis = komodo_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->komodoshis/COIN,(double)checktoshis/COIN); //printf(" v%d %.8f k.%d ht.%d\n",pax->vout,dstr(pax->komodoshis),pax->height,pax->otherheight); if ( seed != 0 && checktoshis != 0 ) { @@ -446,7 +446,7 @@ int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic else if ( (pax2= komodo_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 ) //strcmp((char *)"KMD",pax->symbol) == 0 && + if ( pax->marked == 0 && pax->approved == 0 && pax->validated != 0 ) { if ( n < sizeof(paxes)/sizeof(*paxes) ) { @@ -480,7 +480,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to 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 *kmdsp = hush_stateptrget((char *)"KMD"); + struct hush_state *kmdsp = hush_stateptrget((char *)"HUSH3"); sp = hush_stateptr(symbol,dest); strcpy(symbol,base); if ( SMART_CHAIN_SYMBOL[0] != 0 && hush_baseid(SMART_CHAIN_SYMBOL) < 0 ) @@ -603,7 +603,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to if ( numvouts > 1 ) { if ( tokomodo != 0 ) - strcpy(symbol,(char *)"KMD"); + strcpy(symbol,(char *)"HUSH3"); for (i=0; symbol[i]!=0; i++) data[len++] = symbol[i]; data[len++] = 0; @@ -854,7 +854,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( opretbuf[0] == 'D' ) { tokomodo = 0; - if ( opretlen == 38 ) // any KMD tx + if ( opretlen == 38 ) // any HUSH3 tx { dragon_rwnum(0,&opretbuf[34],sizeof(kmdheight),&kmdheight); memset(base,0,sizeof(base)); @@ -889,7 +889,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( 0 && strcmp(base,SMART_CHAIN_SYMBOL) == 0 ) printf("########### %p deposited %s += %.8f kmdheight.%d %.8f\n",basesp,base,dstr(fiatoshis),kmdheight,dstr(value)); } else printf("cant get stateptr.(%s)\n",base); - komodo_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,'D',kmdheight,height,(char *)"KMD",0); + komodo_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,'D',kmdheight,height,(char *)"HUSH3",0); } if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) { @@ -933,7 +933,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) pax->marked = checktoshis; if ( kmdheight > 238000 && (kmdheight > 214700 || strcmp(base,SMART_CHAIN_SYMBOL) == 0) ) //seed != 0 && - printf("pax %s deposit %.8f rejected kmdheight.%d %.8f KMD check %.8f seed.%llu\n",base,dstr(fiatoshis),kmdheight,dstr(value),dstr(checktoshis),(long long)seed); + printf("pax %s deposit %.8f rejected kmdheight.%d %.8f HUSH3 check %.8f seed.%llu\n",base,dstr(fiatoshis),kmdheight,dstr(value),dstr(checktoshis),(long long)seed); } } //else printf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",SMART_CHAIN_SYMBOL,base,height,kmdheight); } //else printf("unsupported size.%d for opreturn D\n",opretlen); @@ -941,7 +941,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 else if ( opretbuf[0] == 'I' ) { tokomodo = 0; - if ( strncmp((char *)"KMD",(char *)&opretbuf[opretlen-4],3) != 0 && strncmp(SMART_CHAIN_SYMBOL,(char *)&opretbuf[opretlen-4],3) == 0 ) + if ( strncmp((char *)"HUSH3",(char *)&opretbuf[opretlen-4],3) != 0 && strncmp(SMART_CHAIN_SYMBOL,(char *)&opretbuf[opretlen-4],3) == 0 ) { if ( (n= komodo_issued_opreturn(base,txids,vouts,values,srcvalues,kmdheights,otherheights,baseids,rmd160s,opretbuf,opretlen,0)) > 0 ) { @@ -1021,12 +1021,12 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( 0 && strcmp(base,"RUB") == 0 && (pax == 0 || pax->approved == 0) ) printf("notarize %s %.8f -> %.8f kmd.%d other.%d\n",SMART_CHAIN_SYMBOL,dstr(value),dstr(komodoshis),kmdheight,height); } - komodo_gateway_deposit(coinaddr,0,(char *)"KMD",value,rmd160,txid,vout,'W',kmdheight,height,source,0); + komodo_gateway_deposit(coinaddr,0,(char *)"HUSH3",value,rmd160,txid,vout,'W',kmdheight,height,source,0); if ( (pax= komodo_paxfind(txid,vout,'W')) != 0 ) { pax->type = opretbuf[0]; strcpy(pax->source,base); - strcpy(pax->symbol,"KMD"); + strcpy(pax->symbol,"HUSH3"); pax->height = kmdheight; pax->otherheight = height; pax->komodoshis = komodoshis; @@ -1066,8 +1066,8 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 } didstats = 0; seed = 0; - checktoshis = komodo_paxprice(&seed,kmdheights[i],CURRENCIES[baseids[i]],(char *)"KMD",(uint64_t)values[i]); - //printf("PAX_fiatdest ht.%d price %s %.8f -> KMD %.8f vs %.8f\n",kmdheights[i],CURRENCIES[baseids[i]],(double)values[i]/COIN,(double)srcvalues[i]/COIN,(double)checktoshis/COIN); + checktoshis = komodo_paxprice(&seed,kmdheights[i],CURRENCIES[baseids[i]],(char *)"HUSH3",(uint64_t)values[i]); + //printf("PAX_fiatdest ht.%d price %s %.8f -> HUSH3 %.8f vs %.8f\n",kmdheights[i],CURRENCIES[baseids[i]],(double)values[i]/COIN,(double)srcvalues[i]/COIN,(double)checktoshis/COIN); if ( srcvalues[i] == checktoshis ) { if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) == 0 ) @@ -1123,7 +1123,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( baseids[i] < 0 ) continue; bitcoin_address(coinaddr,60,&rmd160s[i*20],20); - komodo_gateway_deposit(coinaddr,0,0,0,0,txids[i],vouts[i],'X',height,0,(char *)"KMD",0); + komodo_gateway_deposit(coinaddr,0,0,0,0,txids[i],vouts[i],'X',height,0,(char *)"HUSH3",0); komodo_paxmark(height,txids[i],vouts[i],'W',height); komodo_paxmark(height,txids[i],vouts[i],'A',height); komodo_paxmark(height,txids[i],vouts[i],'X',height); @@ -1241,8 +1241,8 @@ void hush_stateind_set(struct hush_state *sp,uint32_t *inds,int32_t n,uint8_t *f } } printf("numR.%d numV.%d numN.%d count.%d\n",numR,numV,numN,count); - /*else if ( func == 'K' ) // KMD height: stop after 1st - else if ( func == 'T' ) // KMD height+timestamp: stop after 1st + /*else if ( func == 'K' ) // HUSH height: stop after 1st + else if ( func == 'T' ) // HUSH height+timestamp: stop after 1st else if ( func == 'N' ) // notarization, scan backwards 1440+ blocks; else if ( func == 'V' ) // price feed: can stop after 1440+ else if ( func == 'R' ) // opreturn:*/ @@ -1465,7 +1465,7 @@ void hush_passport_iteration() //printf("PASSPORT %s baseid+1 %d refid.%d\n",SMART_CHAIN_SYMBOL,baseid+1,refid); if ( baseid+1 != refid ) // only need to import state from a different coin { - if ( baseid == 32 ) // only care about KMD's state + if ( baseid == 32 ) // only care about HUSH3's state { refsp->RTmask &= ~(1LL << baseid); hush_statefname(fname,baseid<32?base:(char *)"",(char *)"hushstate"); @@ -1507,7 +1507,7 @@ void hush_passport_iteration() n++; } lastpos[baseid] = ftell(fp); - if ( 0 && lastpos[baseid] == 0 && strcmp(symbol,"KMD") == 0 ) + if ( 0 && lastpos[baseid] == 0 && strcmp(symbol,"HUSH3") == 0 ) printf("from.(%s) lastpos[%s] %ld isrt.%d\n",SMART_CHAIN_SYMBOL,CURRENCIES[baseid],lastpos[baseid],komodo_isrealtime(&ht)); } //else fprintf(stderr,"%s.%ld ",CURRENCIES[baseid],ftell(fp)); fclose(fp); @@ -1574,7 +1574,7 @@ 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[] = { "KMD", "ETH" }; // must be on binance (for now) +const char *Cryptos[] = { "HUSH", "ETH" }; // must be on binance (for now) // "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" From 8547bea64202007b39dc63b222fbfcf399fcaa5d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 20:47:55 -0400 Subject: [PATCH 073/115] Delete unused script --- src/hush-cli-testnet | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100755 src/hush-cli-testnet diff --git a/src/hush-cli-testnet b/src/hush-cli-testnet deleted file mode 100755 index 81cf1b05a..000000000 --- a/src/hush-cli-testnet +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Copyright (c) 2016-2021 The Hush developers - -# set working directory to the location of this script -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $DIR - -NAME=HUSH3T - -CLI=${KOMODOCLI:-./hush-cli} -$CLI -ac_name=$NAME "$@" From 59fbcbb541f968ba00cdeea28ce8174813157bfe Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 1 Sep 2021 22:34:21 -0400 Subject: [PATCH 074/115] . --- src/hush_bitcoind.h | 4 ++-- src/hush_ccdata.h | 2 +- src/main.cpp | 2 +- src/pow.cpp | 2 +- src/rpc/crosschain.cpp | 4 ++-- src/rpc/server.cpp | 2 +- src/txdb.cpp | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 69ace9a3a..829afdf32 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -847,7 +847,7 @@ uint32_t hush_heightstamp(int32_t height) } }*/ -void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) +void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) { int32_t num,i; CBlock block; memset(pubkey33,0,33); @@ -869,7 +869,7 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) memcpy(destpubkey33,pindex->pubkey33,33); return(pindex->notaryid); } - komodo_index2pubkey33(pubkey33,pindex,height); + hush_index2pubkey33(pubkey33,pindex,height); if ( destpubkey33 != 0 ) memcpy(destpubkey33,pindex->pubkey33,33); if ( pindex->didinit != 0 ) diff --git a/src/hush_ccdata.h b/src/hush_ccdata.h index edfb70c2c..e5e431219 100644 --- a/src/hush_ccdata.h +++ b/src/hush_ccdata.h @@ -24,7 +24,7 @@ int32_t CC_firstheight; uint256 BuildMerkleTree(bool* fMutated, const std::vector leaves, std::vector &vMerkleTree); -uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth) +uint256 hush_calcMoM(int32_t height,int32_t MoMdepth) { static uint256 zero; CBlockIndex *pindex; int32_t i; std::vector tree, leaves; bool fMutated; diff --git a/src/main.cpp b/src/main.cpp index 42dd82efd..6e3c24571 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4996,7 +4996,7 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution"); } // Check proof of work matches claimed amount - /*komodo_index2pubkey33(pubkey33,pindex,height); + /*hush_index2pubkey33(pubkey33,pindex,height); if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) ) return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/ return true; diff --git a/src/pow.cpp b/src/pow.cpp index 8b23c993f..c8b30ea3f 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -672,7 +672,7 @@ bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams& param int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t hush_currentheight(); -void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); +void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); bool hush_checkopret(CBlock *pblock, CScript &merkleroot); CScript hush_makeopret(CBlock *pblock, bool fNew); extern int32_t HUSH_CHOSEN_ONE; diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 0b084b896..45140138b 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -59,7 +59,7 @@ bool EnsureWalletIsAvailable(bool avoidException); int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); -uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); +uint256 hush_calcMoM(int32_t height,int32_t MoMdepth); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); extern std::string ASSETCHAINS_SELFIMPORT; @@ -169,7 +169,7 @@ UniValue calc_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( height <= 0 || MoMdepth <= 0 || MoMdepth >= height ) throw runtime_error("calc_MoM illegal height or MoMdepth\n"); //fprintf(stderr,"height_MoM height.%d\n",height); - MoM = komodo_calcMoM(height,MoMdepth); + MoM = hush_calcMoM(height,MoMdepth); ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH" : SMART_CHAIN_SYMBOL))); ret.push_back(Pair("height",height)); ret.push_back(Pair("MoMdepth",MoMdepth)); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 3e9d17cd2..0d8651497 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -872,7 +872,7 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg string experimentalDisabledHelpMsg(const string& rpc, const string& enableArg) { string daemon = "hushd"; - string ticker = SMART_CHAIN_SYMBOL[0] == 0 ? "komodo" : SMART_CHAIN_SYMBOL; + string ticker = SMART_CHAIN_SYMBOL; return "\nWARNING: " + rpc + " is disabled.\n" "To enable it, restart " + daemon + " with the -experimentalfeatures and\n" diff --git a/src/txdb.cpp b/src/txdb.cpp index 74901bdf4..15f2b99cc 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -647,7 +647,7 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { return true; } -void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); +void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); bool CBlockTreeDB::blockOnchainActive(const uint256 &hash) { BlockMap::const_iterator it = mapBlockIndex.find(hash); @@ -723,7 +723,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() if ( 0 ) // POW will be checked before any block is connected { uint8_t pubkey33[33]; - komodo_index2pubkey33(pubkey33,pindexNew,pindexNew->GetHeight()); + hush_index2pubkey33(pubkey33,pindexNew,pindexNew->GetHeight()); if (!CheckProofOfWork(header,pubkey33,pindexNew->GetHeight(),Params().GetConsensus())) return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); } From b4cf845bf3cb9ad091281082763f2a89c53e0539 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 2 Sep 2021 12:22:04 -0400 Subject: [PATCH 075/115] New listaddresses RPC and z_exportwallet RPC now can be called during RPC warmup --- src/bitcoind.cpp | 2 +- src/hush.h | 6 +- src/hush_bitcoind.h | 5 +- src/hush_gateway.h | 18 +-- src/hush_globals.h | 2 +- src/hush_pax.h | 266 +-------------------------------------- src/hush_utils.h | 2 +- src/miner.cpp | 1 - src/rpc/misc.cpp | 2 +- src/rpc/server.cpp | 3 +- src/wallet/rpcwallet.cpp | 8 +- src/wallet/wallet.cpp | 2 +- 12 files changed, 29 insertions(+), 288 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 26998168e..9ba1b93ae 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -113,7 +113,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) extern int32_t IS_HUSH_NOTARY,USE_EXTERNAL_PUBKEY; extern uint32_t ASSETCHAIN_INIT; extern std::string NOTARY_PUBKEY; -int32_t komodo_is_issuer(); +int32_t hush_is_issuer(); void hush_passport_iteration(); bool AppInit(int argc, char* argv[]) diff --git a/src/hush.h b/src/hush.h index c09d2eea6..1570499c9 100644 --- a/src/hush.h +++ b/src/hush.h @@ -610,7 +610,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi memset(&MoMoMdata,0,sizeof(MoMoMdata)); if ( matched == 0 && signedmask != 0 && bitweight(signedmask) >= HUSH_MINRATIFY ) notarized = 1; - if ( strcmp("PIZZA",ccdata.symbol) == 0 || strncmp("TXSCL",ccdata.symbol,5) == 0 || strcmp("BEER",ccdata.symbol) == 0) + if ( strcmp("DPOW",ccdata.symbol) == 0 || strncmp("ZPOW",ccdata.symbol,5) == 0 || strcmp("TUSH",ccdata.symbol) == 0) notarized = 1; if ( 0 && opretlen != 149 ) printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",SMART_CHAIN_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset); @@ -726,7 +726,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi if ( k == 32 ) { *isratificationp = 1; - printf("ISRATIFICATION (%s)\n",(char *)&scriptbuf[len+32*2+4]); + printf("%s: ISRATIFICATION (%s)\n",__func__,(char *)&scriptbuf[len+32*2+4]); } } @@ -809,7 +809,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) txn_count = block.vtx.size(); for (i=0; i 1 && ASSETCHAINS_NOTARY_PAY[0] != 0 ) break; txhash = block.vtx[i].GetHash(); diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 829afdf32..8e46a00f7 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -408,8 +408,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_hei if ( (item= jobj(json,(char *)"result")) != 0 ) { height = jint(item,(char *)"blocks"); - //TODO: which key to use? - *hushnotarized_heightp = strcmp(dest,"KMD") == 0 ? jint(item,(char *)"notarized") : height; + *hushnotarized_heightp = strcmp(dest,"HUSH3") == 0 ? jint(item,(char *)"notarized") : height; } free_json(json); } @@ -1030,7 +1029,7 @@ int32_t hush_nextheight() else return(hush_longestchain() + 1); } -int32_t komodo_isrealtime(int32_t *kmdheightp) +int32_t hush_isrealtime(int32_t *kmdheightp) { struct hush_state *sp; CBlockIndex *pindex; if ( (sp= hush_stateptrget((char *)"HUSH3")) != 0 ) diff --git a/src/hush_gateway.h b/src/hush_gateway.h index fbc5b6748..c85755d63 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -306,7 +306,7 @@ uint64_t komodo_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 ( komodo_isrealtime(&ht) == 0 ) + if ( hush_isrealtime(&ht) == 0 ) return(0); else { @@ -369,7 +369,7 @@ uint64_t komodo_paxtotal() { if ( pax->marked == 0 ) { - if ( komodo_is_issuer() != 0 ) + if ( hush_is_issuer() != 0 ) { if ( pax->validated != 0 && pax->type == 'D' ) { @@ -431,7 +431,7 @@ int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic 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 ( komodo_isrealtime(&ht) == 0 || SMART_CHAIN_SYMBOL[0] != 0 ) + if ( hush_isrealtime(&ht) == 0 || SMART_CHAIN_SYMBOL[0] != 0 ) return(0); n = 0; HASH_ITER(hh,PAX,pax,tmp) @@ -488,7 +488,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to PENDING_HUSH_TX = 0; for (i=0; i<3; i++) { - if ( komodo_isrealtime(&ht) != 0 ) + if ( hush_isrealtime(&ht) != 0 ) break; sleep(1); } @@ -843,7 +843,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 memset(rmd160s,0,sizeof(rmd160s)); memset(kmdheights,0,sizeof(kmdheights)); memset(otherheights,0,sizeof(otherheights)); - tokomodo = (komodo_is_issuer() == 0); + tokomodo = (hush_is_issuer() == 0); if ( opretbuf[0] == 'K' && opretlen != 40 ) { komodo_kvupdate(opretbuf,opretlen,value); @@ -867,7 +867,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 if ( 0 && strcmp("NOK",base) == 0 ) { printf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",SMART_CHAIN_SYMBOL,base,height,kmdheight); - printf("(%s) (%s) kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",SMART_CHAIN_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(value),komodo_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed); + printf("(%s) (%s) kmdheight.%d vs height.%d check %.8f vs %.8f tokomodo.%d %d seed.%llx\n",SMART_CHAIN_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(value),hush_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed); for (i=0; i<32; i++) printf("%02x",((uint8_t *)&txid)[i]); printf(" <- txid.v%u ",vout); @@ -1005,7 +1005,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 bitcoin_address(coinaddr,addrtype,rmd160,20); checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,value); typestr = "withdraw"; - //printf(" [%s] WITHDRAW %s.height.%d vs height.%d check %.8f/%.8f vs %.8f tokomodo.%d %d seed.%llx -> (%s) len.%d\n",SMART_CHAIN_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(komodoshis),dstr(value),komodo_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed,coinaddr,opretlen); + //printf(" [%s] WITHDRAW %s.height.%d vs height.%d check %.8f/%.8f vs %.8f tokomodo.%d %d seed.%llx -> (%s) len.%d\n",SMART_CHAIN_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(komodoshis),dstr(value),hush_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed,coinaddr,opretlen); didstats = 0; //if ( komodo_paxcmp(base,kmdheight,komodoshis,checktoshis,seed) == 0 ) { @@ -1508,7 +1508,7 @@ void hush_passport_iteration() } lastpos[baseid] = ftell(fp); if ( 0 && lastpos[baseid] == 0 && strcmp(symbol,"HUSH3") == 0 ) - printf("from.(%s) lastpos[%s] %ld isrt.%d\n",SMART_CHAIN_SYMBOL,CURRENCIES[baseid],lastpos[baseid],komodo_isrealtime(&ht)); + printf("from.(%s) lastpos[%s] %ld isrt.%d\n",SMART_CHAIN_SYMBOL,CURRENCIES[baseid],lastpos[baseid],hush_isrealtime(&ht)); } //else fprintf(stderr,"%s.%ld ",CURRENCIES[baseid],ftell(fp)); fclose(fp); } else fprintf(stderr,"load error.(%s) %p\n",fname,sp); @@ -1555,7 +1555,7 @@ void hush_passport_iteration() if ( sp != 0 && isrealtime == 0 ) refsp->RTbufs[0][2] = 0; } - //komodo_paxtotal(); // calls komodo_isrealtime(), which calls hush_longestchain() + //komodo_paxtotal(); // calls hush_isrealtime(), which calls hush_longestchain() refsp->RTmask |= RTmask; if ( expired == 0 && HUSH_PASSPORT_INITDONE == 0 ) { diff --git a/src/hush_globals.h b/src/hush_globals.h index 5e88aa19f..2f3a5eba1 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -26,7 +26,7 @@ int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *not char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port); void hush_init(int32_t height); int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t komodo_isrealtime(int32_t *kmdheightp); +int32_t hush_isrealtime(int32_t *kmdheightp); uint64_t komodo_paxtotal(); int32_t hush_longestchain(); uint64_t komodo_maxallowed(int32_t baseid); diff --git a/src/hush_pax.h b/src/hush_pax.h index d953bdcc2..eca3cc917 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -234,69 +234,6 @@ int32_t dpow_readprices(int32_t height,uint8_t *data,uint32_t *timestampp,double return(n); } -int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize) -{ - static uint32_t lastcrc; - FILE *fp; char fname[512]; uint32_t crc32,check,timestamp; int32_t i,n=0,retval,fsize,len=0; uint8_t data[8192]; -#ifdef _WIN32 - sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),(char *)"komodofeed"); -#else - sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),(char *)"komodofeed"); -#endif - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - fsize = (int32_t)ftell(fp); - rewind(fp); - if ( fsize <= maxsize-4 && fsize <= sizeof(data) && fsize > sizeof(crc32) ) - { - if ( (retval= (int32_t)fread(data,1,fsize,fp)) == fsize ) - { - len = dragon_rwnum(0,data,sizeof(crc32),(void *)&crc32); - check = calc_crc32(0,data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); - if ( check == crc32 ) - { - double KMDBTC,BTCUSD,CNYUSD; uint32_t pvals[128]; - if ( dpow_readprices(height,&data[len],×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals) > 0 ) - { - if ( 0 && lastcrc != crc32 ) - { - for (i=0; i<32; i++) - printf("%u ",pvals[i]); - printf("t%u n.%d KMD %f BTC %f CNY %f (%f)\n",timestamp,n,KMDBTC,BTCUSD,CNYUSD,CNYUSD!=0?1./CNYUSD:0); - } - if ( timestamp > time(NULL)-600 ) - { - n = hush_opreturnscript(opret,'P',data+sizeof(crc32),(int32_t)(fsize-sizeof(crc32))); - if ( 0 && lastcrc != crc32 ) - { - for (i=0; i maxsize.%d or data[%d]\n",fsize,maxsize,(int32_t)sizeof(data)); - fclose(fp); - } //else printf("couldnt open %s\n",fname); - return(n); -} - -/*uint32_t PAX_val32(double val) - { - uint32_t val32 = 0; struct price_resolution price; - if ( (price.Pval= val*1000000000) != 0 ) - { - if ( price.Pval > 0xffffffff ) - printf("Pval overflow error %lld\n",(long long)price.Pval); - else val32 = (uint32_t)price.Pval; - } - return(val32); - }*/ - int32_t PAX_pubkey(int32_t rwflag,uint8_t *pubkey33,uint8_t *addrtypep,uint8_t rmd160[20],char fiat[4],uint8_t *shortflagp,int64_t *fiatoshisp) { if ( rwflag != 0 ) @@ -356,7 +293,7 @@ void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) NUM_PRICES++; portable_mutex_unlock(&hush_mutex); if ( 0 ) - printf("OP_RETURN.%d KMD %.8f BTC %.6f CNY %.6f NUM_PRICES.%d (%llu %llu %llu)\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES,(long long)kmdbtc,(long long)btcusd,(long long)cnyusd); + printf("OP_RETURN.%d HUSH %.8f BTC %.6f CNY %.6f NUM_PRICES.%d (%llu %llu %llu)\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES,(long long)kmdbtc,(long long)btcusd,(long long)cnyusd); } } } @@ -497,214 +434,19 @@ uint64_t komodo_paxcalc(int32_t height,uint32_t *pvals,int32_t baseid,int32_t re return(0); } -uint64_t _komodo_paxprice(uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height,char *base,char *rel,uint64_t basevolume,uint64_t kmdbtc,uint64_t btcusd) -{ - int32_t baseid=-1,relid=-1,i; uint32_t *ptr,*pvals; - if ( height > 10 ) - height -= 10; - if ( (baseid= hush_baseid(base)) >= 0 && (relid= hush_baseid(rel)) >= 0 ) - { - //portable_mutex_lock(&hush_mutex); - for (i=NUM_PRICES-1; i>=0; i--) - { - ptr = &PVALS[36 * i]; - if ( *ptr < height ) - { - pvals = &ptr[1]; - if ( kmdbtcp != 0 && btcusdp != 0 ) - { - *kmdbtcp = pvals[MAX_CURRENCIES] / 539; - *btcusdp = pvals[MAX_CURRENCIES + 1] / 539; - } - //portable_mutex_unlock(&hush_mutex); - if ( kmdbtc != 0 && btcusd != 0 ) - return(komodo_paxcalc(height,pvals,baseid,relid,basevolume,kmdbtc,btcusd)); - else return(0); - } - } - //portable_mutex_unlock(&hush_mutex); - } //else printf("paxprice invalid base.%s %d, rel.%s %d\n",base,baseid,rel,relid); - return(0); -} - -int32_t komodo_kmdbtcusd(int32_t rwflag,uint64_t *kmdbtcp,uint64_t *btcusdp,int32_t height) -{ - static uint64_t *KMDBTCS,*BTCUSDS; static int32_t maxheight = 0; int32_t incr = 10000; - if ( height >= maxheight ) - { - //printf("height.%d maxheight.%d incr.%d\n",height,maxheight,incr); - if ( height >= maxheight+incr ) - incr = (height - (maxheight+incr) + 1000); - KMDBTCS = (uint64_t *)realloc(KMDBTCS,((incr + maxheight) * sizeof(*KMDBTCS))); - memset(&KMDBTCS[maxheight],0,(incr * sizeof(*KMDBTCS))); - BTCUSDS = (uint64_t *)realloc(BTCUSDS,((incr + maxheight) * sizeof(*BTCUSDS))); - memset(&BTCUSDS[maxheight],0,(incr * sizeof(*BTCUSDS))); - maxheight += incr; - } - if ( rwflag == 0 ) - { - *kmdbtcp = KMDBTCS[height]; - *btcusdp = BTCUSDS[height]; - } - else - { - KMDBTCS[height] = *kmdbtcp; - BTCUSDS[height] = *btcusdp; - } - if ( *kmdbtcp != 0 && *btcusdp != 0 ) - return(0); - else return(-1); -} - -uint64_t _komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) -{ - int32_t i,j,k,ind,zeroes,numvotes,wt,nonz; int64_t delta; uint64_t lastprice,tolerance,den,densum,sum=0,votes[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],btcusds[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtcs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)],kmdbtc,btcusd; - if ( basevolume > HUSH_PAXMAX ) - { - printf("komodo_paxprice overflow %.8f\n",dstr(basevolume)); - return(0); - } - if ( strcmp(base,"KMD") == 0 || strcmp(base,"kmd") == 0 ) - { - printf("kmd cannot be base currency\n"); - return(0); - } - numvotes = (int32_t)(sizeof(Peggy_inds)/sizeof(*Peggy_inds)); - memset(votes,0,sizeof(votes)); - //if ( komodo_kmdbtcusd(0,&kmdbtc,&btcusd,height) < 0 ) crashes when via passthru GUI use - { - memset(btcusds,0,sizeof(btcusds)); - memset(kmdbtcs,0,sizeof(kmdbtcs)); - for (i=0; i> 1) ) - { - return(0); - } - return(komodo_paxcorrelation(votes,numvotes,seed) * basevolume / 100000); -} - uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) { - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = hush_baseid(base); - if ( height >= 236000 && strcmp(rel,"kmd") == 0 ) - { - usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN); - if ( strcmp("usd",base) == 0 ) - return(komodo_paxvol(basevolume,usdkmd) * 10); - baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN); - basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000; - //if ( strcmp("KMD",base) == 0 ) - // printf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd); - return(basekmd); - } else return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); + return 0; } -/*uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) -{ - uint64_t baseusd,basekmd,usdkmd; int32_t baseid = hush_baseid(base); - //if ( strcmp(rel,"KMD") != 0 || baseid < 0 || MINDENOMS[baseid] == MINDENOMS[USD] ) - // return(_komodo_paxpriceB(seed,height,base,rel,basevolume)); - //else - { - baseusd = _komodo_paxpriceB(seed,height,base,(char *)"USD",SATOSHIDEN); - usdkmd = _komodo_paxpriceB(seed,height,(char *)"USD",(char *)"KMD",SATOSHIDEN); - basekmd = (komodo_paxvol(basevolume,baseusd) * usdkmd) / 10000000; - if ( strcmp("KMD",base) == 0 ) - printf("baseusd.%llu usdkmd.%llu %llu\n",(long long)baseusd,(long long)usdkmd,(long long)basekmd); - return(basekmd); - } -}*/ - uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume) { - int32_t i,nonz=0; int64_t diff; uint64_t price,seed,sum = 0; - if ( SMART_CHAIN_SYMBOL[0] == 0 && chainActive.LastTip() != 0 && height > chainActive.LastTip()->GetHeight() ) - { - if ( height < 100000000 ) - { - static uint32_t counter; - if ( counter++ < 3 ) - printf("komodo_paxprice height.%d vs tip.%d\n",height,chainActive.LastTip()->GetHeight()); - } - return(0); - } - *seedp = hush_seed(height); - portable_mutex_lock(&hush_mutex); - for (i=0; i<17; i++) - { - if ( (price= komodo_paxpriceB(*seedp,height-i,base,rel,basevolume)) != 0 ) - { - sum += price; - nonz++; - if ( 0 && i == 1 && nonz == 2 ) - { - diff = (((int64_t)price - (sum >> 1)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - printf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>1),(long long)(((int64_t)price - (sum >> 1)) * 10000),(long long)diff); - if ( diff < 33 ) - break; - } - else if ( 0 && i == 3 && nonz == 4 ) - { - diff = (((int64_t)price - (sum >> 2)) * 10000); - if ( diff < 0 ) - diff = -diff; - diff /= price; - printf("(%llu %llu %lld).%lld ",(long long)price,(long long)(sum>>2),(long long) (((int64_t)price - (sum >> 2)) * 10000),(long long)diff); - if ( diff < 20 ) - break; - } - } - if ( height < 165000 || height > 236000 ) - break; - } - portable_mutex_unlock(&hush_mutex); - if ( nonz != 0 ) - sum /= nonz; - //printf("-> %lld %s/%s i.%d ht.%d\n",(long long)sum,base,rel,i,height); - return(sum); + return 0; } int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel) { - int32_t baseid=-1,relid=-1,i,num = 0; uint32_t *ptr; - if ( (baseid= hush_baseid(base)) >= 0 && (relid= hush_baseid(rel)) >= 0 ) - { - for (i=NUM_PRICES-1; i>=0; i--) - { - ptr = &PVALS[36 * i]; - heights[num] = *ptr; - prices[num] = komodo_paxcalc(*ptr,&ptr[1],baseid,relid,COIN,0,0); - num++; - if ( num >= max ) - return(num); - } - } - return(num); + return 0; } void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) diff --git a/src/hush_utils.h b/src/hush_utils.h index 6e3edfc0e..6c19523e4 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -809,7 +809,7 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160, return(coinaddr); } -int32_t komodo_is_issuer() +int32_t hush_is_issuer() { if ( SMART_CHAIN_SYMBOL[0] != 0 && hush_baseid(SMART_CHAIN_SYMBOL) >= 0 ) return(1); diff --git a/src/miner.cpp b/src/miner.cpp index 388bd7c37..dd635493c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -137,7 +137,6 @@ void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uin uint32_t Mining_start,Mining_height; int32_t My_notaryid = -1; int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize); int32_t hush_baseid(char *origbase); int32_t hush_longestchain(); int64_t hush_block_unlocktime(uint32_t nHeight); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 91b012b13..2933d7393 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -252,7 +252,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("notarizedtxid", notarized_desttxid.ToString())); if ( HUSH_NSPV_FULLNODE ) { - txid_height = notarizedtxid_height(SMART_CHAIN_SYMBOL[0] != 0 ? (char *)"HUSH3" : (char *)"BTC",(char *)notarized_desttxid.ToString().c_str(),&hushnotarized_height); + txid_height = notarizedtxid_height( (char *)"HUSH3" ,(char *)notarized_desttxid.ToString().c_str(),&hushnotarized_height); if ( txid_height > 0 ) obj.push_back(Pair("notarizedtxid_height", txid_height)); else obj.push_back(Pair("notarizedtxid_height", "mempool")); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 0d8651497..8874c5e67 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -831,7 +831,8 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // few RPCs means we can see our addresses and make private key backups // while a very long wallet rescan is happening if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && - pcmd->name != "getaddressesbyaccount" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { + pcmd->name != "getaddressesbyaccount" && pcmd->name != "listaddresses" && pcmd->name != "z_exportwallet" && + pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 55af77ce2..c1ad28c2a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -612,9 +612,9 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey37[37],char *coinaddr,int32_t height,char *base,int64_t fiatoshis); int32_t hush_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen); extern int32_t HUSH_PAX; -int32_t komodo_is_issuer(); +int32_t hush_is_issuer(); int32_t dragon_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t komodo_isrealtime(int32_t *kmdheightp); +int32_t hush_isrealtime(int32_t *kmdheightp); int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); @@ -774,7 +774,7 @@ UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk) { throw runtime_error("paxdeposit disabled without -pax"); } - if ( komodo_is_issuer() != 0 ) + if ( hush_is_issuer() != 0 ) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "paxdeposit only from KYC"); if (!EnsureWalletIsAvailable(fHelp)) throw runtime_error("paxdeposit needs wallet"); //return Value::null; @@ -822,7 +822,7 @@ UniValue paxwithdraw(const UniValue& params, bool fHelp, const CPubKey& mypk) throw runtime_error("paxwithdraw deprecated"); if (fHelp || params.size() != 2) throw runtime_error("paxwithdraw address fiatamount"); - if ( komodo_isrealtime(&kmdheight) == 0 ) + if ( hush_isrealtime(&kmdheight) == 0 ) return(0); LOCK2(cs_main, pwalletMain->cs_wallet); CBitcoinAddress address(params[0].get_str()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 233851d64..bab6fa5c1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3061,7 +3061,7 @@ std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime) if ( (wtx.nLockTime >= LOCKTIME_THRESHOLD && wtx.nLockTime < now-HUSH_MAXMEMPOOLTIME) ) { - //LogPrintf("skip Relaying wtx %s nLockTime %u vs now.%u\n", wtx.GetHash().ToString(),(uint32_t)wtx.nLockTime,now); + LogPrintf("%s: skip Relaying wtx %s nLockTime %u vs now.%u\n", __func__, wtx.GetHash().ToString(),(uint32_t)wtx.nLockTime,now); //vwtxh.push_back(wtx.GetHash()); continue; } From 18339394b61e012400a694820cb6532b91f99b20 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 2 Sep 2021 12:29:52 -0400 Subject: [PATCH 076/115] RPCs notaries, signmessage, decoderawtransaction and getnetworkinfo can now be called during RPC warmup --- src/rpc/server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 8874c5e67..8139c93ce 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -832,7 +832,8 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // while a very long wallet rescan is happening if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && pcmd->name != "getaddressesbyaccount" && pcmd->name != "listaddresses" && pcmd->name != "z_exportwallet" && - pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { + pcmd->name != "notaries" && pcmd->name != "signmessage" && pcmd->name != "decoderawtransaction" && + pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" && pcmd->name != "getnetworkinfo" ) { throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } } From 8f7f445063a61dedad7178da4efae1aec7986d20 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 2 Sep 2021 14:53:11 -0400 Subject: [PATCH 077/115] Remove dead code --- src/hush_bitcoind.h | 28 ---------------------------- src/hush_notary.h | 8 ++++---- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 8e46a00f7..0271a80d1 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -857,34 +857,6 @@ void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) } } -/*int8_t komodo_minerid(int32_t height,uint8_t *destpubkey33) -{ - int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t pubkey33[33],pubkeys[64][33]; - if ( (pindex= chainActive[height]) != 0 ) - { - if ( pindex->didinit != 0 ) - { - if ( destpubkey33 != 0 ) - memcpy(destpubkey33,pindex->pubkey33,33); - return(pindex->notaryid); - } - hush_index2pubkey33(pubkey33,pindex,height); - if ( destpubkey33 != 0 ) - memcpy(destpubkey33,pindex->pubkey33,33); - if ( pindex->didinit != 0 ) - return(pindex->notaryid); - timestamp = pindex->GetBlockTime(); - if ( (num= hush_notaries(pubkeys,height,timestamp)) > 0 ) - { - for (i=0; i Date: Thu, 2 Sep 2021 15:01:58 -0400 Subject: [PATCH 078/115] Remove dead code --- src/hush_bitcoind.h | 61 ++++-------------------------------------- src/hush_defs.h | 2 +- src/main.cpp | 2 +- src/miner.cpp | 4 +-- src/pow.cpp | 2 +- src/rpc/blockchain.cpp | 2 +- 6 files changed, 11 insertions(+), 62 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index 0271a80d1..ce90b6347 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -664,18 +664,6 @@ int32_t hush_isPoS(CBlock *pblock,int32_t height,bool fJustCheck) return(0); } -void komodo_disconnect(CBlockIndex *pindex,CBlock& block) -{ - char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; struct hush_state *sp; - //fprintf(stderr,"disconnect ht.%d\n",pindex->GetHeight()); - hush_init(pindex->GetHeight()); - if ( (sp= hush_stateptr(symbol,dest)) != 0 ) - { - //sp->rewinding = pindex->GetHeight(); - //fprintf(stderr,"-%d ",pindex->GetHeight()); - } else printf("hush_disconnect: ht.%d cant get hush_state.(%s)\n",pindex->GetHeight(),SMART_CHAIN_SYMBOL); -} - int32_t hush_is_notarytx(const CTransaction& tx) { uint8_t *ptr; static uint8_t crypto555[33]; @@ -805,47 +793,6 @@ uint32_t hush_heightstamp(int32_t height) return(0); } -/*void komodo_pindex_init(CBlockIndex *pindex,int32_t height) gets data corrupted -{ - int32_t i,num; uint8_t pubkeys[64][33]; CBlock block; - if ( pindex->didinit != 0 ) - return; - //printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->GetHeight(),pindex->notaryid,height); - if ( pindex->didinit == 0 ) - { - pindex->notaryid = -1; - if ( HUSH_LOADINGBLOCKS == 0 ) - memset(pindex->pubkey33,0xff,33); - else memset(pindex->pubkey33,0,33); - if ( hush_blockload(block,pindex) == 0 ) - { - hush_block2pubkey33(pindex->pubkey33,&block); - //for (i=0; i<33; i++) - // fprintf(stderr,"%02x",pindex->pubkey33[i]); - //fprintf(stderr," set pubkey at height %d/%d\n",pindex->GetHeight(),height); - //if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 ) - // pindex->didinit = (HUSH_LOADINGBLOCKS == 0); - } // else fprintf(stderr,"error loading block at %d/%d",pindex->GetHeight(),height); - } - if ( pindex->didinit != 0 && pindex->GetHeight() >= 0 && (num= hush_notaries(pubkeys,(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime)) > 0 ) - { - for (i=0; ipubkey33,33) == 0 ) - { - pindex->notaryid = i; - break; - } - } - if ( 0 && i == num ) - { - for (i=0; i<33; i++) - fprintf(stderr,"%02x",pindex->pubkey33[i]); - fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->GetHeight(),height); - } - } -}*/ - void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) { int32_t num,i; CBlock block; @@ -857,7 +804,7 @@ void hush_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) } } -int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height) +int32_t hush_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height) { // after the season HF block ALL new notaries instantly become elegible. int32_t i,j,n,duplicate; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33]; @@ -880,7 +827,9 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blo break; } } - } else fprintf(stderr,"couldnt load block.%d\n",height); + } else { + fprintf(stderr,"%s: couldnt load block height %d\n",__func__,height); + } if ( mids[0] >= 0 && i > 0 && mids[i] == mids[0] ) duplicate++; } @@ -890,7 +839,7 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blo else return(0); } -int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width) +int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width) { int32_t i,j,nonz,numnotaries; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33],pubkey33[33]; numnotaries = hush_notaries(notarypubs33,height,0); diff --git a/src/hush_defs.h b/src/hush_defs.h index d57b58644..e51255dd8 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -538,7 +538,7 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); -int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); +int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); uint32_t hush_blocktime(uint256 hash); diff --git a/src/main.cpp b/src/main.cpp index 6e3c24571..785dd5ee2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2952,7 +2952,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex *pfClean = false; bool fClean = true; - //komodo_disconnect(pindex,block); does nothing? + CBlockUndo blockUndo; CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) diff --git a/src/miner.cpp b/src/miner.cpp index dd635493c..7e5e0361c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -955,7 +955,7 @@ static bool ProcessBlockFound(CBlock* pblock) } int32_t hush_baseid(char *origbase); -int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height); +int32_t hush_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height); arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); int32_t FOUND_BLOCK,HUSH_MAYBEMINED; extern int32_t HUSH_LASTMINED,HUSH_INSYNC; @@ -1188,7 +1188,7 @@ void static BitcoinMiner() int32_t dispflag = 0; if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) || notaryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 ) dispflag = 1; - komodo_eligiblenotary(pubkeys,mids,blocktimes,&nonzpkeys,pindexPrev->GetHeight()); + hush_eligiblenotary(pubkeys,mids,blocktimes,&nonzpkeys,pindexPrev->GetHeight()); if ( nonzpkeys > 0 ) { for (i=0; i<33; i++) diff --git a/src/pow.cpp b/src/pow.cpp index c8b30ea3f..e42af6720 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -679,7 +679,7 @@ extern int32_t HUSH_CHOSEN_ONE; extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; #define KOMODO_ELECTION_GAP 2000 -int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); +int32_t hush_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); int32_t HUSH_LOADINGBLOCKS = 1; extern std::string NOTARY_PUBKEY; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index f6a1f6dde..82f73036c 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -928,7 +928,7 @@ UniValue minerids(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( pblockindex != 0 ) timestamp = pblockindex->GetBlockTime(); } - if ( (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) + if ( (n= hush_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) { memset(tally,0,sizeof(tally)); numnotaries = hush_notaries(pubkeys,height,timestamp); From 31fa46e2a18d56d32569de09403db3c156f4f11d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 2 Sep 2021 15:49:57 -0400 Subject: [PATCH 079/115] Extra debug for notary stuff --- src/hush_bitcoind.h | 2 +- src/hush_notary.h | 5 +++++ src/main.cpp | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index ce90b6347..bf53316db 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -676,7 +676,7 @@ int32_t hush_is_notarytx(const CTransaction& tx) decode_hex(crypto555,33,(char *)CRYPTO555_PUBSECPSTR); if ( memcmp(ptr+1,crypto555,33) == 0 ) { - //printf("found notarytx\n"); + fprintf(stderr,"%s: found notarytx\n", __func__); return(1); } } diff --git a/src/hush_notary.h b/src/hush_notary.h index 0d10ed6c5..a9280a923 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -99,6 +99,11 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) int32_t hush_season = 0; bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; hush_season = ishush3 ? gethushseason(height) : getacseason(timestamp); + + if(IS_HUSH_NOTARY) { + fprintf(stderr,"%s: [%s] season=%d height=%d time=%d\n", __func__, ishush3 ? "HUSH3" : SMART_CHAIN_SYMBOL, hush_season, height, timestamp); + } + if ( hush_season != 0 ) { if ( didinit[hush_season-1] == 0 ) diff --git a/src/main.cpp b/src/main.cpp index 785dd5ee2..0771ffdb5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1452,8 +1452,12 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState return true; } +// This is used only in RPC currently but hush_notaries()/gethushseason/getacseason is consensus int32_t hush_isnotaryvout(char *coinaddr,uint32_t tiptime) { - int32_t season = getacseason(tiptime); + bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + int32_t height = chainActive.LastTip()->GetHeight(); + int32_t season = ishush3 ? gethushseason(height) : getacseason(tiptime); + fprintf(stderr,"%s: season=%d, tiptime=%d\n", __func__, season,tiptime); if ( NOTARY_ADDRESSES[season-1][0][0] == 0 ) { uint8_t pubkeys[64][33]; hush_notaries(pubkeys,0,tiptime); From e3bb6ed01e546357f30dbd19f0167e60b0f574c4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 2 Sep 2021 18:50:56 -0400 Subject: [PATCH 080/115] listaddresses takes no params and remove accounts from docs --- 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 c1ad28c2a..38546dcea 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -428,12 +428,12 @@ UniValue listaddresses(const UniValue& params, bool fHelp, const CPubKey& mypk) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (fHelp || params.size() != 0) throw runtime_error( "listaddresses\n" "\nResult:\n" "[ (json array of string)\n" - " \"" + strprintf("%s",hush_chainname()) + "_address\" (string) a " + strprintf("%s",hush_chainname()) + " address associated with the given account\n" + " \"" + strprintf("%s",hush_chainname()) + "_address\" (string) a " + strprintf("%s",hush_chainname()) + " address\n" " ,...\n" "]\n" "\nExamples:\n" From 2653b04cfbe11391f32e757d3eedc6ce3e9b875a Mon Sep 17 00:00:00 2001 From: jahway603 Date: Thu, 2 Sep 2021 19:25:50 -0400 Subject: [PATCH 081/115] updated (c) year --- src/smartchains | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smartchains b/src/smartchains index 5dd954c12..1a210dd01 100755 --- a/src/smartchains +++ b/src/smartchains @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2018-2020 The Hush developers +# Copyright (c) 2018-2021 The Hush developers set -eo pipefail # You can now add delay line to pubkey.txt file From 085f28a067c2108afbef2bca462debc9750adbe6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 3 Sep 2021 11:44:22 -0400 Subject: [PATCH 082/115] Hush does not have elections --- src/hush.h | 2 +- src/hush_defs.h | 2 +- src/hush_globals.h | 2 +- src/hush_notary.h | 28 ++++++++++++++-------------- src/miner.cpp | 2 +- src/pow.cpp | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/hush.h b/src/hush.h index 1570499c9..b25dcfcb4 100644 --- a/src/hush.h +++ b/src/hush.h @@ -944,7 +944,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) { memset(&txhash,0,sizeof(txhash)); hush_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); - printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); + printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+HUSH_DPOW_GAP/2)/HUSH_DPOW_GAP)+1)*HUSH_DPOW_GAP,height); } else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); } } diff --git a/src/hush_defs.h b/src/hush_defs.h index e51255dd8..190dae86c 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -23,7 +23,7 @@ #define HUSH_EARLYTXID_HEIGHT 100 #define ASSETCHAINS_MINHEIGHT 128 #define ASSETCHAINS_MAX_ERAS 7 -#define KOMODO_ELECTION_GAP 2000 +#define HUSH_DPOW_GAP 2000 #define ROUNDROBIN_DELAY 61 #define HUSH_SMART_CHAIN_MAXLEN 65 #define HUSH_LIMITED_NETWORKSIZE 4 diff --git a/src/hush_globals.h b/src/hush_globals.h index 2f3a5eba1..c298d8c15 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -34,7 +34,7 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); int32_t hush_checkvout(int32_t vout,int32_t k,int32_t indallvouts); pthread_mutex_t hush_mutex; -#define KOMODO_ELECTION_GAP 2000 //((SMART_CHAIN_SYMBOL[0] == 0) ? 2000 : 100) +#define HUSH_DPOW_GAP 2000 //((SMART_CHAIN_SYMBOL[0] == 0) ? 2000 : 100) #define HUSH_SMART_CHAIN_MAXLEN 65 struct pax_transaction *PAX; diff --git a/src/hush_notary.h b/src/hush_notary.h index a9280a923..610407df3 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -143,17 +143,17 @@ void hush_notarysinit(int32_t origheight,uint8_t pubkeys[64][33],int32_t num) static int32_t hwmheight; int32_t k,i,htind,height; struct knotary_entry *kp; struct knotaries_entry N; if ( Pubkeys == 0 ) - Pubkeys = (struct knotaries_entry *)calloc(1 + (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP),sizeof(*Pubkeys)); + Pubkeys = (struct knotaries_entry *)calloc(1 + (HUSH_MAXBLOCKS / HUSH_DPOW_GAP),sizeof(*Pubkeys)); memset(&N,0,sizeof(N)); if ( origheight > 0 ) { - height = (origheight + KOMODO_ELECTION_GAP/2); - height /= KOMODO_ELECTION_GAP; - height = ((height + 1) * KOMODO_ELECTION_GAP); - htind = (height / KOMODO_ELECTION_GAP); - if ( htind >= HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; - //printf("htind.%d activation %d from %d vs %d | hwmheight.%d %s\n",htind,height,origheight,(((origheight+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,hwmheight,SMART_CHAIN_SYMBOL); + height = (origheight + HUSH_DPOW_GAP/2); + height /= HUSH_DPOW_GAP; + height = ((height + 1) * HUSH_DPOW_GAP); + htind = (height / HUSH_DPOW_GAP); + if ( htind >= HUSH_MAXBLOCKS / HUSH_DPOW_GAP ) + htind = (HUSH_MAXBLOCKS / HUSH_DPOW_GAP) - 1; + //printf("htind.%d activation %d from %d vs %d | hwmheight.%d %s\n",htind,height,origheight,(((origheight+HUSH_DPOW_GAP/2)/HUSH_DPOW_GAP)+1)*HUSH_DPOW_GAP,hwmheight,SMART_CHAIN_SYMBOL); } else htind = 0; pthread_mutex_lock(&hush_mutex); for (k=0; k hwmheight ) @@ -207,9 +207,9 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui return(-1); if ( Pubkeys == 0 ) hush_init(0); - htind = height / KOMODO_ELECTION_GAP; - if ( htind >= HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP ) - htind = (HUSH_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; + htind = height / HUSH_DPOW_GAP; + if ( htind >= HUSH_MAXBLOCKS / HUSH_DPOW_GAP ) + htind = (HUSH_MAXBLOCKS / HUSH_DPOW_GAP) - 1; pthread_mutex_lock(&hush_mutex); HASH_FIND(hh,Pubkeys[htind].Notaries,pubkey33,33,kp); pthread_mutex_unlock(&hush_mutex); diff --git a/src/miner.cpp b/src/miner.cpp index 7e5e0361c..2f4b7495e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1183,7 +1183,7 @@ void static BitcoinMiner() if ( SMART_CHAIN_SYMBOL[0] == 0 && notaryid >= 0 ) { j = 65; - if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 || Mining_height > 1000000 ) + if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % HUSH_DPOW_GAP) > 64 || (Mining_height % HUSH_DPOW_GAP) == 0 || Mining_height > 1000000 ) { int32_t dispflag = 0; if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) || notaryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 ) diff --git a/src/pow.cpp b/src/pow.cpp index e42af6720..143ee71c0 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -677,7 +677,7 @@ bool hush_checkopret(CBlock *pblock, CScript &merkleroot); CScript hush_makeopret(CBlock *pblock, bool fNew); extern int32_t HUSH_CHOSEN_ONE; extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; -#define KOMODO_ELECTION_GAP 2000 +#define HUSH_DPOW_GAP 2000 int32_t hush_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height); int32_t HUSH_LOADINGBLOCKS = 1; From 9e643ba7e96d6b256e10f9ba7349c49afa350275 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 3 Sep 2021 11:55:46 -0400 Subject: [PATCH 083/115] Remove unused code --- src/hush_pax.h | 173 +------------------------------------------------ 1 file changed, 1 insertion(+), 172 deletions(-) diff --git a/src/hush_pax.h b/src/hush_pax.h index eca3cc917..242e4d0fe 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -195,45 +195,6 @@ double PAX_BTCUSD(int32_t height,uint32_t btcusd) return(BTCUSD); } -int32_t dpow_readprices(int32_t height,uint8_t *data,uint32_t *timestampp,double *KMDBTCp,double *BTCUSDp,double *CNYUSDp,uint32_t *pvals) -{ - uint32_t kmdbtc,btcusd,cnyusd; int32_t i,n,nonz,len = 0; - if ( data[0] == 'P' && data[5] == 35 ) - data++; - len += dragon_rwnum(0,&data[len],sizeof(uint32_t),(void *)timestampp); - len += dragon_rwnum(0,&data[len],sizeof(uint32_t),(void *)&n); - if ( n != 35 ) - { - printf("dpow_readprices illegal n.%d\n",n); - return(-1); - } - len += dragon_rwnum(0,&data[len],sizeof(uint32_t),(void *)&kmdbtc); // /= 1000 - len += dragon_rwnum(0,&data[len],sizeof(uint32_t),(void *)&btcusd); // *= 1000 - len += dragon_rwnum(0,&data[len],sizeof(uint32_t),(void *)&cnyusd); - *KMDBTCp = ((double)kmdbtc / (1000000000. * 1000.)); - *BTCUSDp = PAX_BTCUSD(height,btcusd); - *CNYUSDp = ((double)cnyusd / 1000000000.); - for (i=nonz=0; i= 35 ) - { - for (nonz=i=0; i<32; i++) - { - if ( pvals[i] != 0 ) - nonz++; - //printf("%u ",pvals[i]); - } - if ( nonz == 32 ) - { - kmdbtc = pvals[i++]; - btcusd = pvals[i++]; - cnyusd = pvals[i++]; - KMDBTC = ((double)kmdbtc / (1000000000. * 1000.)); - BTCUSD = PAX_BTCUSD(height,btcusd); - CNYUSD = ((double)cnyusd / 1000000000.); - portable_mutex_lock(&hush_mutex); - PVALS = (uint32_t *)realloc(PVALS,(NUM_PRICES+1) * sizeof(*PVALS) * 36); - PVALS[36 * NUM_PRICES] = height; - memcpy(&PVALS[36 * NUM_PRICES + 1],pvals,sizeof(*pvals) * 35); - NUM_PRICES++; - portable_mutex_unlock(&hush_mutex); - if ( 0 ) - printf("OP_RETURN.%d HUSH %.8f BTC %.6f CNY %.6f NUM_PRICES.%d (%llu %llu %llu)\n",height,KMDBTC,BTCUSD,CNYUSD,NUM_PRICES,(long long)kmdbtc,(long long)btcusd,(long long)cnyusd); - } - } } uint64_t komodo_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed) @@ -360,80 +294,6 @@ uint64_t komodo_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed) return(sum); } -uint64_t komodo_paxcalc(int32_t height,uint32_t *pvals,int32_t baseid,int32_t relid,uint64_t basevolume,uint64_t refkmdbtc,uint64_t refbtcusd) -{ - uint32_t pvalb,pvalr; double BTCUSD; uint64_t price,kmdbtc,btcusd,usdvol,baseusd,usdkmd,baserel,ranked[32]; - if ( basevolume > HUSH_PAXMAX ) - { - printf("paxcalc overflow %.8f\n",dstr(basevolume)); - return(0); - } - if ( (pvalb= pvals[baseid]) != 0 ) - { - if ( relid == MAX_CURRENCIES ) - { - if ( height < 236000 ) - { - if ( kmdbtc == 0 ) - kmdbtc = pvals[MAX_CURRENCIES]; - if ( btcusd == 0 ) - btcusd = pvals[MAX_CURRENCIES + 1]; - } - else - { - if ( (kmdbtc= pvals[MAX_CURRENCIES]) == 0 ) - kmdbtc = refkmdbtc; - if ( (btcusd= pvals[MAX_CURRENCIES + 1]) == 0 ) - btcusd = refbtcusd; - } - if ( kmdbtc < 25000000 ) - kmdbtc = 25000000; - if ( pvals[USD] != 0 && kmdbtc != 0 && btcusd != 0 ) - { - baseusd = (((uint64_t)pvalb * 1000000000) / pvals[USD]); - usdvol = komodo_paxvol(basevolume,baseusd); - usdkmd = ((uint64_t)kmdbtc * 1000000000) / btcusd; - if ( height >= 236000-10 ) - { - BTCUSD = PAX_BTCUSD(height,btcusd); - if ( height < BTCFACTOR_HEIGHT || (height < 500000 && BTCUSD > 20000) ) - usdkmd = ((uint64_t)kmdbtc * btcusd) / 1000000000; - else usdkmd = ((uint64_t)kmdbtc * btcusd) / 10000000; - ///if ( height >= BTCFACTOR_HEIGHT && BTCUSD >= 43 ) - // usdkmd = ((uint64_t)kmdbtc * btcusd) / 10000000; - //else usdkmd = ((uint64_t)kmdbtc * btcusd) / 1000000000; - price = ((uint64_t)10000000000 * MINDENOMS[USD] / MINDENOMS[baseid]) / komodo_paxvol(usdvol,usdkmd); - //fprintf(stderr,"ht.%d %.3f kmdbtc.%llu btcusd.%llu base -> USD %llu, usdkmd %llu usdvol %llu -> %llu\n",height,BTCUSD,(long long)kmdbtc,(long long)btcusd,(long long)baseusd,(long long)usdkmd,(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100))); - //fprintf(stderr,"usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)),(long long)price); - //fprintf(stderr,"usdkmd.%llu basevolume.%llu baseusd.%llu paxvol.%llu usdvol.%llu -> %llu\n",(long long)usdkmd,(long long)basevolume,(long long)baseusd,(long long)komodo_paxvol(basevolume,baseusd),(long long)usdvol,(long long)(MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100))); - } else price = (MINDENOMS[USD] * komodo_paxvol(usdvol,usdkmd) / (MINDENOMS[baseid]/100)); - return(price); - } //else printf("zero val in KMD conv %llu %llu %llu\n",(long long)pvals[USD],(long long)kmdbtc,(long long)btcusd); - } - else if ( baseid == relid ) - { - if ( baseid != MAX_CURRENCIES ) - { - pax_rank(ranked,pvals); - //printf("%s M1 percentage %.8f\n",CURRENCIES[baseid],dstr(10 * ranked[baseid])); - return(10 * ranked[baseid]); // scaled percentage of M1 total - } else return(basevolume); - } - else if ( (pvalr= pvals[relid]) != 0 ) - { - baserel = ((uint64_t)pvalb * 1000000000) / pvalr; - //printf("baserel.%lld %lld %lld %.8f %.8f\n",(long long)baserel,(long long)MINDENOMS[baseid],(long long)MINDENOMS[relid],dstr(MINDENOMS[baseid]/MINDENOMS[relid]),dstr(MINDENOMS[relid]/MINDENOMS[baseid])); - if ( MINDENOMS[baseid] > MINDENOMS[relid] ) - basevolume /= (MINDENOMS[baseid] / MINDENOMS[relid]); - else if ( MINDENOMS[baseid] < MINDENOMS[relid] ) - basevolume *= (MINDENOMS[relid] / MINDENOMS[baseid]); - return(komodo_paxvol(basevolume,baserel)); - } - else printf("null pval for %s\n",CURRENCIES[relid]); - } else printf("null pval for %s\n",CURRENCIES[baseid]); - return(0); -} - uint64_t komodo_paxpriceB(uint64_t seed,int32_t height,char *base,char *rel,uint64_t basevolume) { return 0; @@ -451,40 +311,9 @@ int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *bas void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) { - double KMDBTC,BTCUSD,CNYUSD; uint32_t numpvals,timestamp,pvals[128]; uint256 zero; - numpvals = dpow_readprices(height,pricefeed,×tamp,&KMDBTC,&BTCUSD,&CNYUSD,pvals); - memset(&zero,0,sizeof(zero)); - hush_stateupdate(height,0,0,0,zero,0,0,pvals,numpvals,0,0,0,0,0,0,zero,0); - if ( 0 ) - { - int32_t i; - for (i=0; i KMD %.8f seed.%llx\n",height,base,(double)fiatoshis/COIN,(double)komodoshis/COIN,(long long)*seedp); - if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 ) - { - PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis); - bitcoin_address(destaddr,HUSH_PUBTYPE,pubkey33,33); - } - return(komodoshis); + return 0; } From ae9b87740d53fcc14e590dc6e51b2382fe5e2f44 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 3 Sep 2021 12:05:20 -0400 Subject: [PATCH 084/115] Remove broken links --- src/cc/dapps/zmigrate.c | 4 ++-- src/test-hush/test_eval_notarization.cpp | 8 -------- src/wallet/test/wallet_tests.cpp | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index 0e9d08112..fd9e381d5 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -1044,8 +1044,8 @@ int32_t itemvalid(char *refcoin,int64_t *refundedp,int64_t *waitingp,struct clai *refundedp = *waitingp = 0; if ( item->refundvalue < 0 ) return(-1); - // change "kmd" -> %s, tolowerstr(refcoin) - sprintf(url,"https://kmd.explorer.dexstats.info/insight-api-komodo/addr/%s",item->destaddr); + + sprintf(url,"https://explorer.hush.is/api/addr/%s",item->destaddr); if ( (retstr= send_curl(url,"/tmp/itemvalid")) != 0 ) { if ( (curljson= cJSON_Parse(retstr)) != 0 ) diff --git a/src/test-hush/test_eval_notarization.cpp b/src/test-hush/test_eval_notarization.cpp index c0c1c6751..d42327718 100644 --- a/src/test-hush/test_eval_notarization.cpp +++ b/src/test-hush/test_eval_notarization.cpp @@ -3,7 +3,6 @@ // file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #include #include - #include "cc/betprotocol.h" #include "cc/eval.h" #include "base58.h" @@ -14,16 +13,12 @@ #include "primitives/transaction.h" #include "script/interpreter.h" #include "script/serverchecker.h" - #include "testutils.h" - extern int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); - namespace TestEvalNotarization { - class EvalMock : public Eval { public: @@ -86,7 +81,6 @@ namespace TestEvalNotarization { } - // https://kmd.explorer.supernet.org/tx/5b8055d37cff745a404d1ae45e21ffdba62da7b28ed6533c67468d7379b20bae // inputs have been dropped static auto rawNotaryTx = "01000000000290460100000000002321020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9ac0000000000000000506a4c4dae8e0f3e6e5de498a072f5967f3c418c4faba5d56ac8ce17f472d029ef3000008f2e0100424f545300050ba773f0bc31da5839fc7cb9bd7b87f3b765ca608e5cf66785a466659b28880500000000000000"; CTransaction notaryTx; @@ -201,6 +195,4 @@ TEST(TestEvalNotarization, testInvalidNotarizationInputNotCheckSig) ASSERT_FALSE(eval.GetNotarizationData(notary.GetHash(), data)); } - - } /* namespace TestEvalNotarization */ diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 529449ba1..3831aaed4 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet,0)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount - // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) + // run the 'mtgox' test // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change empty_wallet(); for (int i = 0; i < 20; i++) From 3d4123ee88551b1db02c579ccf5f0576f45078cc Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 3 Sep 2021 12:35:59 -0400 Subject: [PATCH 085/115] Cleanup --- src/cc/CC_made_easy.md | 4 +-- src/cc/dapps/dappinc.h | 4 +-- src/cc/dapps/zmigrate.c | 69 +++++++++++++--------------------------- src/hush_curve25519.h | 6 ++-- src/hush_defs.h | 2 +- src/hush_gateway.h | 2 +- src/hush_globals.h | 2 +- src/hush_kv.h | 34 ++++++++++---------- src/hush_structs.h | 2 +- src/rpc/blockchain.cpp | 2 +- src/wallet/rpcwallet.cpp | 28 ++++++++-------- 11 files changed, 65 insertions(+), 90 deletions(-) diff --git a/src/cc/CC_made_easy.md b/src/cc/CC_made_easy.md index daf7cbedd..48ccde25a 100644 --- a/src/cc/CC_made_easy.md +++ b/src/cc/CC_made_easy.md @@ -17,7 +17,7 @@ How to write utxo based CryptoConditions contracts for HUSH chains by jl777 -This is not the only smart contracts methodology that is possible to build on top of OP_CHECKCRYPTOCONDITION, just the first one. All the credit for getting OP_CHECKCRYPTOCONDITION working in the Komodo codebase goes to @libscott. I am just hooking into the code that he made and tried to make it just a little easier to make new contracts. +This is not the only smart contracts methodology that is possible to build on top of OP_CHECKCRYPTOCONDITION, just the first one. All the credit for getting OP_CHECKCRYPTOCONDITION working in the Hush codebase goes to @libscott. I am just hooking into the code that he made and tried to make it just a little easier to make new contracts. There is probably some fancy marketing name to use, but for now, I will just call it "CC contract" for short, knowing that it is not 100% technically accurate as the CryptoConditions aspect is not really the main attribute. However, the HUSH contracts were built to make the CryptoConditions codebase that was integrated into it to be more accessible. @@ -677,7 +677,7 @@ This codebase and tools in between the GUI and the rpc level will be a very good ########## Conclusion -I hope this document has helped you understand what a Komodo utxo based CC contract is and how it is different from the other smart contracts. If you are now able to dive into the cc directory and start making your own CC contract, then I am very happy! +I hope this document has helped you understand what a Hush utxo based CC contract is and how it is different from the other smart contracts. If you are now able to dive into the cc directory and start making your own CC contract, then I am very happy! gateways CC diff --git a/src/cc/dapps/dappinc.h b/src/cc/dapps/dappinc.h index c89658e72..f81db7dd2 100644 --- a/src/cc/dapps/dappinc.h +++ b/src/cc/dapps/dappinc.h @@ -384,7 +384,7 @@ cJSON *hushdex_cli(char *clistr,char **retstrp,char *method,char *arg0,char *arg return(retjson); } -bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson) +bits256 hushbroadcast(char *refcoin,char *acname,cJSON *hexjson) { char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid; memset(txid.bytes,0,sizeof(txid)); @@ -439,7 +439,7 @@ bits256 tokentransfer(char *refcoin,char *acname,char *tokenid,char *destpub,int sprintf(numstr,"%llu",(long long)units); if ( (retjson= get_hushcli(refcoin,&retstr,acname,"tokentransfer",tokenid,destpub,numstr,"","","","")) != 0 ) { - txid = komodobroadcast(refcoin,acname,retjson); + txid = hushbroadcast(refcoin,acname,retjson); fprintf(stderr,"tokentransfer returned (%s)\n",jprint(retjson,0)); free_json(retjson); } diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index fd9e381d5..e8b547c6b 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -316,7 +316,7 @@ cJSON *get_urljson(char *url,char *fname) char *REFCOIN_CLI; -cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3) +cJSON *get_hushcli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3) { long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[256]; sprintf(fname,"/tmp/zmigrate.%s",method); @@ -346,37 +346,12 @@ cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char return(retjson); } -bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson) -{ - char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid; - memset(txid.bytes,0,sizeof(txid)); - if ( (hexstr= jstr(hexjson,"hex")) != 0 ) - { - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","")) != 0 ) - { - //fprintf(stderr,"broadcast.(%s)\n",jprint(retjson,0)); - free_json(retjson); - } - else if ( retstr != 0 ) - { - if ( strlen(retstr) >= 64 ) - { - retstr[64] = 0; - decode_hex(txid.bytes,32,retstr); - } - fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid)); - free(retstr); - } - } - return(txid); -} - bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis) { char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid; memset(txid.bytes,0,sizeof(txid)); sprintf(numstr,"%.8f",(double)satoshis/SATOSHIDEN); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"","")) != 0 ) { fprintf(stderr,"unexpected sendrawtransaction json.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -397,7 +372,7 @@ bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis int32_t get_coinheight(char *refcoin,char *acname) { cJSON *retjson; char *retstr; int32_t height=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockchaininfo","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getblockchaininfo","","","","")) != 0 ) { height = jint(retjson,"blocks"); free_json(retjson); @@ -415,7 +390,7 @@ bits256 get_coinblockhash(char *refcoin,char *acname,int32_t height) cJSON *retjson; char *retstr,heightstr[32]; bits256 hash; memset(hash.bytes,0,sizeof(hash)); sprintf(heightstr,"%d",height); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","")) != 0 ) { fprintf(stderr,"unexpected blockhash json.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -436,7 +411,7 @@ bits256 get_coinmerkleroot(char *refcoin,char *acname,bits256 blockhash) { cJSON *retjson; char *retstr,str[65]; bits256 merkleroot; memset(merkleroot.bytes,0,sizeof(merkleroot)); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","")) != 0 ) { merkleroot = jbits256(retjson,"merkleroot"); //fprintf(stderr,"got merkleroot.(%s)\n",bits256_str(str,merkleroot)); @@ -474,7 +449,7 @@ int32_t get_coinheader(char *refcoin,char *acname,bits256 *blockhashp,bits256 *m cJSON *get_rawmempool(char *refcoin,char *acname) { cJSON *retjson; char *retstr; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getrawmempool","","","","")) != 0 ) { //printf("mempool.(%s)\n",jprint(retjson,0)); return(retjson); @@ -493,7 +468,7 @@ cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) if ( refcoin[0] != 0 && strcmp(refcoin,"HUSH3") != 0 ) printf("warning: assumes %s has addressindex enabled\n",refcoin); sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","")) != 0 ) { //printf("addressutxos.(%s)\n",jprint(retjson,0)); return(retjson); @@ -509,7 +484,7 @@ cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid) { cJSON *retjson; char *retstr,str[65]; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","")) != 0 ) { return(retjson); } @@ -524,7 +499,7 @@ cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid) cJSON *get_listunspent(char *refcoin,char *acname) { cJSON *retjson; char *retstr,str[65]; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"listunspent","","","","")) != 0 ) { return(retjson); } @@ -539,7 +514,7 @@ cJSON *get_listunspent(char *refcoin,char *acname) cJSON *z_listunspent(char *refcoin,char *acname) { cJSON *retjson; char *retstr,str[65]; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listunspent","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_listunspent","","","","")) != 0 ) { return(retjson); } @@ -554,7 +529,7 @@ cJSON *z_listunspent(char *refcoin,char *acname) cJSON *z_listoperationids(char *refcoin,char *acname) { cJSON *retjson; char *retstr,str[65]; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listoperationids","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_listoperationids","","","","")) != 0 ) { return(retjson); } @@ -570,7 +545,7 @@ cJSON *z_getoperationstatus(char *refcoin,char *acname,char *opid) { cJSON *retjson; char *retstr,str[65],params[512]; sprintf(params,"'[\"%s\"]'",opid); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationstatus",params,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_getoperationstatus",params,"","","")) != 0 ) { //printf("got status (%s)\n",jprint(retjson,0)); return(retjson); @@ -587,7 +562,7 @@ cJSON *z_getoperationresult(char *refcoin,char *acname,char *opid) { cJSON *retjson; char *retstr,str[65],params[512]; sprintf(params,"'[\"%s\"]'",opid); - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationresult",params,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_getoperationresult",params,"","","")) != 0 ) { return(retjson); } @@ -602,7 +577,7 @@ cJSON *z_getoperationresult(char *refcoin,char *acname,char *opid) int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare) { cJSON *retjson; char *retstr; int32_t res=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","")) != 0 ) { if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; free_json(retjson); @@ -618,7 +593,7 @@ int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* comp int32_t z_validateaddress(char *refcoin,char *acname,char *depositaddr, char *compare) { cJSON *retjson; char *retstr; int32_t res=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_validateaddress",depositaddr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_validateaddress",depositaddr,"","","")) != 0 ) { if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; @@ -635,7 +610,7 @@ int32_t z_validateaddress(char *refcoin,char *acname,char *depositaddr, char *co int64_t z_getbalance(char *refcoin,char *acname,char *coinaddr) { cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getbalance",coinaddr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_getbalance",coinaddr,"","","")) != 0 ) { fprintf(stderr,"z_getbalance.(%s) %s returned json!\n",refcoin,acname); free_json(retjson); @@ -656,7 +631,7 @@ int32_t z_exportkey(char *privkey,char *refcoin,char *acname,char *zaddr) { cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; privkey[0] = 0; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_exportkey",zaddr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_exportkey",zaddr,"","","")) != 0 ) { fprintf(stderr,"z_exportkey.(%s) %s returned json!\n",refcoin,acname); free_json(retjson); @@ -675,7 +650,7 @@ int32_t z_exportkey(char *privkey,char *refcoin,char *acname,char *zaddr) int32_t getnewaddress(char *coinaddr,char *refcoin,char *acname) { cJSON *retjson; char *retstr; int64_t amount=0; int32_t retval = -1; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getnewaddress","","","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"getnewaddress","","","","")) != 0 ) { fprintf(stderr,"getnewaddress.(%s) %s returned json!\n",refcoin,acname); free_json(retjson); @@ -692,7 +667,7 @@ int32_t getnewaddress(char *coinaddr,char *refcoin,char *acname) int32_t z_getnewaddress(char *coinaddr,char *refcoin,char *acname,char *typestr) { cJSON *retjson; char *retstr; int64_t amount=0; int32_t retval = -1; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getnewaddress",typestr,"","","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"z_getnewaddress",typestr,"","","")) != 0 ) { fprintf(stderr,"z_getnewaddress.(%s) %s returned json!\n",refcoin,acname); free_json(retjson); @@ -764,7 +739,7 @@ int64_t find_sprout_amount(char *coinstr,char *zcaddr) void importaddress(char *refcoin,char *acname,char *depositaddr) { cJSON *retjson; char *retstr; - if ( (retjson= get_komodocli(refcoin,&retstr,acname,"importaddress",depositaddr,"","true","")) != 0 ) + if ( (retjson= get_hushcli(refcoin,&retstr,acname,"importaddress",depositaddr,"","true","")) != 0 ) { printf("importaddress.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -782,7 +757,7 @@ int32_t z_sendmany(char *opidstr,char *coinstr,char *acname,char *srcaddr,char * sprintf(params,"'[{\"address\":\"%s\",\"amount\":%.8f}]'",destaddr,dstr(amount)); sprintf(addr,"\"%s\"",srcaddr); printf("z_sendmany from.(%s) -> %s\n",srcaddr,params); - if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_sendmany",addr,params,"","")) != 0 ) + if ( (retjson= get_hushcli(coinstr,&retstr,acname,"z_sendmany",addr,params,"","")) != 0 ) { printf("unexpected json z_sendmany.(%s)\n",jprint(retjson,0)); free_json(retjson); @@ -801,7 +776,7 @@ int32_t z_mergetoaddress(char *opidstr,char *coinstr,char *acname,char *destaddr { cJSON *retjson; char *retstr,addr[128],*opstr; int32_t retval = -1; sprintf(addr,"[\\\"ANY_SPROUT\\\"]"); - if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_mergetoaddress",addr,destaddr,"","")) != 0 ) + if ( (retjson= get_hushcli(coinstr,&retstr,acname,"z_mergetoaddress",addr,destaddr,"","")) != 0 ) { if ( (opstr= jstr(retjson,"opid")) != 0 ) strcpy(opidstr,opstr); diff --git a/src/hush_curve25519.h b/src/hush_curve25519.h index 5094719e7..688d9cc9b 100644 --- a/src/hush_curve25519.h +++ b/src/hush_curve25519.h @@ -955,14 +955,14 @@ uint64_t conv_NXTpassword(unsigned char *mysecret,unsigned char *mypublic,uint8_ return(addr); } -uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase) +uint256 hush_kvprivkey(uint256 *pubkeyp,char *passphrase) { uint256 privkey; conv_NXTpassword((uint8_t *)&privkey,(uint8_t *)pubkeyp,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); return(privkey); } -uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey) +uint256 hush_kvsig(uint8_t *buf,int32_t len,uint256 _privkey) { bits256 sig,hash,otherpub,checksig,pubkey,privkey; uint256 usig; memcpy(&privkey,&_privkey,sizeof(privkey)); @@ -984,7 +984,7 @@ uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 _privkey) return(usig); } -int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig) +int32_t hush_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig) { bits256 hash,checksig,pubkey; static uint256 zeroes; memcpy(&pubkey,&_pubkey,sizeof(pubkey)); diff --git a/src/hush_defs.h b/src/hush_defs.h index 190dae86c..8fa2024ee 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -539,7 +539,7 @@ int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *bas int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width); -int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); +int32_t hush_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); uint32_t hush_blocktime(uint256 hash); int32_t hush_longestchain(); diff --git a/src/hush_gateway.h b/src/hush_gateway.h index c85755d63..ddaf366a2 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -846,7 +846,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 tokomodo = (hush_is_issuer() == 0); if ( opretbuf[0] == 'K' && opretlen != 40 ) { - komodo_kvupdate(opretbuf,opretlen,value); + hush_kvupdate(opretbuf,opretlen,value); return("kv"); } else if ( SMART_CHAIN_SYMBOL[0] == 0 && HUSH_PAX == 0 ) diff --git a/src/hush_globals.h b/src/hush_globals.h index c298d8c15..12f4f7f65 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -103,7 +103,7 @@ int32_t HUSH_TESTNODE, HUSH_SNAPSHOT_INTERVAL; CScript HUSH_EARLYTXID_SCRIPTPUB; int32_t ASSETCHAINS_EARLYTXIDCONTRACT; std::map mapHeightEvalActivate; -struct komodo_kv *HUSH_KV; +struct hush_kv *HUSH_KV; pthread_mutex_t HUSH_KV_mutex,HUSH_CC_mutex; #define MAX_CURRENCIES 32 diff --git a/src/hush_kv.h b/src/hush_kv.h index b64522f36..9149c9ec4 100644 --- a/src/hush_kv.h +++ b/src/hush_kv.h @@ -21,7 +21,7 @@ #include "hush_defs.h" -int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize) +int32_t hush_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize) { if ( refvalue == 0 && value == 0 ) return(0); @@ -32,7 +32,7 @@ int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint else return(memcmp(refvalue,value,valuesize)); } -int32_t komodo_kvnumdays(uint32_t flags) +int32_t hush_kvnumdays(uint32_t flags) { int32_t numdays; if ( (numdays= ((flags>>2)&0x3ff)+1) > 365 ) @@ -40,25 +40,25 @@ int32_t komodo_kvnumdays(uint32_t flags) return(numdays); } -int32_t komodo_kvduration(uint32_t flags) +int32_t hush_kvduration(uint32_t flags) { - return(komodo_kvnumdays(flags) * HUSH_KVDURATION); + return(hush_kvnumdays(flags) * HUSH_KVDURATION); } -uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen) +uint64_t hush_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen) { int32_t numdays,k; uint64_t fee; if ( (k= keylen) > 32 ) k = 32; - numdays = komodo_kvnumdays(flags); + numdays = hush_kvnumdays(flags); if ( (fee= (numdays*(opretlen * opretlen / k))) < 100000 ) fee = 100000; return(fee); } -int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen) +int32_t hush_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen) { - struct komodo_kv *ptr; int32_t duration,retval = -1; + struct hush_kv *ptr; int32_t duration,retval = -1; *heightp = -1; *flagsp = 0; memset(pubkeyp,0,sizeof(*pubkeyp)); @@ -66,7 +66,7 @@ int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp HASH_FIND(hh,HUSH_KV,key,keylen,ptr); if ( ptr != 0 ) { - duration = komodo_kvduration(ptr->flags); + duration = hush_kvduration(ptr->flags); //fprintf(stderr,"duration.%d flags.%d current.%d ht.%d keylen.%d valuesize.%d\n",duration,ptr->flags,current_height,ptr->height,ptr->keylen,ptr->valuesize); if ( current_height > (ptr->height + duration) ) { @@ -100,10 +100,10 @@ int32_t komodo_kvsearch(uint256 *pubkeyp,int32_t current_height,uint32_t *flagsp return(retval); } -void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) +void hush_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) { static uint256 zeroes; - uint32_t flags; uint256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[DRAGON_MAXSCRIPTSIZE*8]; struct komodo_kv *ptr; char *transferpubstr,*tstr; uint64_t fee; + uint32_t flags; uint256 pubkey,refpubkey,sig; int32_t i,refvaluesize,hassig,coresize,haspubkey,height,kvheight; uint16_t keylen,valuesize,newflag = 0; uint8_t *key,*valueptr,keyvalue[DRAGON_MAXSCRIPTSIZE*8]; struct hush_kv *ptr; char *transferpubstr,*tstr; uint64_t fee; if ( SMART_CHAIN_SYMBOL[0] == 0 ) // disable KV return; dragon_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); @@ -115,11 +115,11 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) { static uint32_t counter; if ( ++counter < 1 ) - fprintf(stderr,"komodo_kvupdate: keylen.%d + 13 > opretlen.%d, this can be ignored\n",keylen,opretlen); + fprintf(stderr,"hush_kvupdate: keylen.%d + 13 > opretlen.%d, this can be ignored\n",keylen,opretlen); return; } valueptr = &key[keylen]; - fee = komodo_kvfee(flags,opretlen,keylen); + fee = hush_kvfee(flags,opretlen,keylen); //fprintf(stderr,"fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]); if ( value >= fee ) { @@ -139,13 +139,13 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(uint256)+i]; } memcpy(keyvalue,key,keylen); - if ( (refvaluesize= komodo_kvsearch((uint256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) + if ( (refvaluesize= hush_kvsearch((uint256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) { if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) { - if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) + if ( hush_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) { - //fprintf(stderr,"komodo_kvsigverify error [%d]\n",coresize-13); + //fprintf(stderr,"hush_kvsigverify error [%d]\n",coresize-13); return; } } @@ -169,7 +169,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) } else if ( ptr == 0 ) { - ptr = (struct komodo_kv *)calloc(1,sizeof(*ptr)); + ptr = (struct hush_kv *)calloc(1,sizeof(*ptr)); ptr->key = (uint8_t *)calloc(1,keylen); ptr->keylen = keylen; memcpy(ptr->key,key,keylen); diff --git a/src/hush_structs.h b/src/hush_structs.h index fde010d7b..3ba56fefc 100644 --- a/src/hush_structs.h +++ b/src/hush_structs.h @@ -56,7 +56,7 @@ union _bits320 { uint8_t bytes[40]; uint16_t ushorts[20]; uint32_t uints[10]; uint64_t ulongs[5]; uint64_t txid; }; typedef union _bits320 bits320; -struct komodo_kv { UT_hash_handle hh; bits256 pubkey; uint8_t *key,*value; int32_t height; uint32_t flags; uint16_t keylen,valuesize; }; +struct hush_kv { UT_hash_handle hh; bits256 pubkey; uint8_t *key,*value; int32_t height; uint32_t flags; uint16_t keylen,valuesize; }; struct hush_event_notarized { uint256 blockhash,desttxid,MoM; int32_t notarizedheight,MoMdepth; char dest[16]; }; struct hush_event_pubkeys { uint8_t num; uint8_t pubkeys[64][33]; }; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 82f73036c..bf38cc5e2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -893,7 +893,7 @@ UniValue kvsearch(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( keylen < sizeof(key) ) { memcpy(key,params[0].get_str().c_str(),keylen); - if ( (valuesize= komodo_kvsearch(&refpubkey,chainActive.LastTip()->GetHeight(),&flags,&height,value,key,keylen)) >= 0 ) + if ( (valuesize= hush_kvsearch(&refpubkey,chainActive.LastTip()->GetHeight(),&flags,&height,value,key,keylen)) >= 0 ) { std::string val; char *valuestr; val.resize(valuesize); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 38546dcea..f7cc48433 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -616,19 +616,19 @@ int32_t hush_is_issuer(); int32_t dragon_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); int32_t hush_isrealtime(int32_t *kmdheightp); int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); -int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); -int32_t komodo_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); -uint64_t komodo_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen); -uint256 komodo_kvsig(uint8_t *buf,int32_t len,uint256 privkey); -int32_t komodo_kvduration(uint32_t flags); -uint256 komodo_kvprivkey(uint256 *pubkeyp,char *passphrase); -int32_t komodo_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig); +int32_t hush_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); +int32_t hush_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); +uint64_t hush_kvfee(uint32_t flags,int32_t opretlen,int32_t keylen); +uint256 hush_kvsig(uint8_t *buf,int32_t len,uint256 privkey); +int32_t hush_kvduration(uint32_t flags); +uint256 hush_kvprivkey(uint256 *pubkeyp,char *passphrase); +int32_t hush_kvsigverify(uint8_t *buf,int32_t len,uint256 _pubkey,uint256 sig); UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) { static uint256 zeroes; CWalletTx wtx; UniValue ret(UniValue::VOBJ); - uint8_t keyvalue[DRAGON_MAXSCRIPTSIZE*8],opretbuf[DRAGON_MAXSCRIPTSIZE*8]; int32_t i,coresize,haveprivkey,duration,opretlen,height; uint16_t keylen=0,valuesize=0,refvaluesize=0; uint8_t *key,*value=0; uint32_t flags,tmpflags,n; struct komodo_kv *ptr; uint64_t fee; uint256 privkey,pubkey,refpubkey,sig; + uint8_t keyvalue[DRAGON_MAXSCRIPTSIZE*8],opretbuf[DRAGON_MAXSCRIPTSIZE*8]; int32_t i,coresize,haveprivkey,duration,opretlen,height; uint16_t keylen=0,valuesize=0,refvaluesize=0; uint8_t *key,*value=0; uint32_t flags,tmpflags,n; struct hush_kv *ptr; uint64_t fee; uint256 privkey,pubkey,refpubkey,sig; if (fHelp || params.size() < 3 ) throw runtime_error( "kvupdate key \"value\" days passphrase\n" @@ -670,7 +670,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) //printf("flags.%d (%s) n.%d\n",flags,params[2].get_str().c_str(),n); } else flags = 0; if ( n >= 4 ) - privkey = komodo_kvprivkey(&pubkey,(char *)(n >= 4 ? params[3].get_str().c_str() : "password")); + privkey = hush_kvprivkey(&pubkey,(char *)(n >= 4 ? params[3].get_str().c_str() : "password")); haveprivkey = 1; flags |= 1; /*for (i=0; i<32; i++) @@ -690,7 +690,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) valuesize = (int32_t)strlen(params[1].get_str().c_str()); } memcpy(keyvalue,key,keylen); - if ( (refvaluesize= komodo_kvsearch(&refpubkey,chainActive.LastTip()->GetHeight(),&tmpflags,&height,&keyvalue[keylen],key,keylen)) >= 0 ) + if ( (refvaluesize= hush_kvsearch(&refpubkey,chainActive.LastTip()->GetHeight(),&tmpflags,&height,&keyvalue[keylen],key,keylen)) >= 0 ) { if ( (tmpflags & HUSH_KVPROTECTED) != 0 ) { @@ -702,8 +702,8 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) } if ( keylen+refvaluesize <= sizeof(keyvalue) ) { - sig = komodo_kvsig(keyvalue,keylen+refvaluesize,privkey); - if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) + sig = hush_kvsig(keyvalue,keylen+refvaluesize,privkey); + if ( hush_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) { ret.push_back(Pair("error",(char *)"error verifying sig, passphrase is probably wrong")); printf("VERIFY ERROR\n"); @@ -719,7 +719,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) ret.push_back(Pair("owner",refpubkey.GetHex())); ret.push_back(Pair("height", (int64_t)height)); - duration = komodo_kvduration(flags); //((flags >> 2) + 1) * HUSH_KVDURATION; + duration = hush_kvduration(flags); //((flags >> 2) + 1) * HUSH_KVDURATION; ret.push_back(Pair("expiration", (int64_t)(height+duration))); ret.push_back(Pair("flags",(int64_t)flags)); ret.push_back(Pair("key",params[0].get_str())); @@ -755,7 +755,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) // printf("%02x",opretbuf[i]); //printf(" opretbuf keylen.%d valuesize.%d height.%d (%02x %02x %02x)\n",*(uint16_t *)&keyvalue[0],*(uint16_t *)&keyvalue[2],*(uint32_t *)&keyvalue[4],keyvalue[8],keyvalue[9],keyvalue[10]); EnsureWalletIsUnlocked(); - fee = komodo_kvfee(flags,opretlen,keylen); + fee = hush_kvfee(flags,opretlen,keylen); ret.push_back(Pair("fee",(double)fee/COIN)); CBitcoinAddress destaddress(CRYPTO555_HUSHADDR); if (!destaddress.IsValid()) From f19c70bfa65b91d41d4ea1da1778d08bada73232 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 9 Sep 2021 12:36:59 -0400 Subject: [PATCH 086/115] Add missing newline to rescan log line --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bab6fa5c1..4217e3825 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2738,7 +2738,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) // Build initial witness caches for blocks involving one of our addresses if (involvesMe) { - LogPrintf("%s: block has one of our transactions, building witness cache", __func__); + LogPrintf("%s: block has one of our transactions, building witness cache\n", __func__); BuildWitnessCache(pindex, true); } From 977e93cbaac1eda244f937200bc8e4852ccfc25a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 13 Sep 2021 13:12:37 -0400 Subject: [PATCH 087/115] Get rid of wolfssl warning about timing resistance --- src/wallet/crypter.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 17519c0ca..ff0da14d6 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -2,7 +2,6 @@ // Copyright (c) 2016-2021 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 © 2014-2019 The SuperNET Developers. * * * @@ -17,17 +16,21 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - #include "crypter.h" - #include "script/script.h" #include "script/standard.h" #include "streams.h" #include "util.h" - #include #include #include +// TODO: these are not set correctly by wolfssl for some reason. Ja bless. +#undef ECC_TIMING_RESISTANT +#undef TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT 420 +#define TFM_TIMING_RESISTANT 420 +#undef WC_RSA_BLINDING +#define WC_RSA_BLINDING #include #include From 49713d8a0441d233998ea763576dec42a1bd89c0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Sep 2021 16:00:08 -0400 Subject: [PATCH 088/115] Various things --- src/hush_bitcoind.h | 10 +++--- src/hush_defs.h | 75 ++++++++++++++++++++++++++++++++++++++++-- src/hush_globals.h | 2 +- src/hush_notary.h | 24 +++++++++++--- src/main.cpp | 3 +- src/rpc/crosschain.cpp | 45 +++++++------------------ src/rpc/server.cpp | 4 ++- 7 files changed, 114 insertions(+), 49 deletions(-) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index bf53316db..e2b4e9fa7 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -868,18 +868,18 @@ int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width) return(nonz); } -int32_t hush_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) +int32_t hush_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { - int32_t depth,notarized_ht; uint256 MoM,kmdtxid; - depth = hush_MoMdata(¬arized_ht,&MoM,&kmdtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,kmdstartip,kmdendip); + int32_t depth,notarized_ht; uint256 MoM,hushtxid; + depth = hush_MoMdata(¬arized_ht,&MoM,&hushtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,kmdstartip,kmdendip); memset(MoMp,0,sizeof(*MoMp)); - memset(kmdtxidp,0,sizeof(*kmdtxidp)); + memset(hushtxidp,0,sizeof(*hushtxidp)); *notarized_heightp = 0; if ( depth != 0 && notarized_ht > 0 && nHeight > notarized_ht-depth && nHeight <= notarized_ht ) { *MoMp = MoM; *notarized_heightp = notarized_ht; - *kmdtxidp = kmdtxid; + *hushtxidp = hushtxid; } return(depth); } diff --git a/src/hush_defs.h b/src/hush_defs.h index 8fa2024ee..c88abe9d6 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -53,13 +53,15 @@ const uint32_t nHushHardforkHeight = 166250; const uint32_t nHushHardforkHeight2 = 245055; // This height begins Hush DPoW from Hush notaries -const uint32_t nHushHardforkHeight3 = 340420; - -// No coins/code are currently using timestamp activated fork +const uint32_t nHushHardforkHeight3 = 340420; const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT +// Used by HSCs static const uint32_t HUSH_SEASON_TIMESTAMPS[NUM_HUSH_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5, nHushHardforkTimestamp2*6, nHushHardforkTimestamp2*7}; + +// Used by HUSH3+TUSH +// Block 1702100 = nHushHardforkHeight3*5 static const int32_t HUSH_SEASON_HEIGHTS[NUM_HUSH_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)340000, nHushHardforkHeight3, nHushHardforkHeight3*5}; // Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. @@ -472,6 +474,73 @@ static const char *notaries_elected[NUM_HUSH_SEASONS][NUM_HUSH_NOTARIES][2] = {"RAJWHL6MzGFKg7KB2sZ87KPQUSvxy3VrEW", "0389971362b002ab5dfa1b5f9c4f88e68249511a3935242ba1e0d31c1c88a36d70"}, {"RU592tQnbH8gt6xd5Uu23nEw3SucDNkXmK", "02b8b6a2266fe57b25f2d4b1da93a07d27930154e78f9d137bc7509cf1ae8e3d49"}, {"RLGCLRzaEmruPC9UmVt5qRHEhXwHip1e6d", "02a2fd96b4459411ad2b09597ba59cf52b282c56330da7c0cc6d2a5c0323a18f1e"} + }, + { + // season 7 + {"RFetqf8WUfWnwNeXdknkm8ojk7EXnYFzrv", "038a1bd41a08f38edda51042988022933c5775dfce81f7bae0b32a9179650352ac"}, + {"RV7YSVW89WC9jBDtFG4ubtopDRove4Tfvc", "03c9d35488be73fe4f2dbb1dc011468482d71bac32249f8cce6480bcc574415d19"}, + {"RBPFE9oXceZBWTn3Vhne4FUKE9vxGEXUKX", "028a8bb6ded2692b39a69ec2d3c9836ff221815909d5cd65257374aeb66394a002"}, + {"RM3cvUcafPhjyypZLEginQjdhjLnSgJHte", "03a36180014115b47b97c1c8776a269bba66047b1ce2c7eb1a3d4e995a6dfff0df"}, + {"RFFX1VaTmZYPBLCzFj7w3iJQArV9ZdaWcW", "02190865f3ca3678d322c96e49a3ddf8ad394a4c8cd97d4bb3376cf547d0d83c66"}, + {"RDwZsLpH1QiAbJwUEY8ajXwTzu3PaWhx7n", "023ea0babb34e1ff9f4db8131ee84ad8991b954038a1e6ef9afc2a1b3fa13bbcb9"}, + {"RCUvfnmt16ZMvLTmLGGAztcAE8fBjfbP6u", "0379a5ba9fb6b463ffcdc0b1f3ecf45a5b737275354f9c2598492f20660f6f7dfd"}, + {"RBLu9adNVMVf6jzLLbAenWovcwq8nU6gYd", "022cd69381231d69d6d3b9638762df849bc7bbab71cbb8383eec29ca677f1afa30"}, + {"RWfv6wd2fwgecnJxC1Ykpf1SJefGh2Wc6i", "03da8a8f57d88afb61f712a8cd35462b65ce2b2575db8f9ee33a725dcd12c44755"}, + {"RWiK4xooG3dPdvaovu6JvR3DWoYD4tfRjx", "02ffe66af4d71345fe6984b5002ad69206e1817566a70d9ac406a679be6a3335a0"}, + {"RYLNiJiRnEGeMxx1Q2xLoFujshRNkBa2x4", "028ef6501004569c1170ce2d7ec7ecfe5739001130ad1b39129f8b88cd3d610257"}, + {"RTw36Ksy5Wk1Xv3B53T79zoRd6XDsE9MS6", "02d7cf4ece00895ca857fcdd0a4c2fc9c949a518d2750396f77d9f031c08a94364"}, + {"RTPkUBriQzZy67WmFhEs6aQzJn5HBB3ntb", "03319ca1eae5888c45115d160ac07c4f2abd1720926aa579d535c4b46c807bb7f7"}, + {"RBmZzttvDnMaEv47cWXs8SgdC993djB68r", "034302c4e1ff72a5f5391f259f7a46e646c7845aa2c9de9fb0c0a4c4802aad79d6"}, + {"RGocb2jLCa2E9kVHDUsijrVGTDP82ngGYZ", "024440a18a16e38b836b3ad9bb54ab0b5ba83b04edebb58c62c09b2de29e9fc703"}, + {"RVqwCjPQ6AJ6r9WeGzQvAT4eGXDScprLkW", "028a94e53ad8ed9e78f0f8a87cf3bc4754784222ad7ddf2d3dc5fafec2f6891cde"}, + {"RB2Xc8eLrATRWVsxrZKHHx3hyJz1vugMt9", "02eca07a9b5810fe929a87f90e5f02e29a06479d39cd3a888abfa1793e1565155a"}, + {"RKm7WUuFfqCTiUBkbxBsdh54nT6ivXpDPX", "03e3f634671005c8ffb7fe883fcf9e08f6f5486df057f215d761741d91c88de898"}, + {"RLbHTvFQoz946W3o3gXTrjxxADeUsWWW16", "02e6bb6dcecf5e3abfe239dec55842a92f096eeac7f0ff7621c3e8948e5e789b27"}, + {"RD75njr2RLGC5PqjHbWwuL7ndTqZiUfYxs", "0250d9996c25a34cb1b4e86303a297fc5c49c65615eb31a57fb17d1e1b376e71be"}, + {"RT1VTzZYZLWUsPWFJ2oypEqB1MXMfq8b5Y", "02d1797941b7df42a98f59ede0f22294e7c02754232a8b1de9512ededaf3f82880"}, + {"RKeXriTVXioHeKpFTjC8Cjohd6DHGUcKqt", "0341e62f0cdffc4ba3e0efb793c0fcaaad1b611db7021b844f643d5c25847733d2"}, + {"RQYrDEgZPKMFAgTHNkWFeMHEmpkXe8j28T", "02b8719cd8484755990158cbdf7b9d990d4a5c3741cabe204e51ed04be5bd50133"}, + {"RE85TACcn8CEn26itAxQV9afxV9mVg17vm", "0367f569d3dc304e699196fe9b798671fe3f12df7851a0a474879b0dbf8bc508d1"}, + {"RPYWQJXto1aeCGe8T6g9Wo4tAL4xE82LJ8", "02cf1e245dfb44e418fd550abb825a600e1753d46a51995970e70c98be539da33e"}, + {"RSVHRS5wqEw7bxfuE9k6xJGbARcy5guisp", "03ab8ac83d689ce76b5d29a54c3b34d0a6cb37d64313ff4467c744787475969a23"}, + {"REAQwBaJFo6DyBkwfW7rTTDbUtkdmATcQ8", "025e80f0075514cc5940de85c0c559efa99a3688faf6cccb8c1d1f38b96ca91e71"}, + {"RF1gz8QBw5uFScGasqVxoUjQwJCD9zHJwC", "031cdae4b545e5049ccee8e0cb792e25795b56e08b5e64b1d972c9b94e9bfd4ed0"}, + {"RTnLGoWzpsyoGSViGH8GyYcYhSveSEmnPV", "03cf3403a9d1cefa83e07b73e618a7f991d140a8283a02df3ce7c00223f27f43d0"}, + {"RArURqxp6qfF7fqv38tCYr6p4zBtLtqf4x", "026bc4c91c2c35fabe88fea6470d6cda98977a97c251656adf25b81653c00c3800"}, + {"RN8GCryShNFvBWtcNEWrQJ5A9AWb3JJoXt", "02afa94f6574cd0fe4f5dc83b09a2112457862421ce96bdc75c1cf25ef5b1f8c4b"}, + {"RQSC2eBckcFPWzq9UtofePC31wgDySfJtw", "035d570768d844c8150a3bd966a2e13aa99316f4ab3e80370c4d16fb02f95d0974"}, + {"RC4uQsfH6jXpgnTFuFiDwAFo58gHLNkWo7", "02402b0ab7001fd4bcb4fa0d8d7006a6c521b1c76e85aad7b374ecd6c5d564c237"}, + {"RREcuaUWSkNzTNPBbFLbXKTKiC4fd5t47J", "03d5bf8b43c44ba064e897da47dd36dba537bebf013d28247ce7a088496dd9b66d"}, + {"REFyC5e7kmse3PUapDuXHL2xmtYEGttYYL", "035f56fd01dd21725928bbd878b795dccafecc03b978dc83748e9194dcbfebfb79"}, + {"RH1BLwZosLp2hv9msdZGdSu93K8GrMWw7D", "0224ab22ece88f624f80a8535b8d5194646ad6be749070ec188a22c5e29fdd7098"}, + {"RNkhugMQVbqDysSayHu2eAhTQpXzKWqZ3m", "02caab4c83c8cc245a7aeb6d25504363555d1b0874aef0f9f8116b4ddb61f24799"}, + {"RKiyhLELDJATA7ZCUcutkP1WCEHnAgZRZ8", "028c01859a700ed3941a5786cf2043992e17a45c6689ac4bf608ad3f19e6d0e832"}, + {"RLKARvLNo6Abkh5qh5NVn2HJmYfj8ELa6A", "0300a33629da90b9d3c0519d796f4b1278355bb8c46e4caee04b1305e2ab2ff3f2"}, + {"RACX21FKLenyyEf8SYK3LmjsDzkDthwUbR", "0205d73c6a3e969eff29e5f424c861d22544245e09eaafc3fefe021cad052b7c0b"}, + {"RETb7pEDauKBEuTBuXDhKS3ksd2p8x9KYa", "025c1f7596fd0b7286e6ebd1b3c275a14a13aa4d134db4677769324969b7b7e3a5"}, + {"RJrAo78TL6zUmiHXbBv8oRhfGKxGnPnxUu", "02d40a76fbab96a78898b7579626be6dfe360c63b91030e513f849f212d57c1af6"}, + {"RL8g6ANxhZBPHHHWgApaiSQ2BSP9qKwuwf", "020236a5748ea49da891276bcb85dc03487cb9f3d0c2b2cdb35227b6a624f86797"}, + {"RY3vwBjuuTCiYL5am9HmwbdCjffWd9f4CE", "032f61fd08957d9b88dabc077d8732bef6c30d0234c14e02f3a741116834f591dc"}, + {"RQW4LsSzjCPtNw1HGamSaCoiirvsrZmDY5", "02e29451f9baf0186a655396726a22a20617a3e54ea895590f6066abc993f83d32"}, + {"RJtjorxqhazz39UpFdhDW8MiW4E3jhXDNk", "03795b7a650db872c22f13a9c88ad5c1ad3cb07a349f1f29e9789efd27e151164b"}, + {"RSi8AiCCtS3doFupdpdfuorAhkrCS6mLMu", "037a62ff6b7eb2ba1e170b5c42e7788817ded6a3a7ed841321c01cc107aa647d42"}, + {"RMjMXC8m9PgAaMMvwqgLCyCrv47pp6F6XY", "033bdf151c01bc733e614f9d4f204ca44396bf56984df6643205d349a35f7b265d"}, + {"RYB3ZMgHt4h7YL8TUzpqaSDw22ABksAPGC", "021266e045f95322fceddae02877dca9721792bef8f2be28cacd7c36290cd813a7"}, + {"RGwy64PXswUKpiepfzgaRW98v3gsuqPtow", "03008783c34c2622e7167f0a5201846133e530e89dfe1a8fbcf4c29b33051c4565"}, + {"RKJRPLaQV4AkWF6EfUUzFwawTGU4RQZgcS", "03c20a9fd21de76a20ffc87e384be735dfabb7f34a2d881ca9714830fb1bbe6bdb"}, + {"RQ4SPvBKTEKyV6y31iSihtfMxi3KeyAJgV", "033c5a23c75d946c15c15fac1e6d78e08c2b656549a158627cfb6bc44bb7b3a560"}, + {"RTvRBC1pCQpPKrS27Q4hUCVKVpa5tSTsFS", "02c25672fae388a0613d0127fcfe38ef37f5f354ecfdea0fb734528e354319bd9d"}, + {"RKxWu9HpCg7m3UeUGw2Xs1SpFiR96fSCQj", "02ec760d09b369b82b34d864af5a468d8a7dc5609b06bce455d045d1059c4b0f71"}, + {"RBAaUWAD8jwVLL7ueb7ciAQewqgheKxwdk", "0274ec3abcca214cdf7f1a565f5f3d3fa910e62e751a1ab0de148ea14ba72d6ba7"}, + {"RT853SBEGt4EWrKbpSujya69DG1jSNYjob", "02e80260ca44b8539159e6af678cf5ed0bc596753e4985f66418d6417085b4104e"}, + {"RKjEuhVByPwJcZ9wuBgfELiCVnBrc4F8i4", "0357c38f5d5eb1662a54b980c9243ddd8b2100d4b2b9f8175246938ef76e100678"}, + {"RT6wVuFFPU5tY6C7Buup1GLV3SE5mpYEha", "02571085ead1aca86b9e90fa9a23d99a194c862524b0c714102888be5bf122dc7d"}, + {"RSTgcpV82AivrvWJpd4LR2KwWirwbwXE3Y", "021a0ee4611ca4d8a2e209cc43b95036deb0a9d1cc31fc9f87d50233a44f05ec1a"}, + {"RCiaXRzo4AAG3zmPL3Hx63NsRWv5UGiNuM", "02f4876be65c54613e47f7fac67f1453e8d8fde5e19fa53f278a1083a08b258ab3"}, + {"RCGgLWrTTaqBhUsS1BqrmFpJZAdNJMzscv", "02893d2db5329b15a33aa7edfbf323c85cabbdc25caa6cf6186fac6052ae6d96a0"}, + {"RAJWHL6MzGFKg7KB2sZ87KPQUSvxy3VrEW", "0389971362b002ab5dfa1b5f9c4f88e68249511a3935242ba1e0d31c1c88a36d70"}, + {"RU592tQnbH8gt6xd5Uu23nEw3SucDNkXmK", "02b8b6a2266fe57b25f2d4b1da93a07d27930154e78f9d137bc7509cf1ae8e3d49"}, + {"RLGCLRzaEmruPC9UmVt5qRHEhXwHip1e6d", "02a2fd96b4459411ad2b09597ba59cf52b282c56330da7c0cc6d2a5c0323a18f1e"} } }; diff --git a/src/hush_globals.h b/src/hush_globals.h index 12f4f7f65..605d78021 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -21,7 +21,7 @@ void hush_prefetch(FILE *fp); uint32_t hush_heightstamp(int32_t height); void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void hush_init(int32_t height); -int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port); void hush_init(int32_t height); diff --git a/src/hush_notary.h b/src/hush_notary.h index 610407df3..a8f792f8f 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -62,6 +62,19 @@ const char *Notaries_genesis[][2] = int32_t gethushseason(int32_t height) { + bool istush = strncmp(SMART_CHAIN_SYMBOL, "TUSH",4) == 0 ? true : false; + if ( istush ) { + // TUSH is always Season 7 DPoW notaries from genblock + return 7; + } + + // It is season 7 until a new consensus code change, instead + // of the old way, which requires a new code release before + // the last season block height or nodes stop working correctly + if ( height > nHushHardforkHeight3 ) { + return 7; + } + if ( height <= HUSH_SEASON_HEIGHTS[0] ) return(1); for (int32_t i = 1; i < NUM_HUSH_SEASONS; i++) @@ -89,6 +102,7 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) int32_t i,htind,n; uint64_t mask = 0; struct knotary_entry *kp,*tmp; static uint8_t hush_pubkeys[NUM_HUSH_SEASONS][64][33],didinit[NUM_HUSH_SEASONS]; + //HUSH3+TUSH use block heights, HSCs use timestamps if ( timestamp == 0 && SMART_CHAIN_SYMBOL[0] != 0 ) { timestamp = hush_heightstamp(height); } else if ( SMART_CHAIN_SYMBOL[0] == 0 ) { @@ -98,7 +112,9 @@ int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) // Find the correct DPoW Notary pubkeys for this season int32_t hush_season = 0; bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; - hush_season = ishush3 ? gethushseason(height) : getacseason(timestamp); + bool istush = strncmp(SMART_CHAIN_SYMBOL, "TUSH",4) == 0 ? true : false; + // TUSH uses height activation like HUSH3, other HSCs use timestamps + hush_season = (ishush3 || istush) ? gethushseason(height) : getacseason(timestamp); if(IS_HUSH_NOTARY) { fprintf(stderr,"%s: [%s] season=%d height=%d time=%d\n", __func__, ishush3 ? "HUSH3" : SMART_CHAIN_SYMBOL, hush_season, height, timestamp); @@ -323,14 +339,14 @@ int32_t hush_dpowconfs(int32_t txheight,int32_t numconfs) return(numconfs); } -int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) +int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { struct notarized_checkpoint *np = 0; if ( (np= komodo_npptr(height)) != 0 ) { *notarized_htp = np->notarized_height; *MoMp = np->MoM; - *kmdtxidp = np->notarized_desttxid; + *hushtxidp = np->notarized_desttxid; *MoMoMp = np->MoMoM; *MoMoMoffsetp = np->MoMoMoffset; *MoMoMdepthp = np->MoMoMdepth; @@ -341,7 +357,7 @@ int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int3 *notarized_htp = *MoMoMoffsetp = *MoMoMdepthp = *kmdstartip = *kmdendip = 0; memset(MoMp,0,sizeof(*MoMp)); memset(MoMoMp,0,sizeof(*MoMoMp)); - memset(kmdtxidp,0,sizeof(*kmdtxidp)); + memset(hushtxidp,0,sizeof(*hushtxidp)); return(0); } diff --git a/src/main.cpp b/src/main.cpp index 0771ffdb5..eabed2626 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1455,8 +1455,9 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState // This is used only in RPC currently but hush_notaries()/gethushseason/getacseason is consensus int32_t hush_isnotaryvout(char *coinaddr,uint32_t tiptime) { bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false; + bool istush = strncmp(SMART_CHAIN_SYMBOL, "TUSH",4) == 0 ? true : false; int32_t height = chainActive.LastTip()->GetHeight(); - int32_t season = ishush3 ? gethushseason(height) : getacseason(tiptime); + int32_t season = (ishush3 || istush) ? gethushseason(height) : getacseason(tiptime); fprintf(stderr,"%s: season=%d, tiptime=%d\n", __func__, season,tiptime); if ( NOTARY_ADDRESSES[season-1][0][0] == 0 ) { uint8_t pubkeys[64][33]; diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 45140138b..375bbfbd5 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -56,7 +56,7 @@ int32_t ensure_CCrequirements(uint8_t evalcode); bool EnsureWalletIsAvailable(bool avoidException); -int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); uint256 hush_calcMoM(int32_t height,int32_t MoMdepth); @@ -71,7 +71,7 @@ UniValue assetchainproof(const UniValue& params, bool fHelp, const CPubKey& mypk { uint256 hash; - // parse params and get notarisation data for tx + // parse params and get notarization data for tx if ( fHelp || params.size() != 1) throw runtime_error("assetchainproof needs a txid"); @@ -93,7 +93,7 @@ UniValue crosschainproof(const UniValue& params, bool fHelp, const CPubKey& mypk UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) { - int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); + int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,hushtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); if ( fHelp || params.size() != 1 ) throw runtime_error("height_MoM height\n"); LOCK(cs_main); @@ -108,7 +108,7 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) height = chainActive.Tip()->GetHeight(); } //fprintf(stderr,"height_MoM height.%d\n",height); - depth = hush_MoM(¬arized_height,&MoM,&kmdtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi); + depth = hush_MoM(¬arized_height,&MoM,&hushtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi); ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH" : SMART_CHAIN_SYMBOL))); ret.push_back(Pair("height",height)); ret.push_back(Pair("timestamp",(uint64_t)timestamp)); @@ -117,7 +117,7 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) ret.push_back(Pair("depth",depth)); ret.push_back(Pair("notarized_height",notarized_height)); ret.push_back(Pair("MoM",MoM.GetHex())); - ret.push_back(Pair("kmdtxid",kmdtxid.GetHex())); + ret.push_back(Pair("hushtxid",hushtxid.GetHex())); if ( SMART_CHAIN_SYMBOL[0] != 0 ) { ret.push_back(Pair("MoMoM",MoMoM.GetHex())); @@ -134,18 +134,18 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) UniValue MoMoMdata(const UniValue& params, bool fHelp, const CPubKey& mypk) { if ( fHelp || params.size() != 3 ) - throw runtime_error("MoMoMdata symbol kmdheight ccid\n"); + throw runtime_error("MoMoMdata symbol hushheight ccid\n"); UniValue ret(UniValue::VOBJ); char* symbol = (char *)params[0].get_str().c_str(); - int kmdheight = atoi(params[1].get_str().c_str()); + int hushheight = atoi(params[1].get_str().c_str()); uint32_t ccid = atoi(params[2].get_str().c_str()); ret.push_back(Pair("coin",symbol)); - ret.push_back(Pair("kmdheight",kmdheight-5)); + ret.push_back(Pair("hushheight",hushheight-5)); ret.push_back(Pair("ccid", (int) ccid)); uint256 destNotarizationTxid; std::vector moms; - uint256 MoMoM = CalculateProofRoot(symbol, ccid, kmdheight-5, moms, destNotarizationTxid); + uint256 MoMoM = CalculateProofRoot(symbol, ccid, hushheight-5, moms, destNotarizationTxid); UniValue valMoms(UniValue::VARR); for (int i=0; i 3) throw runtime_error("scanNotarizationsDB blockHeight symbol [blocksLimit=1440]\n\n" - "Scans notarisationsdb backwards from height for a notarisation" + "Scans notarizationsdb backwards from height for a notarization" " of given symbol"); int height = atoi(params[0].get_str().c_str()); std::string symbol = params[1].get_str().c_str(); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 8139c93ce..0046d4b7f 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -829,8 +829,10 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // Others may not have data loaded yet, such as wallet details, but // those RPCs are written defensively to deal with that. Allowing these // few RPCs means we can see our addresses and make private key backups - // while a very long wallet rescan is happening + // while a very long wallet rescan is happening and do other read-only devopz if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && + pcmd->name != "getNotarizationsForBlock" && pcmd->name != "scanNotarizationsDB" && + pcmd->name != "getnotarysendmany" && pcmd->name != "geterablockheights" && pcmd->name != "getaddressesbyaccount" && pcmd->name != "listaddresses" && pcmd->name != "z_exportwallet" && pcmd->name != "notaries" && pcmd->name != "signmessage" && pcmd->name != "decoderawtransaction" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" && pcmd->name != "getnetworkinfo" ) { From 6c0c505eeadc4128380b889758ee6df40b706d98 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Sep 2021 16:03:34 -0400 Subject: [PATCH 089/115] TUSH is alive and well --- src/tush-cli | 17 +++++++++++++++++ src/tushd | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 src/tush-cli create mode 100755 src/tushd diff --git a/src/tush-cli b/src/tush-cli new file mode 100755 index 000000000..fa40e9f81 --- /dev/null +++ b/src/tush-cli @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright (c) 2016-2021 The Hush developers + +# set working directory to the location of this script +# readlink -f does not always exist +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $DIR +DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" +cd $DIR + +NAME=TUSH + +# Use the HUSHCLI env var to over-ride using the same directory as this file +CLI=${HUSHCLI:-./hush-cli} +if [ -f $CLI ]; then + $CLI -ac_name=$NAME "$@" +fi diff --git a/src/tushd b/src/tushd new file mode 100755 index 000000000..ad5fafa21 --- /dev/null +++ b/src/tushd @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Copyright (c) 2016-2021 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 + +# set working directory to the location of this script +# readlink -f does not always exist +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $DIR +DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" +cd $DIR + +./hushd -ac_name=TUSH -ac_private=1 -gen=1 -testnode=1 + From 844d8163bddb785e1c072c65e0a36cda02a9c09f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 10:15:02 -0400 Subject: [PATCH 090/115] Add more default nodes --- 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 6c19523e4..71f46d0d4 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1810,7 +1810,7 @@ void hush_args(char *argv0) vector HUSH_nodes= {"node1.hush.is","node2.hush.is","node3.hush.is", "node4.hush.is","node5.hush.is","node6.hush.is", - "node7.hush.is","node8.hush.is"}; + "node7.hush.is","node8.hush.is","node1.hush.land", "node2.hush.land"}; vector more_nodes = mapMultiArgs["-addnode"]; if (more_nodes.size() > 0) { fprintf(stderr,"%s: Adding %lu more nodes via custom -addnode arguments\n", __func__, more_nodes.size() ); From 9c67f1b7589795880cd3ba8b9d9405cd35c0a5b7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 10:23:13 -0400 Subject: [PATCH 091/115] Checkpoints --- contrib/checkpoints.pl | 6 +-- src/chainparams.cpp | 86 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/contrib/checkpoints.pl b/contrib/checkpoints.pl index 1a6524820..64f555261 100755 --- a/contrib/checkpoints.pl +++ b/contrib/checkpoints.pl @@ -37,9 +37,9 @@ while (1) { } my $time = qx{$hush getblock $last |grep time|cut -d: -f2| sed 's/,//g'}; chomp($time); -# TODO: This is Linux-only -my $line1 = qx{grep --text height=$prev ~/.komodo/HUSH3/debug.log}; -my $line2 = qx{grep --text height=$blocks ~/.komodo/HUSH3/debug.log}; +# TODO: This is Linux-only and assumes new (not legacy) dir +my $line1 = qx{grep --text height=$prev ~/.hush/HUSH3/debug.log}; +my $line2 = qx{grep --text height=$blocks ~/.hush/HUSH3/debug.log}; my $txs_per_day = 2 * $perday; # default estimate is 2 txs per block, on average my $total_txs = 0; #print "line1: $line1\n"; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 26f4e8488..df85bdf23 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -882,10 +882,88 @@ void *chainparams_commandline() { (584000, uint256S("0x0000000720f29b0d72469739e9d94607e67b48eb9957b45c2fd5a34b86df039a")) (585000, uint256S("0x00000001409c395b2e37e2b88110b320996996241bfb489103db9e17aaf2ddc7")) (586000, uint256S("0x00000006ff6509d260f66af2fc4fc1769d56394333f3ad5a19bbd10c8c26742b")) - (587000, uint256S("0x00000003866d330ac5448e07eb5e95d2e1860203f2e0ca568161d04ea5c5deb8")), - (int64_t) 1625849524, // time of last checkpointed block - (int64_t) 0, // total txs - (double) 2304 // txs in the last day before block 587157 + (587000, uint256S("0x00000003866d330ac5448e07eb5e95d2e1860203f2e0ca568161d04ea5c5deb8")) + (588000, uint256S("0x0000000247f3b1c8f60b82a1dc5b86ead3adb023a6e3508d1c732c88bceae666")) + (589000, uint256S("0x00000000d9108a0e811622919777fb929986966034bb53678d431dd50f0b3640")) + (590000, uint256S("0x00000006a7699d8fb948cc67dd2427ee25fbfa2a8e02517aad45880658eab983")) + (591000, uint256S("0x00000004f6746a57c60ab45b5d0a30375e635bb8b564c85b92e8b34afbb82077")) + (592000, uint256S("0x000000023987ca4c3454b0fd17fe64febcc2c1b75d2820e0368084c59d71cbb3")) + (593000, uint256S("0x00000006e05b247fa1a4b99e5292d4c696e2627ed5b64263ceb2a985d98cb446")) + (594000, uint256S("0x000000010f20489639e7ec3a3694b2c1def345f2bf7804fadbd1ee92813a020d")) + (595000, uint256S("0x00000008fda549361df97ddac7f495fdb629c4c6a646c91e5535f96d12d98dee")) + (596000, uint256S("0x0000000512d08ea2cd501bb2132dec8dd997e0332e5d0a51bf9d0992451030da")) + (597000, uint256S("0x00000006384749ab79ee12dd46e068634254354c511f535278d54b8efd41e29e")) + (598000, uint256S("0x000000031ba9be6704d352002cfb763dc7123e93911796159ef8d2d0328da348")) + (599000, uint256S("0x00000005bf47be7b949ff5217ae980fcea48d9d25e824c68367ce934447ef0bd")) + (600000, uint256S("0x00000000a721ce253a2c130fec44c581810dfb9448a46ef524a16f1ef3920bec")) + (601000, uint256S("0x00000007cdbdfd7f1c9bf8c20ff4f35c2c25a21558a5e70ea139bd50d2421fab")) + (602000, uint256S("0x0000000708ba8ec93c022184d3258cd4956f82e2edd0b67c2493f74a3bf6afef")) + (603000, uint256S("0x00000005a7b51fd94b80f51ae2b0d0dc8f7285eb418914bd177f6f2fcc68e745")) + (604000, uint256S("0x00000010bd1bce0ed2c83f8860b5201a700c535dfc6d6af2c15ee7de4e2e0cba")) + (605000, uint256S("0x00000002cac498bb995a395d52a41a48372e57b494de023cd4e2eb70c5616b1b")) + (606000, uint256S("0x0000000269e7256e93648c29f72e169767af626c7db95fa8ac853be6072a7942")) + (607000, uint256S("0x000000073e07d2a4757b93641c318dbdc784067b02d4cc9f0be4747c80319f3b")) + (608000, uint256S("0x00000001613776b53c2060529996e64d24fa5874879b7457aee20430ab2bc87f")) + (609000, uint256S("0x0000000acd03e99bfe60d8a5d5023b373aa13f71a5d577c813141b3b714cc95a")) + (610000, uint256S("0x0000000aa64b831908eb621b6e2c548620d29146b0c8dae951dd84daef0e63d1")) + (611000, uint256S("0x0000000736b273fdf7d8df9bddba568e71547a79e0b14c71027e61dae6a83443")) + (612000, uint256S("0x00000012a5b000bcb8606acb628c46d49157bc97189fc8e37dfaaf280b05f8a1")) + (613000, uint256S("0x00000006bb698faba83d28b958cd9a242fa9baadb2efa510e2e27b1eebedb951")) + (614000, uint256S("0x000000007c66271651afb1468d0546f3ea1b9720d42e3597c9277429d43765f1")) + (615000, uint256S("0x00000015a141ae1feec020f529a3e5dea51d29efdef8d0425677e5126c850f73")) + (616000, uint256S("0x0000000967c92b77c884fc58d7973a8d78ea47c2ec8e68e1619f6b92f3db2c05")) + (617000, uint256S("0x0000000a7eb3e594474d545752f35a70965c17e497c2201fa8f38943bebb8756")) + (618000, uint256S("0x0000000ca0f1eb16ed72e5ea4e77cb165fb87384e4c3e0064d5faac7f49c91b9")) + (619000, uint256S("0x00000006da3e4a2e36342593090efb0fdf19e77d4ce8663a54df0dd7109b178b")) + (620000, uint256S("0x0000000d7c987adbdbf3742c6cebd55b7c8fe213362385f1e24e6eecf7dd4ea0")) + (621000, uint256S("0x00000003009cf1ac25864d6997dd9c9ce76cf6cb58f0e61700bb52ec72f54cc6")) + (622000, uint256S("0x0000000cf25b9a537ea61d548979003dde28155b73b26d53cf2a7b69036926cb")) + (623000, uint256S("0x00000007da399943d00f84c9e190e9968f3f456de70060ad17b6b63606287db0")) + (624000, uint256S("0x0000000cab9f7f9e6e5223eda1bee8de7384b6dbed3bfe807818871d78f9594f")) + (625000, uint256S("0x0000000266b471c7ee107a85080792531d7dc91c23d7b42b46e44728c3d9ea8c")) + (626000, uint256S("0x00000003fe1af9fffd32fae9b809c916d7484024021053c09286c763fd2fc1e6")) + (627000, uint256S("0x00000006f9bbef0362e0e99bb4061b4d386c82477d64d84850e4a1b6fce85093")) + (628000, uint256S("0x0000000d9afb9e78eac960bc5b7aaa8356ac6660e5147175117ed53f6d41215e")) + (629000, uint256S("0x000000071ee3b95304b4df78e66c56f8f1deb557b57ed7716c389b0e04344d87")) + (630000, uint256S("0x00000002ed362482e0bc5d03d07e406748590d01871f91e03ed86d15737d1e2f")) + (631000, uint256S("0x0000000e55845a96afa1359c6aaac5e66c84daf56ccea33d9127a66e6162736d")) + (632000, uint256S("0x0000000fb180307499ce6d21f2308ffdf20b0d03ed45ba0de3420fac71434b95")) + (633000, uint256S("0x00000010ddf5569109d8a405eedac88f2ae9f56838dcf279cd9ca32185cf5d55")) + (634000, uint256S("0x0000000781805d9c573380c22215cf83280c4d0688bbd730adb0821c89b2a3d0")) + (635000, uint256S("0x0000000fa1d7aba218223517de8ceeecfcda087b7e549b0537a986465520e040")) + (636000, uint256S("0x00000010eb125169e1e9cbe061564c9c663389b6a68a06445d18c4346601ce78")) + (637000, uint256S("0x0000000c85df82c1ade3c311e5673c294d97858ea23dac5d5f03aaf32b374b1b")) + (638000, uint256S("0x00000002aa16a3abc3ae9739609eddaf805fce5d0f7b0ae8d9494381843ab5a2")) + (639000, uint256S("0x00000012eb63468724acc222e45889a9bf54c1a5e0152ad1fc9c57cdb7bcb460")) + (640000, uint256S("0x0000000bf6a31eec79a36c5423f52069e5d6858bfc566081556ba9487a5ef36f")) + (641000, uint256S("0x000000065414f1d2a543687ee4c0137ca5d66d5d35f9dbf9b4fe73e59ecc5af7")) + (642000, uint256S("0x00000005fe35f60661760b7ca027a73e6915f6add12e736018357a1e782310a4")) + (643000, uint256S("0x000000076e77c3e0a2a1890a5bea2d92aa720a08bb4e5571e76bb05c93f40c98")) + (644000, uint256S("0x0000001054093374a3a414047113ab882d092f012c1c17cf3d98ca8006b8e8bc")) + (645000, uint256S("0x0000000cb0c07c2325e8162e58f3fcc14323450274a1d69aff06ac799cf72f53")) + (646000, uint256S("0x0000000252d31029d2e96406697ada40ca3afb3d9fe2a2f67cdad2462e8fe00d")) + (647000, uint256S("0x0000001155755f0718b6cc3474e44748358e5328c2c0c32c97cfd3842bf22510")) + (648000, uint256S("0x000000173c2e63d658263c1c28e1e0a1b2ce30f2d3d4eba2f540836315a9d5ea")) + (649000, uint256S("0x00000002044331ebe095ea838da367fed1495be4ad69b0c655df653ccb1923dd")) + (650000, uint256S("0x00000010afad2d800c397557a9cbe501f32cd09f18f89c2f3f11e0e38ae45843")) + (651000, uint256S("0x0000000b6a9630f3a2334d4529ba013480104e54fc59dc4cabc3a8869ad17a01")) + (652000, uint256S("0x00000004d22aa00fb4c8266b0304f43bc7bec8e18850e764a431438a9fdfd141")) + (653000, uint256S("0x0000000a248721cef01783838a5b53547b12273ddf57a2bc3ba708ea987f8937")) + (654000, uint256S("0x00000004c95adc9e17e429c35cc4c8ffd130e23228245e29f150896ab66ffdfd")) + (655000, uint256S("0x0000001428523dbe3cf9338753a42c579a669df7bbd8d6fa667f4daf2c4c749f")) + (656000, uint256S("0x0000001704429a9b902d4cddee708bd0ae7b758c6bd9ed634c143931e15ac337")) + (657000, uint256S("0x00000007b376e2c197b21a2eacac81847f401f92ed50213e845e039d3516458c")) + (658000, uint256S("0x00000026e751010b1135052b105f2be464702b040d76610bfeae1b1a2bcab15c")) + (659000, uint256S("0x00000005d784a9cf7b60bc6908234052c29a555dcf1d4f8a82663aabbc2e0c83")) + (660000, uint256S("0x00000015cdf576c284ad93912955194f6764a16d562308bb82bcfdc7a27ad20b")) + (661000, uint256S("0x0000000af126a5261626bc10a6cf2a8a07ea145f6aa33539e4d434033411c4db")) + (662000, uint256S("0x00000011c4659f0bbe3559c32ff24588d78a3822e8b0e31bb9298a16213fe154")) + (663000, uint256S("0x000000076756708535e3daeaca6bc32aa1dc360228af6a0c5e5e07b5d9f5f00b")) + (664000, uint256S("0x000000181806c17b47bb843537cc91c95ca1e3596bb9e049d18c2e73c1026258")) + (665000, uint256S("0x0000001e966c9edae76c40262e65a6c9ab764a09154eb802fb892ceebc2d1935")), + (int64_t) 1631750258, // time of last checkpointed block + (int64_t) 1064407, // total txs + (double) 1402 // txs in the last day before block 665685 }; } else { checkpointData = //(Checkpoints::CCheckpointData) From f21065394f4e1071fc5be3faca66910ae64af8a8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 10:25:23 -0400 Subject: [PATCH 092/115] Update dapp header file location and error message --- src/cc/dapps/dappstd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/dapps/dappstd.c b/src/cc/dapps/dappstd.c index 1d897196b..67cb6b9cb 100644 --- a/src/cc/dapps/dappstd.c +++ b/src/cc/dapps/dappstd.c @@ -246,9 +246,9 @@ int32_t safecopy(char *dest,char *src,long len) #define true 1 #define false 0 //#ifdef STANDALONE -//#include "../komodo/src/komodo_cJSON.c" +//#include "../hush3/src/hush_cJSON.c" //#else -#include "../komodo_cJSON.c" +#include "../hush_cJSON.c" //#endif int32_t games_replay(uint64_t seed,int32_t sleeptime); @@ -1105,7 +1105,7 @@ int main(int argc, char **argv) fclose(fp); if ( GAMES_PORT == 0 ) { - printf("you must copy %s.conf from ~/.komodo/%s/%s.conf (or equivalent location) to current dir\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_SYMBOL,ASSETCHAINS_SYMBOL); + printf("you must copy %s.conf from ~/.hush/%s/%s.conf (or equivalent location) to current dir\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_SYMBOL,ASSETCHAINS_SYMBOL); return(-1); } return(GAMEMAIN(argc,argv)); From f22cbbf1e21d73ab931d41993ec8800264c7c14e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 14:12:31 -0400 Subject: [PATCH 093/115] Cleanup and remove dead code --- src/bitcoind.cpp | 2 +- src/cc/CCPrices.h | 2 +- src/cc/CC_made_easy.md | 4 +- src/cc/cclib.cpp | 2 +- src/cc/gamescc.cpp | 6 +- src/hush.h | 14 +- src/hush_bitcoind.h | 14 +- src/hush_cJSON.h | 4 +- src/hush_ccdata.h | 24 +-- src/hush_defs.h | 24 +-- src/hush_events.h | 26 +-- src/hush_gateway.h | 386 +++++++++++++++++++------------------- src/hush_globals.h | 8 +- src/hush_nSPV_fullnode.h | 2 +- src/hush_nSPV_superlite.h | 8 +- src/hush_notary.h | 14 +- src/hush_pax.h | 18 +- src/hush_structs.h | 4 +- src/hush_utils.h | 8 +- src/main.cpp | 18 +- src/miner.cpp | 20 +- src/rpc/blockchain.cpp | 6 +- src/rpc/crosschain.cpp | 4 +- src/rpc/mining.cpp | 2 +- src/wallet/rpcwallet.cpp | 22 +-- 25 files changed, 321 insertions(+), 321 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 9ba1b93ae..9e5a2b43a 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -69,7 +69,7 @@ void WaitForShutdown(boost::thread_group* threadGroup) // Tell the main threads to shutdown. if ( ASSETCHAINS_CBOPRET != 0 ) { - komodo_pricesinit(); + hush_pricesinit(); } while (!fShutdown) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 5b352d0f6..e715706b9 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -23,7 +23,7 @@ #include "hush_defs.h" #include "CCinclude.h" -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); +int32_t hush_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); extern void GetHushEarlytxidScriptPub(); extern CScript HUSH_EARLYTXID_SCRIPTPUB; diff --git a/src/cc/CC_made_easy.md b/src/cc/CC_made_easy.md index 48ccde25a..149c5321c 100644 --- a/src/cc/CC_made_easy.md +++ b/src/cc/CC_made_easy.md @@ -84,7 +84,7 @@ However, this is the CC contract basics chapter, so let us ignore mempool issues That means to just follow a known working template and only changing the things where the existing templates are not sufficient, ie. the core differentiator of your CC contract. -In the ~/komodo/src/cc/eval.h file all the eval codes are defined, currently: +In the hush3/src/cc/eval.h file all the eval codes are defined, currently: #define FOREACH_EVAL(EVAL) \ EVAL(EVAL_IMPORTPAYOUT, 0xe1) \ @@ -201,7 +201,7 @@ You do need to be careful not to cause a deadlock as the CC validation code is c Chapter 6 - faucet example Finally, we are ready for the first actual example of a CC contract. The faucet. This is a very simple contract and it ran into some interesting bugs in the first incarnation. -The code in ~/komodo/src/cc/faucet.cpp is the ultimate documentation for it with all the details, so I will just address the conceptual issues here. +The code in hush3/src/cc/faucet.cpp is the ultimate documentation for it with all the details, so I will just address the conceptual issues here. The idea is that people send funds to the faucet by locking it in faucet's global CC address and anybody is allowed to create a faucetget transaction that spends it. diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index c1ae646ca..30df42f3a 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -47,7 +47,7 @@ std::string MYCCLIBNAME = (char *)"sudoku"; #endif #ifndef BUILD_GAMESCC -void komodo_netevent(std::vector payload) {} +void hush_netevent(std::vector payload) {} #endif extern std::string MYCCLIBNAME; diff --git a/src/cc/gamescc.cpp b/src/cc/gamescc.cpp index e2d563d00..80251819f 100644 --- a/src/cc/gamescc.cpp +++ b/src/cc/gamescc.cpp @@ -479,7 +479,7 @@ int32_t games_event(uint32_t timestamp,uint256 gametxid,int32_t eventid,std::vec { GetOpReturnData(games_eventopret(timestamp,mypk,sig,payload),vopret); games_payloadrecv(mypk,timestamp,payload); - komodo_sendmessage(4,8,"events",vopret); + hush_sendmessage(4,8,"events",vopret); return(0); } fprintf(stderr,"games_eventsign error\n"); @@ -539,7 +539,7 @@ UniValue games_events(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) return(result); } -void komodo_netevent(std::vector message) +void hush_netevent(std::vector message) { int32_t i,retval,lag,lagerr=0; uint32_t timestamp,now; CPubKey pk; std::vector sig,payload; char str[67]; if ( games_eventdecode(timestamp,pk,sig,payload,message) == 'E' ) @@ -560,7 +560,7 @@ void komodo_netevent(std::vector message) if ( (rand() % 10) == 0 ) { //fprintf(stderr,"relay message.[%d]\n",(int32_t)message.size()); - komodo_sendmessage(2,2,"events",message); + hush_sendmessage(2,2,"events",message); } } } diff --git a/src/hush.h b/src/hush.h index b25dcfcb4..63bbf3dbe 100644 --- a/src/hush.h +++ b/src/hush.h @@ -146,7 +146,7 @@ int32_t hush_parsestatefile(struct hush_state *sp,FILE *fp,char *symbol,char *de errs++; //if ( matched != 0 ) global independent states -> inside *sp //printf("%s.%d load[%s] ht.%d\n",SMART_CHAIN_SYMBOL,ht,symbol,kheight); - hush_eventadd_kmdheight(sp,symbol,ht,kheight,0); + hush_eventadd_hushheight(sp,symbol,ht,kheight,0); } else if ( func == 'T' ) { @@ -157,7 +157,7 @@ int32_t hush_parsestatefile(struct hush_state *sp,FILE *fp,char *symbol,char *de errs++; //if ( matched != 0 ) global independent states -> inside *sp //printf("%s.%d load[%s] ht.%d t.%u\n",SMART_CHAIN_SYMBOL,ht,symbol,kheight,ktimestamp); - hush_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); + hush_eventadd_hushheight(sp,symbol,ht,kheight,ktimestamp); } else if ( func == 'R' ) { @@ -285,7 +285,7 @@ int32_t hush_parsestatefiledata(struct hush_state *sp,uint8_t *filedata,long *fp int32_t kheight; if ( memread(&kheight,sizeof(kheight),filedata,&fpos,datalen) != sizeof(kheight) ) errs++; - hush_eventadd_kmdheight(sp,symbol,ht,kheight,0); + hush_eventadd_hushheight(sp,symbol,ht,kheight,0); } else if ( func == 'T' ) { @@ -296,7 +296,7 @@ int32_t hush_parsestatefiledata(struct hush_state *sp,uint8_t *filedata,long *fp errs++; //if ( matched != 0 ) global independent states -> inside *sp //printf("%s.%d load[%s] ht.%d t.%u\n",SMART_CHAIN_SYMBOL,ht,symbol,kheight,ktimestamp); - hush_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); + hush_eventadd_hushheight(sp,symbol,ht,kheight,ktimestamp); } else if ( func == 'R' ) { @@ -409,7 +409,7 @@ void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotarie if ( fwrite(&HUSHheight,1,sizeof(HUSHheight),fp) != sizeof(HUSHheight) ) errs++; } - hush_eventadd_kmdheight(sp,symbol,height,HUSHheight,HUSHtimestamp); + hush_eventadd_hushheight(sp,symbol,height,HUSHheight,HUSHtimestamp); } else if ( opretbuf != 0 && opretlen > 0 ) { uint16_t olen = opretlen; fputc('R',fp); @@ -711,7 +711,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 ) { if ( notaryid >= 0 && notaryid < 64 ) - komodo_paxpricefeed(height,&scriptbuf[len],opretlen); + hush_paxpricefeed(height,&scriptbuf[len],opretlen); } else if ( matched != 0 ) { @@ -792,7 +792,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) if ( pindex->GetHeight() != hwmheight ) { printf("%s hwmheight.%d vs pindex->GetHeight().%d t.%u reorg.%d\n",SMART_CHAIN_SYMBOL,hwmheight,pindex->GetHeight(),(uint32_t)pindex->nTime,hwmheight-pindex->GetHeight()); - komodo_purge_ccdata((int32_t)pindex->GetHeight()); + hush_purge_ccdata((int32_t)pindex->GetHeight()); hwmheight = pindex->GetHeight(); } if (!fJustCheck) diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index e2b4e9fa7..df299d6dd 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -950,12 +950,12 @@ int32_t hush_nextheight() else return(hush_longestchain() + 1); } -int32_t hush_isrealtime(int32_t *kmdheightp) +int32_t hush_isrealtime(int32_t *hushheightp) { struct hush_state *sp; CBlockIndex *pindex; if ( (sp= hush_stateptrget((char *)"HUSH3")) != 0 ) - *kmdheightp = sp->CURRENT_HEIGHT; - else *kmdheightp = 0; + *hushheightp = sp->CURRENT_HEIGHT; + else *hushheightp = 0; if ( (pindex= chainActive.LastTip()) != 0 && pindex->GetHeight() >= (int32_t)hush_longestchain() ) return(1); else return(0); @@ -1212,7 +1212,7 @@ void hush_segids(uint8_t *hashbuf,int32_t height,int32_t n) } } -arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime) +arith_uint256 hush_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime) { arith_uint256 origtarget,easy; int32_t diff,tipdiff; int64_t mult; bool fNegative,fOverflow; CBlockIndex *tipindex; if ( height > 10 && (tipindex= hush_chainactive(height - 1)) != 0 ) // disable offchain diffchange @@ -1238,7 +1238,7 @@ arith_uint256 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,ui return(bnTarget); } -arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc) +arith_uint256 hush_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc) { int32_t oldflag = 0,dispflag = 0; CBlockIndex *pindex; arith_uint256 easydiff,bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,m,ht,percPoS,diff,val; @@ -1543,7 +1543,7 @@ uint64_t hush_checknotarypay(CBlock *pblock,int32_t height) return(0); } -bool komodo_appendACscriptpub() +bool hush_appendACscriptpub() { static bool didinit = false; if ( didinit ) @@ -1638,7 +1638,7 @@ int64_t hush_checkcommission(CBlock *pblock,int32_t height) if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) { static bool didinit = false; - if ( !didinit && height > HUSH_EARLYTXID_HEIGHT && HUSH_EARLYTXID != zeroid && komodo_appendACscriptpub() ) + if ( !didinit && height > HUSH_EARLYTXID_HEIGHT && HUSH_EARLYTXID != zeroid && hush_appendACscriptpub() ) { fprintf(stderr, "appended CC_op_return to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; diff --git a/src/hush_cJSON.h b/src/hush_cJSON.h index f83e1896d..d7eb3a4dd 100644 --- a/src/hush_cJSON.h +++ b/src/hush_cJSON.h @@ -36,8 +36,8 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ -#ifndef komodo_cJSON__h -#define komodo_cJSON__h +#ifndef hush_cJSON__h +#define hush_cJSON__h #include #include #include diff --git a/src/hush_ccdata.h b/src/hush_ccdata.h index e5e431219..420a7243e 100644 --- a/src/hush_ccdata.h +++ b/src/hush_ccdata.h @@ -41,7 +41,7 @@ uint256 hush_calcMoM(int32_t height,int32_t MoMdepth) return BuildMerkleTree(&fMutated, leaves, tree); } -struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) +struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) { struct hush_ccdata_entry *allMoMs=0; struct hush_ccdata *ccdata,*tmpptr; int32_t i,num,max; bool fMutated; std::vector tree, leaves; @@ -58,7 +58,7 @@ struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t k } allMoMs[num].MoM = ccdata->MoMdata.MoM; allMoMs[num].notarized_height = ccdata->MoMdata.notarized_height; - allMoMs[num].kmdheight = ccdata->MoMdata.height; + allMoMs[num].hushheight = ccdata->MoMdata.height; allMoMs[num].txi = ccdata->MoMdata.txi; strcpy(allMoMs[num].symbol,ccdata->symbol); num++; @@ -81,7 +81,7 @@ struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t k return(allMoMs); } -int32_t komodo_addpair(struct hush_ccdataMoMoM *mdata,int32_t notarized_height,int32_t offset,int32_t maxpairs) +int32_t hush_addpair(struct hush_ccdataMoMoM *mdata,int32_t notarized_height,int32_t offset,int32_t maxpairs) { if ( maxpairs >= 0) { if ( mdata->numpairs >= maxpairs ) @@ -91,7 +91,7 @@ int32_t komodo_addpair(struct hush_ccdataMoMoM *mdata,int32_t notarized_height,i //fprintf(stderr,"pairs reallocated to %p num.%d\n",mdata->pairs,mdata->numpairs); } } else { - fprintf(stderr,"komodo_addpair.maxpairs %d must be >= 0\n",(int32_t)maxpairs); + fprintf(stderr,"hush_addpair.maxpairs %d must be >= 0\n",(int32_t)maxpairs); return(-1); } mdata->pairs[mdata->numpairs].notarized_height = notarized_height; @@ -100,7 +100,7 @@ int32_t komodo_addpair(struct hush_ccdataMoMoM *mdata,int32_t notarized_height,i return(maxpairs); } -int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height) +int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t hushheight,int32_t notarized_height) { uint8_t hexdata[8192]; struct hush_ccdata *ccdata,*tmpptr; int32_t len,maxpairs,i,retval=-1,depth,starti,endi,CCid=0; struct hush_ccdata_entry *allMoMs; starti = endi = depth = len = maxpairs = 0; @@ -114,7 +114,7 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda portable_mutex_lock(&HUSH_CC_mutex); DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) { - if ( ccdata->MoMdata.height < kmdheight ) + if ( ccdata->MoMdata.height < hushheight ) { //fprintf(stderr,"%s notarized.%d kmd.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height); if ( strcmp(ccdata->symbol,symbol) == 0 ) @@ -140,13 +140,13 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda mdata->kmdendi = endi; if ( starti != 0 && endi != 0 && endi >= starti ) { - if ( (allMoMs= komodo_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 ) + if ( (allMoMs= hush_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 ) { mdata->MoMoMdepth = depth; for (i=0; inumpairs > 0 ) { @@ -160,7 +160,7 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda { if ( len + sizeof(uint32_t)*2 > sizeof(hexdata) ) { - fprintf(stderr,"%s %d %d i.%d of %d exceeds hexdata.%d\n",symbol,kmdheight,notarized_height,i,mdata->numpairs,(int32_t)sizeof(hexdata)); + fprintf(stderr,"%s %d %d i.%d of %d exceeds hexdata.%d\n",symbol,hushheight,notarized_height,i,mdata->numpairs,(int32_t)sizeof(hexdata)); break; } len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].notarized_height); @@ -171,7 +171,7 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda init_hexbytes_noT(hexstr,hexdata,len); //fprintf(stderr,"hexstr.(%s)\n",hexstr); retval = 0; - } else fprintf(stderr,"%s %d %d too much hexdata[%d] for hexstr[%d]\n",symbol,kmdheight,notarized_height,len,hexsize); + } else fprintf(stderr,"%s %d %d too much hexdata[%d] for hexstr[%d]\n",symbol,hushheight,notarized_height,len,hexsize); } free(allMoMs); } @@ -179,7 +179,7 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda return(retval); } -void komodo_purge_ccdata(int32_t height) +void hush_purge_ccdata(int32_t height) { struct hush_ccdata *ccdata,*tmpptr; if ( SMART_CHAIN_SYMBOL[0] == 0 ) @@ -247,7 +247,7 @@ int32_t hush_rwccdata(char *thischain,int32_t rwflag,struct hush_ccdata *ccdata, { for (i=0; inumpairs; i++) { - if ( (np= komodo_npptr(MoMoMdata->pairs[i].notarized_height)) != 0 ) + if ( (np= hush_npptr(MoMoMdata->pairs[i].notarized_height)) != 0 ) { memset(&zero,0,sizeof(zero)); if ( memcmp(&np->MoMoM,&zero,sizeof(np->MoMoM)) == 0 ) diff --git a/src/hush_defs.h b/src/hush_defs.h index c88abe9d6..4d8bd62b8 100644 --- a/src/hush_defs.h +++ b/src/hush_defs.h @@ -594,7 +594,7 @@ extern int32_t ASSETCHAINS_EARLYTXIDCONTRACT; int tx_height( const uint256 &hash ); extern std::vector vAllowListAddress; extern std::map mapHeightEvalActivate; -void komodo_netevent(std::vector payload); +void hush_netevent(std::vector payload); int32_t getacseason(uint32_t timestamp); int32_t gethushseason(int32_t height); @@ -603,8 +603,8 @@ int32_t gethushseason(int32_t height); #define HUSH_KVBINARY 2 #define PRICES_SMOOTHWIDTH 1 #define PRICES_MAXDATAPOINTS 8 -uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume); -int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); +uint64_t hush_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume); +int32_t hush_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width); @@ -615,22 +615,22 @@ int32_t hush_longestchain(); int32_t hush_dpowconfs(int32_t height,int32_t numconfs); int8_t hush_segid(int32_t nocache,int32_t height); int32_t hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeight); -char *komodo_pricename(char *name,int32_t ind); -int32_t komodo_priceind(const char *symbol); -int32_t komodo_pricesinit(); -int64_t komodo_priceave(int64_t *tmpbuf,int64_t *correlated,int32_t cskip); -int64_t komodo_pricecorrelated(uint64_t seed,int32_t ind,uint32_t *rawprices,int32_t rawskip,uint32_t *nonzprices,int32_t smoothwidth); +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 komodo_pricemult(int32_t ind); -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); +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 komodo_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime); +arith_uint256 hush_adaptivepow_target(int32_t height,arith_uint256 bnTarget,uint32_t nTime); bool hush_hardfork_active(uint32_t time); uint256 Parseuint256(const char *hexstr); -void komodo_sendmessage(int32_t minpeers, int32_t maxpeers, const char *message, std::vector payload); +void hush_sendmessage(int32_t minpeers, int32_t maxpeers, const char *message, std::vector payload); CBlockIndex *hush_getblockindex(uint256 hash); int32_t hush_nextheight(); CBlockIndex *hush_blockindex(uint256 hash); diff --git a/src/hush_events.h b/src/hush_events.h index 6d733483d..00832ae23 100644 --- a/src/hush_events.h +++ b/src/hush_events.h @@ -88,7 +88,7 @@ void hush_eventadd_pricefeed(struct hush_state *sp,char *symbol,int32_t height,u memcpy(F.prices,prices,sizeof(*F.prices) * num); hush_eventadd(sp,height,symbol,HUSH_EVENT_PRICEFEED,(uint8_t *)&F,(int32_t)(sizeof(F.num) + sizeof(*F.prices) * num)); if ( sp != 0 ) - komodo_pvals(height,prices,num); + hush_pvals(height,prices,num); } //else fprintf(stderr,"skip pricefeed[%d]\n",num); } @@ -107,7 +107,7 @@ void hush_eventadd_opreturn(struct hush_state *sp,char *symbol,int32_t height,ui hush_eventadd(sp,height,symbol,HUSH_EVENT_OPRETURN,opret,O.oplen); free(opret); if ( sp != 0 ) - komodo_opreturn(height,value,buf,opretlen,txid,vout,symbol); + hush_opreturn(height,value,buf,opretlen,txid,vout,symbol); } } @@ -155,32 +155,32 @@ void hush_event_rewind(struct hush_state *sp,char *symbol,int32_t height) } } -void komodo_setkmdheight(struct hush_state *sp,int32_t kmdheight,uint32_t timestamp) +void hush_sethushheight(struct hush_state *sp,int32_t hushheight,uint32_t timestamp) { if ( sp != 0 ) { - if ( kmdheight > sp->SAVEDHEIGHT ) + if ( hushheight > sp->SAVEDHEIGHT ) { - sp->SAVEDHEIGHT = kmdheight; + sp->SAVEDHEIGHT = hushheight; sp->SAVEDTIMESTAMP = timestamp; } - if ( kmdheight > sp->CURRENT_HEIGHT ) - sp->CURRENT_HEIGHT = kmdheight; + if ( hushheight > sp->CURRENT_HEIGHT ) + sp->CURRENT_HEIGHT = hushheight; } } -void hush_eventadd_kmdheight(struct hush_state *sp,char *symbol,int32_t height,int32_t kmdheight,uint32_t timestamp) +void hush_eventadd_hushheight(struct hush_state *sp,char *symbol,int32_t height,int32_t hushheight,uint32_t timestamp) { uint32_t buf[2]; - if ( kmdheight > 0 ) { - buf[0] = (uint32_t)kmdheight; + if ( hushheight > 0 ) { + buf[0] = (uint32_t)hushheight; buf[1] = timestamp; hush_eventadd(sp,height,symbol,HUSH_EVENT_HUSHHEIGHT,(uint8_t *)buf,sizeof(buf)); if ( sp != 0 ) - komodo_setkmdheight(sp,kmdheight,timestamp); + hush_sethushheight(sp,hushheight,timestamp); } else { - //fprintf(stderr,"REWIND kmdheight.%d\n",kmdheight); - kmdheight = -kmdheight; + //fprintf(stderr,"REWIND hushheight.%d\n",hushheight); + hushheight = -hushheight; hush_eventadd(sp,height,symbol,HUSH_EVENT_REWIND,(uint8_t *)&height,sizeof(height)); if ( sp != 0 ) hush_event_rewind(sp,symbol,height); diff --git a/src/hush_gateway.h b/src/hush_gateway.h index ddaf366a2..b52ab8a1e 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -45,7 +45,7 @@ int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued, if ( sp->withdrawn > maxval ) maxval = sp->withdrawn; netliability = (sp->issued - maxval) - sp->shorted; - maxallowed = komodo_maxallowed(baseid); + maxallowed = hush_maxallowed(baseid); if ( netliability < maxallowed ) *available = (maxallowed - netliability); //printf("%llu - %llu %s %.8f %.8f %.8f %.8f %.8f\n",(long long)maxallowed,(long long)netliability,base,dstr(*deposited),dstr(*issued),dstr(*withdrawn),dstr(*approved),dstr(*redeemed)); @@ -62,7 +62,7 @@ void pax_keyset(uint8_t *buf,uint256 txid,uint16_t vout,uint8_t type) buf[34] = type; } -struct pax_transaction *komodo_paxfind(uint256 txid,uint16_t vout,uint8_t type) +struct pax_transaction *hush_paxfind(uint256 txid,uint16_t vout,uint8_t type) { struct pax_transaction *pax; uint8_t buf[35]; pthread_mutex_lock(&hush_mutex); @@ -72,16 +72,16 @@ struct pax_transaction *komodo_paxfind(uint256 txid,uint16_t vout,uint8_t type) return(pax); } -struct pax_transaction *komodo_paxfinds(uint256 txid,uint16_t vout) +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; imarked = mark; //if ( height > 214700 || pax->height > 214700 ) - // printf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->komodoshis),dstr(pax->fiatoshis)); + // printf("mark ht.%d %.8f %.8f\n",pax->height,dstr(pax->puposhis),dstr(pax->fiatoshis)); } pthread_mutex_unlock(&hush_mutex); return(pax); } -void komodo_paxdelete(struct pax_transaction *pax) +void hush_paxdelete(struct pax_transaction *pax) { return; // breaks when out of order pthread_mutex_lock(&hush_mutex); @@ -116,7 +116,7 @@ void komodo_paxdelete(struct pax_transaction *pax) pthread_mutex_unlock(&hush_mutex); } -void komodo_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 +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 ) @@ -148,7 +148,7 @@ void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t { strcpy(pax->coinaddr,coinaddr); if ( value != 0 ) - pax->komodoshis = value; + pax->puposhis = value; if ( symbol != 0 ) strcpy(pax->symbol,symbol); if ( source != 0 ) @@ -169,7 +169,7 @@ void komodo_gateway_deposit(char *coinaddr,uint64_t value,char *symbol,uint64_t } } -int32_t komodo_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transaction *pax) +int32_t hush_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transaction *pax) { int32_t i,len = 0; if ( rwflag == 1 ) @@ -189,7 +189,7 @@ int32_t komodo_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transactio pax->vout += ((uint32_t)opretbuf[len++] << 8); //printf(" txid v.%d\n",pax->vout); } - len += dragon_rwnum(rwflag,&opretbuf[len],sizeof(pax->komodoshis),&pax->komodoshis); + 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); @@ -208,7 +208,7 @@ int32_t komodo_rwapproval(int32_t rwflag,uint8_t *opretbuf,struct pax_transactio return(len); } -int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t *values,int64_t *srcvalues,int32_t *kmdheights,int32_t *otherheights,int8_t *baseids,uint8_t *rmd160s,uint8_t *opretbuf,int32_t opretlen,int32_t iskomodo) +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) { struct pax_transaction p,*pax; int32_t i,n=0,j,len=0,incr,height,otherheight; uint8_t type,rmd160[20]; uint64_t fiatoshis; char symbol[HUSH_SMART_CHAIN_MAXLEN]; //if ( HUSH_PAX == 0 ) @@ -231,14 +231,14 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t if ( iskomodo != 0 ) { memset(&p,0,sizeof(p)); - len += komodo_rwapproval(0,&opretbuf[len],&p); - if ( values != 0 && srcvalues != 0 && kmdheights != 0 && otherheights != 0 && baseids != 0 && rmd160s != 0 ) + len += hush_rwapproval(0,&opretbuf[len],&p); + if ( values != 0 && srcvalues != 0 && hushheights != 0 && otherheights != 0 && baseids != 0 && rmd160s != 0 ) { txids[n] = p.txid; vouts[n] = p.vout; - values[n] = (strcmp("HUSH3",base) == 0) ? p.komodoshis : p.fiatoshis; - srcvalues[n] = (strcmp("HUSH3",base) == 0) ? p.fiatoshis : p.komodoshis; - kmdheights[n] = p.height; + values[n] = (strcmp("HUSH3",base) == 0) ? p.puposhis : p.fiatoshis; + srcvalues[n] = (strcmp("HUSH3",base) == 0) ? p.fiatoshis : p.puposhis; + hushheights[n] = p.height; otherheights[n] = p.otherheight; memcpy(&rmd160s[n * 20],p.rmd160,20); baseids[n] = hush_baseid(p.source); @@ -246,7 +246,7 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t { char coinaddr[64]; bitcoin_address(coinaddr,60,&rmd160s[n * 20],20); - printf(">>>>>>> %s: (%s) fiat %.8f kmdheight.%d other.%d -> %s %.8f\n",type=='A'?"approvedA":"issuedX",baseids[n]>=0?CURRENCIES[baseids[n]]:"???",dstr(p.fiatoshis),kmdheights[n],otherheights[n],coinaddr,dstr(values[n])); + printf(">>>>>>> %s: (%s) fiat %.8f hushheight.%d other.%d -> %s %.8f\n",type=='A'?"approvedA":"issuedX",baseids[n]>=0?CURRENCIES[baseids[n]]:"???",dstr(p.fiatoshis),hushheights[n],otherheights[n],coinaddr,dstr(values[n])); } } } @@ -262,22 +262,22 @@ int32_t komodo_issued_opreturn(char *base,uint256 *txids,uint16_t *vouts,int64_t vouts[n] = opretbuf[len++]; vouts[n] = (opretbuf[len++] << 8) | vouts[n]; baseids[n] = hush_baseid(base); - if ( (pax= komodo_paxfinds(txids[n],vouts[n])) != 0 ) + if ( (pax= hush_paxfinds(txids[n],vouts[n])) != 0 ) { - values[n] = (strcmp("HUSH3",base) == 0) ? pax->komodoshis : pax->fiatoshis; - srcvalues[n] = (strcmp("HUSH3",base) == 0) ? pax->fiatoshis : pax->komodoshis; - kmdheights[n] = pax->height; + values[n] = (strcmp("HUSH3",base) == 0) ? pax->puposhis : pax->fiatoshis; + srcvalues[n] = (strcmp("HUSH3",base) == 0) ? pax->fiatoshis : pax->puposhis; + hushheights[n] = pax->height; otherheights[n] = pax->otherheight; memcpy(&rmd160s[n * 20],pax->rmd160,20); } } - //printf(" komodo_issued_opreturn issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen); + //printf(" hush_issued_opreturn issuedtxid v%d i.%d opretlen.%d\n",vouts[n],n,opretlen); } } return(n); } -int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t checkvalue,uint64_t seed) +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 ) @@ -288,7 +288,7 @@ int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t che else { if ( SMART_CHAIN_SYMBOL[0] != 0 ) - printf("ht.%d ignore mismatched %s value %lld vs checkvalue %lld -> ratio.%d\n",kmdheight,symbol,(long long)value,(long long)checkvalue,ratio); + 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); } } @@ -301,7 +301,7 @@ int32_t komodo_paxcmp(char *symbol,int32_t kmdheight,uint64_t value,uint64_t che return(value != checkvalue); } -uint64_t komodo_paxtotal() +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 || @@ -320,16 +320,16 @@ uint64_t komodo_paxtotal() basesp = hush_stateptrget(str); if ( basesp != 0 && pax->didstats == 0 ) { - if ( pax->type == 'I' && (pax2= komodo_paxfind(pax->txid,pax->vout,'D')) != 0 ) + if ( pax->type == 'I' && (pax2= hush_paxfind(pax->txid,pax->vout,'D')) != 0 ) { if ( pax2->fiatoshis != 0 ) { - pax->komodoshis = pax2->komodoshis; + 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 kmdheight.%d %.8f other.%d\n",basesp,str,dstr(pax->fiatoshis),pax->height,dstr(pax->komodoshis),pax->otherheight); + 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; } @@ -337,20 +337,20 @@ uint64_t komodo_paxtotal() else if ( pax->type == 'W' ) { //bitcoin_address(coinaddr,addrtype,rmd160,20); - if ( (checktoshis= komodo_paxprice(&seed,pax->height,pax->source,(char *)"HUSH3",(uint64_t)pax->fiatoshis)) != 0 ) + if ( (checktoshis= hush_paxprice(&seed,pax->height,pax->source,(char *)"HUSH3",(uint64_t)pax->fiatoshis)) != 0 ) { - if ( komodo_paxcmp(pax->source,pax->height,pax->komodoshis,checktoshis,seed) != 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->komodoshis)); + //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->komodoshis = checktoshis; + 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 kmd.%d ht.%d %.8f -> %.8f/%.8f\n",pax->vout,pax,pax->source,pax->height,pax->otherheight,dstr(pax->fiatoshis),dstr(pax->komodoshis),dstr(checktoshis)); + // printf(" v%d %p got WITHDRAW.%s kmd.%d ht.%d %.8f -> %.8f/%.8f\n",pax->vout,pax,pax->source,pax->height,pax->otherheight,dstr(pax->fiatoshis),dstr(pax->puposhis),dstr(checktoshis)); } } } @@ -362,7 +362,7 @@ uint64_t komodo_paxtotal() { 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->komodoshis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0); + 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' ) @@ -381,28 +381,28 @@ uint64_t komodo_paxtotal() { if ( pax->validated != 0 ) { - total += pax->komodoshis; + total += pax->puposhis; pax->ready = 1; } else { seed = 0; - checktoshis = komodo_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->komodoshis/COIN,(double)checktoshis/COIN); - //printf(" v%d %.8f k.%d ht.%d\n",pax->vout,dstr(pax->komodoshis),pax->height,pax->otherheight); + 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->komodoshis ) + if ( checktoshis == pax->puposhis ) { - total += pax->komodoshis; - pax->validated = pax->komodoshis; + 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->komodoshis),dstr(pax->fiatoshis),pax->validated != 0,pax->approved != 0,pax->ready,pax->height); + 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); } } } @@ -415,8 +415,8 @@ 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->komodoshis + pax_a->height; - bval = pax_b->fiatoshis + pax_b->komodoshis + pax_b->height; + 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 ) @@ -426,7 +426,7 @@ static int _paxorder(const void *a,const void *b) #undef pax_b } -int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic order +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 ) @@ -438,12 +438,12 @@ int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic { if ( pax->type == 'W' ) { - if ( (pax2= komodo_paxfind(pax->txid,pax->vout,'A')) != 0 ) + if ( (pax2= hush_paxfind(pax->txid,pax->vout,'A')) != 0 ) { if ( pax2->approved != 0 ) pax->approved = pax2->approved; } - else if ( (pax2= komodo_paxfind(pax->txid,pax->vout,'X')) != 0 ) + 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 ) @@ -453,7 +453,7 @@ int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic paxes[n++] = pax; //int32_t j; for (j=0; j<32; j++) // printf("%02x",((uint8_t *)&pax->txid)[j]); - //printf(" %s.(kmdht.%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->komodoshis)); + //printf(" %s.(kmdht.%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)); } } } @@ -466,16 +466,16 @@ int32_t komodo_pending_withdraws(char *opretstr) // todo: enforce deterministic for (i=0; i>3)*7 ) - len += komodo_rwapproval(1,&opretbuf[len],paxes[i]); + len += hush_rwapproval(1,&opretbuf[len],paxes[i]); } if ( len > 0 ) init_hexbytes_noT(opretstr,opretbuf,len); } - //fprintf(stderr,"komodo_pending_withdraws len.%d PAXTOTAL %.8f\n",len,dstr(komodo_paxtotal())); + //fprintf(stderr,"hush_pending_withdraws len.%d PAXTOTAL %.8f\n",len,dstr(hush_paxtotal())); return(len); } -int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t tokomodo) +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 || @@ -505,7 +505,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to else { opcode = 'X'; - if ( 1 || komodo_paxtotal() == 0 ) + if ( 1 || hush_paxtotal() == 0 ) return(0); } HASH_ITER(hh,PAX,pax,tmp) @@ -517,18 +517,18 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to if ( pax->height > 236000 ) { if ( kmdsp != 0 && kmdsp->NOTARIZED_HEIGHT >= pax->height ) - pax->validated = pax->komodoshis; + pax->validated = pax->puposhis; else if ( kmdsp->CURRENT_HEIGHT > pax->height+30 ) pax->validated = pax->ready = 0; } else { if ( kmdsp != 0 && (kmdsp->NOTARIZED_HEIGHT >= pax->height || kmdsp->CURRENT_HEIGHT > pax->height+30) ) // assumes same chain as notarize - pax->validated = pax->komodoshis; + pax->validated = pax->puposhis; else pax->validated = pax->ready = 0; } #else - pax->validated = pax->komodoshis; + pax->validated = pax->puposhis; #endif } if ( SMART_CHAIN_SYMBOL[0] != 0 && (pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,symbol) != 0 || available < pax->fiatoshis) ) @@ -537,7 +537,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to // 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->komodoshis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0); + /*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"); @@ -564,9 +564,9 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to } else continue; } - //printf("redeem.%d? (%c) %p pax.%s marked.%d %.8f -> %.8f ready.%d validated.%d approved.%d\n",tokomodo,pax->type,pax,pax->symbol,pax->marked,dstr(pax->komodoshis),dstr(pax->fiatoshis),pax->ready!=0,pax->validated!=0,pax->approved!=0); + //printf("redeem.%d? (%c) %p pax.%s marked.%d %.8f -> %.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->komodoshis),dstr(pax->fiatoshis)); + 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; @@ -574,7 +574,7 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to break; } txNew->vout.resize(numvouts+1); - txNew->vout[numvouts].nValue = (opcode == 'I') ? pax->fiatoshis : pax->komodoshis; + 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; @@ -593,8 +593,8 @@ int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t to } else { - len += komodo_rwapproval(1,&data[len],pax); - PENDING_HUSH_TX += pax->komodoshis; + 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 ) @@ -665,12 +665,12 @@ int32_t hush_checkvout(int32_t vout,int32_t k,int32_t indallvouts) else return(vout == 0); } -int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max) +int32_t hush_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max) { int32_t i; if ( sizeof(banned_txids)/sizeof(*banned_txids) > max ) { - fprintf(stderr,"komodo_bannedset: buffer too small %d vs %d\n",(int32_t)(sizeof(banned_txids)/sizeof(*banned_txids)),max); + fprintf(stderr,"hush_bannedset: buffer too small %d vs %d\n",(int32_t)(sizeof(banned_txids)/sizeof(*banned_txids)),max); StartShutdown(); } for (i=0; i 195000 || kmdheight <= height) ) + if ( strcmp(base,SMART_CHAIN_SYMBOL) == 0 && (hushheight > 195000 || hushheight <= height) ) { didstats = 0; - if ( komodo_paxcmp(base,kmdheight,value,checktoshis,kmdheight < 225000 ? seed : 0) == 0 ) + if ( hush_paxcmp(base,hushheight,value,checktoshis,hushheight < 225000 ? seed : 0) == 0 ) { - if ( (pax= komodo_paxfind(txid,vout,'D')) == 0 ) + if ( (pax= hush_paxfind(txid,vout,'D')) == 0 ) { if ( (basesp= hush_stateptrget(base)) != 0 ) { basesp->deposited += fiatoshis; didstats = 1; if ( 0 && strcmp(base,SMART_CHAIN_SYMBOL) == 0 ) - printf("########### %p deposited %s += %.8f kmdheight.%d %.8f\n",basesp,base,dstr(fiatoshis),kmdheight,dstr(value)); + printf("########### %p deposited %s += %.8f hushheight.%d %.8f\n",basesp,base,dstr(fiatoshis),hushheight,dstr(value)); } else printf("cant get stateptr.(%s)\n",base); - komodo_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,'D',kmdheight,height,(char *)"HUSH3",0); + hush_gateway_deposit(coinaddr,value,base,fiatoshis,rmd160,txid,vout,'D',hushheight,height,(char *)"HUSH3",0); } - if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) + if ( (pax= hush_paxfind(txid,vout,'D')) != 0 ) { - pax->height = kmdheight; + pax->height = hushheight; pax->validated = value; - pax->komodoshis = value; + pax->puposhis = value; pax->fiatoshis = fiatoshis; if ( didstats == 0 && pax->didstats == 0 ) { @@ -904,15 +904,15 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 basesp->deposited += fiatoshis; didstats = 1; if ( 0 && strcmp(base,SMART_CHAIN_SYMBOL) == 0 ) - printf("########### %p depositedB %s += %.8f/%.8f kmdheight.%d/%d %.8f/%.8f\n",basesp,base,dstr(fiatoshis),dstr(pax->fiatoshis),kmdheight,pax->height,dstr(value),dstr(pax->komodoshis)); + printf("########### %p depositedB %s += %.8f/%.8f hushheight.%d/%d %.8f/%.8f\n",basesp,base,dstr(fiatoshis),dstr(pax->fiatoshis),hushheight,pax->height,dstr(value),dstr(pax->puposhis)); } } // if ( didstats != 0 ) pax->didstats = 1; - if ( (pax2= komodo_paxfind(txid,vout,'I')) != 0 ) + if ( (pax2= hush_paxfind(txid,vout,'I')) != 0 ) { pax2->fiatoshis = pax->fiatoshis; - pax2->komodoshis = pax->komodoshis; + pax2->puposhis = pax->puposhis; pax->marked = pax2->marked = pax->height; pax2->height = pax->height = height; if ( pax2->didstats == 0 ) @@ -922,7 +922,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 basesp->issued += pax2->fiatoshis; pax2->didstats = 1; if ( 0 && strcmp(base,"USD") == 0 ) - printf("########### %p issueda %s += %.8f kmdheight.%d %.8f other.%d [%d]\n",basesp,base,dstr(pax2->fiatoshis),pax2->height,dstr(pax2->komodoshis),pax2->otherheight,height); + printf("########### %p issueda %s += %.8f hushheight.%d %.8f other.%d [%d]\n",basesp,base,dstr(pax2->fiatoshis),pax2->height,dstr(pax2->puposhis),pax2->otherheight,height); } } } @@ -930,12 +930,12 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 } else { - if ( (pax= komodo_paxfind(txid,vout,'D')) != 0 ) + if ( (pax= hush_paxfind(txid,vout,'D')) != 0 ) pax->marked = checktoshis; - if ( kmdheight > 238000 && (kmdheight > 214700 || strcmp(base,SMART_CHAIN_SYMBOL) == 0) ) //seed != 0 && - printf("pax %s deposit %.8f rejected kmdheight.%d %.8f HUSH3 check %.8f seed.%llu\n",base,dstr(fiatoshis),kmdheight,dstr(value),dstr(checktoshis),(long long)seed); + if ( hushheight > 238000 && (hushheight > 214700 || strcmp(base,SMART_CHAIN_SYMBOL) == 0) ) //seed != 0 && + printf("pax %s deposit %.8f rejected hushheight.%d %.8f HUSH3 check %.8f seed.%llu\n",base,dstr(fiatoshis),hushheight,dstr(value),dstr(checktoshis),(long long)seed); } - } //else printf("[%s] %s paxdeposit height.%d vs kmdheight.%d\n",SMART_CHAIN_SYMBOL,base,height,kmdheight); + } //else printf("[%s] %s paxdeposit height.%d vs hushheight.%d\n",SMART_CHAIN_SYMBOL,base,height,hushheight); } //else printf("unsupported size.%d for opreturn D\n",opretlen); } else if ( opretbuf[0] == 'I' ) @@ -943,7 +943,7 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 tokomodo = 0; if ( strncmp((char *)"HUSH3",(char *)&opretbuf[opretlen-4],3) != 0 && strncmp(SMART_CHAIN_SYMBOL,(char *)&opretbuf[opretlen-4],3) == 0 ) { - if ( (n= komodo_issued_opreturn(base,txids,vouts,values,srcvalues,kmdheights,otherheights,baseids,rmd160s,opretbuf,opretlen,0)) > 0 ) + if ( (n= hush_issued_opreturn(base,txids,vouts,values,srcvalues,hushheights,otherheights,baseids,rmd160s,opretbuf,opretlen,0)) > 0 ) { for (i=0; itype = opretbuf[0]; strcpy(pax->source,(char *)&opretbuf[opretlen-4]); - if ( (pax2= komodo_paxfind(txids[i],vouts[i],'D')) != 0 && pax2->fiatoshis != 0 && pax2->komodoshis != 0 ) + if ( (pax2= hush_paxfind(txids[i],vouts[i],'D')) != 0 && pax2->fiatoshis != 0 && pax2->puposhis != 0 ) { // realtime path? pax->fiatoshis = pax2->fiatoshis; - pax->komodoshis = pax2->komodoshis; + pax->puposhis = pax2->puposhis; pax->marked = pax2->marked = pax2->height; if ( pax->didstats == 0 ) { @@ -976,15 +976,15 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 pax->height = pax2->height; pax->otherheight = height; if ( 1 && strcmp(CURRENCIES[baseids[i]],"USD") == 0 ) - printf("########### %p issuedb %s += %.8f kmdheight.%d %.8f other.%d [%d]\n",basesp,CURRENCIES[baseids[i]],dstr(pax->fiatoshis),pax->height,dstr(pax->komodoshis),pax->otherheight,height); + printf("########### %p issuedb %s += %.8f hushheight.%d %.8f other.%d [%d]\n",basesp,CURRENCIES[baseids[i]],dstr(pax->fiatoshis),pax->height,dstr(pax->puposhis),pax->otherheight,height); } } } } - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'I',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'D',height)) != 0 ) - komodo_paxdelete(pax); + if ( (pax= hush_paxmark(height,txids[i],vouts[i],'I',height)) != 0 ) + hush_paxdelete(pax); + if ( (pax= hush_paxmark(height,txids[i],vouts[i],'D',height)) != 0 ) + hush_paxdelete(pax); } } //else printf("opreturn none issued?\n"); } @@ -999,17 +999,17 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 return(typestr); } tokomodo = 1; - dragon_rwnum(0,&opretbuf[34],sizeof(kmdheight),&kmdheight); + dragon_rwnum(0,&opretbuf[34],sizeof(hushheight),&hushheight); memset(base,0,sizeof(base)); - PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&komodoshis); + PAX_pubkey(0,&opretbuf[1],&addrtype,rmd160,base,&shortflag,&puposhis); bitcoin_address(coinaddr,addrtype,rmd160,20); - checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,kmdheight,base,value); + checktoshis = PAX_fiatdest(&seed,tokomodo,destaddr,pubkey33,coinaddr,hushheight,base,value); typestr = "withdraw"; - //printf(" [%s] WITHDRAW %s.height.%d vs height.%d check %.8f/%.8f vs %.8f tokomodo.%d %d seed.%llx -> (%s) len.%d\n",SMART_CHAIN_SYMBOL,base,kmdheight,height,dstr(checktoshis),dstr(komodoshis),dstr(value),hush_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed,coinaddr,opretlen); + //printf(" [%s] WITHDRAW %s.height.%d vs height.%d check %.8f/%.8f vs %.8f tokomodo.%d %d seed.%llx -> (%s) len.%d\n",SMART_CHAIN_SYMBOL,base,hushheight,height,dstr(checktoshis),dstr(puposhis),dstr(value),hush_is_issuer(),strncmp(SMART_CHAIN_SYMBOL,base,strlen(base)) == 0,(long long)seed,coinaddr,opretlen); didstats = 0; - //if ( komodo_paxcmp(base,kmdheight,komodoshis,checktoshis,seed) == 0 ) + //if ( hush_paxcmp(base,hushheight,puposhis,checktoshis,seed) == 0 ) { - if ( value != 0 && ((pax= komodo_paxfind(txid,vout,'W')) == 0 || pax->didstats == 0) ) + if ( value != 0 && ((pax= hush_paxfind(txid,vout,'W')) == 0 || pax->didstats == 0) ) { if ( (basesp= hush_stateptrget(base)) != 0 ) { @@ -1019,19 +1019,19 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 printf("########### %p withdrawn %s += %.8f check %.8f\n",basesp,base,dstr(value),dstr(checktoshis)); } if ( 0 && strcmp(base,"RUB") == 0 && (pax == 0 || pax->approved == 0) ) - printf("notarize %s %.8f -> %.8f kmd.%d other.%d\n",SMART_CHAIN_SYMBOL,dstr(value),dstr(komodoshis),kmdheight,height); + printf("notarize %s %.8f -> %.8f kmd.%d other.%d\n",SMART_CHAIN_SYMBOL,dstr(value),dstr(puposhis),hushheight,height); } - komodo_gateway_deposit(coinaddr,0,(char *)"HUSH3",value,rmd160,txid,vout,'W',kmdheight,height,source,0); - if ( (pax= komodo_paxfind(txid,vout,'W')) != 0 ) + hush_gateway_deposit(coinaddr,0,(char *)"HUSH3",value,rmd160,txid,vout,'W',hushheight,height,source,0); + if ( (pax= hush_paxfind(txid,vout,'W')) != 0 ) { pax->type = opretbuf[0]; strcpy(pax->source,base); strcpy(pax->symbol,"HUSH3"); - pax->height = kmdheight; + pax->height = hushheight; pax->otherheight = height; - pax->komodoshis = komodoshis; + pax->puposhis = puposhis; } - } // else printf("withdraw %s paxcmp ht.%d %d error value %.8f -> %.8f vs %.8f\n",base,kmdheight,height,dstr(value),dstr(komodoshis),dstr(checktoshis)); + } // else printf("withdraw %s paxcmp ht.%d %d error value %.8f -> %.8f vs %.8f\n",base,hushheight,height,dstr(value),dstr(puposhis),dstr(checktoshis)); // need to allocate pax } else if ( height < 236000 && tokomodo != 0 && opretbuf[0] == 'A' && SMART_CHAIN_SYMBOL[0] == 0 ) @@ -1041,22 +1041,22 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 { for (i=0; i 0 ) + if ( (n= hush_issued_opreturn(base,txids,vouts,values,srcvalues,hushheights,otherheights,baseids,rmd160s,opretbuf,opretlen,1)) > 0 ) { for (i=0; isymbol); printf("override neg1 with (%s)\n",pax->symbol); @@ -1066,26 +1066,26 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 } didstats = 0; seed = 0; - checktoshis = komodo_paxprice(&seed,kmdheights[i],CURRENCIES[baseids[i]],(char *)"HUSH3",(uint64_t)values[i]); - //printf("PAX_fiatdest ht.%d price %s %.8f -> HUSH3 %.8f vs %.8f\n",kmdheights[i],CURRENCIES[baseids[i]],(double)values[i]/COIN,(double)srcvalues[i]/COIN,(double)checktoshis/COIN); + checktoshis = hush_paxprice(&seed,hushheights[i],CURRENCIES[baseids[i]],(char *)"HUSH3",(uint64_t)values[i]); + //printf("PAX_fiatdest ht.%d price %s %.8f -> HUSH3 %.8f vs %.8f\n",hushheights[i],CURRENCIES[baseids[i]],(double)values[i]/COIN,(double)srcvalues[i]/COIN,(double)checktoshis/COIN); if ( srcvalues[i] == checktoshis ) { - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) == 0 ) + if ( (pax= hush_paxfind(txids[i],vouts[i],'A')) == 0 ) { bitcoin_address(coinaddr,60,&rmd160s[i*20],20); - komodo_gateway_deposit(coinaddr,srcvalues[i],CURRENCIES[baseids[i]],values[i],&rmd160s[i*20],txids[i],vouts[i],'A',kmdheights[i],otherheights[i],CURRENCIES[baseids[i]],kmdheights[i]); - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) == 0 ) + hush_gateway_deposit(coinaddr,srcvalues[i],CURRENCIES[baseids[i]],values[i],&rmd160s[i*20],txids[i],vouts[i],'A',hushheights[i],otherheights[i],CURRENCIES[baseids[i]],hushheights[i]); + if ( (pax= hush_paxfind(txids[i],vouts[i],'A')) == 0 ) printf("unexpected null pax for approve\n"); else pax->validated = checktoshis; - if ( (pax2= komodo_paxfind(txids[i],vouts[i],'W')) != 0 ) - pax2->approved = kmdheights[i]; - komodo_paxmark(height,txids[i],vouts[i],'W',height); - //komodo_paxmark(height,txids[i],vouts[i],'A',height); + if ( (pax2= hush_paxfind(txids[i],vouts[i],'W')) != 0 ) + pax2->approved = hushheights[i]; + hush_paxmark(height,txids[i],vouts[i],'W',height); + //hush_paxmark(height,txids[i],vouts[i],'A',height); if ( values[i] != 0 && (basesp= hush_stateptrget(CURRENCIES[baseids[i]])) != 0 ) { basesp->approved += values[i]; didstats = 1; - //printf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),kmdheights[i],otherheights[i]); + //printf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),hushheights[i],otherheights[i]); } //printf(" i.%d (%s) <- %.8f ADDFLAG APPROVED\n",i,coinaddr,dstr(values[i])); } @@ -1095,39 +1095,39 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 { basesp->approved += values[i]; didstats = 1; - //printf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),kmdheights[i],otherheights[i]); + //printf("pax.%p ########### %p approved %s += %.8f -> %.8f/%.8f kht.%d %d\n",pax,basesp,CURRENCIES[baseids[i]],dstr(values[i]),dstr(srcvalues[i]),dstr(checktoshis),hushheights[i],otherheights[i]); } } //else printf(" i.%d of n.%d pax.%p baseids[] %d\n",i,n,pax,baseids[i]); - if ( (pax= komodo_paxfind(txids[i],vouts[i],'A')) != 0 ) + if ( (pax= hush_paxfind(txids[i],vouts[i],'A')) != 0 ) { pax->type = opretbuf[0]; - pax->approved = kmdheights[i]; + pax->approved = hushheights[i]; pax->validated = checktoshis; if ( didstats != 0 ) pax->didstats = 1; //if ( strcmp(CURRENCIES[baseids[i]],SMART_CHAIN_SYMBOL) == 0 ) - //printf(" i.%d approved.%d <<<<<<<<<<<<< APPROVED %p\n",i,kmdheights[i],pax); + //printf(" i.%d approved.%d <<<<<<<<<<<<< APPROVED %p\n",i,hushheights[i],pax); } } } } //else printf("n.%d from opreturns\n",n); - //printf("extra.[%d] after %.8f\n",n,dstr(komodo_paxtotal())); + //printf("extra.[%d] after %.8f\n",n,dstr(hush_paxtotal())); } else if ( height < 236000 && opretbuf[0] == 'X' && SMART_CHAIN_SYMBOL[0] == 0 ) { tokomodo = 1; - if ( (n= komodo_issued_opreturn(base,txids,vouts,values,srcvalues,kmdheights,otherheights,baseids,rmd160s,opretbuf,opretlen,1)) > 0 ) + if ( (n= hush_issued_opreturn(base,txids,vouts,values,srcvalues,hushheights,otherheights,baseids,rmd160s,opretbuf,opretlen,1)) > 0 ) { for (i=0; itype = opretbuf[0]; if ( height < 121842 ) // fields got switched around due to legacy issues and approves @@ -1138,17 +1138,17 @@ const char *komodo_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int3 basesp->redeemed += value; pax->didstats = 1; if ( strcmp(CURRENCIES[baseids[i]],SMART_CHAIN_SYMBOL) == 0 ) - printf("ht.%d %.8f ########### %p redeemed %s += %.8f %.8f kht.%d ht.%d\n",height,dstr(value),basesp,CURRENCIES[baseids[i]],dstr(value),dstr(srcvalues[i]),kmdheights[i],otherheights[i]); + printf("ht.%d %.8f ########### %p redeemed %s += %.8f %.8f kht.%d ht.%d\n",height,dstr(value),basesp,CURRENCIES[baseids[i]],dstr(value),dstr(srcvalues[i]),hushheights[i],otherheights[i]); } } - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'W',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'A',height)) != 0 ) - komodo_paxdelete(pax); - if ( (pax= komodo_paxmark(height,txids[i],vouts[i],'X',height)) != 0 ) - komodo_paxdelete(pax); + if ( (pax= hush_paxmark(height,txids[i],vouts[i],'W',height)) != 0 ) + hush_paxdelete(pax); + if ( (pax= hush_paxmark(height,txids[i],vouts[i],'A',height)) != 0 ) + hush_paxdelete(pax); + if ( (pax= hush_paxmark(height,txids[i],vouts[i],'X',height)) != 0 ) + hush_paxdelete(pax); } - } //else printf("komodo_issued_opreturn returned %d\n",n); + } //else printf("hush_issued_opreturn returned %d\n",n); } return(typestr); } @@ -1339,7 +1339,7 @@ long hush_stateind_validate(struct hush_state *sp,char *indfname,uint8_t *fileda return(-1); } -long komodo_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long newfpos,uint8_t func,uint32_t *indcounterp) +long hush_indfile_update(FILE *indfp,uint32_t *prevpos100p,long lastfpos,long newfpos,uint8_t func,uint32_t *indcounterp) { uint32_t tmp; if ( indfp != 0 ) @@ -1375,7 +1375,7 @@ int32_t hush_faststateinit(struct hush_state *sp,char *fname,char *symbol,char * fprintf(stderr,"processing %s %ldKB, validated.%ld\n",fname,datalen/1024,validated); while ( (func= hush_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0 ) { - lastfpos = komodo_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); + lastfpos = hush_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); } if ( indfp != 0 ) { @@ -1400,7 +1400,7 @@ int32_t hush_faststateinit(struct hush_state *sp,char *fname,char *symbol,char * { while ( (func= hush_parsestatefiledata(sp,filedata,&fpos,datalen,symbol,dest)) >= 0 ) { - lastfpos = komodo_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); + lastfpos = hush_indfile_update(indfp,&prevpos100,lastfpos,fpos,func,&indcounter); if ( lastfpos != fpos ) fprintf(stderr,"unexpected lastfpos.%ld != %ld\n",lastfpos,fpos); } @@ -1555,7 +1555,7 @@ void hush_passport_iteration() if ( sp != 0 && isrealtime == 0 ) refsp->RTbufs[0][2] = 0; } - //komodo_paxtotal(); // calls hush_isrealtime(), which calls hush_longestchain() + //hush_paxtotal(); // calls hush_isrealtime(), which calls hush_longestchain() refsp->RTmask |= RTmask; if ( expired == 0 && HUSH_PASSPORT_INITDONE == 0 ) { @@ -1574,13 +1574,13 @@ 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" }; // must be on binance (for now) +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 komodo_extremeprice +struct hush_extremeprice { uint256 blockhash; uint32_t pricebits,timestamp; @@ -1588,7 +1588,7 @@ struct komodo_extremeprice int16_t dir,ind; } ExtremePrice; -struct komodo_priceinfo +struct hush_priceinfo { FILE *fp; char symbol[64]; @@ -1598,7 +1598,7 @@ uint32_t PriceCache[HUSH_LOCALPRICE_CACHESIZE][HUSH_MAXPRICES];//4+sizeof(Crypto int64_t PriceMult[HUSH_MAXPRICES]; int32_t hush_cbopretsize(uint64_t flags); -void komodo_PriceCache_shift() +void hush_PriceCache_shift() { int32_t i; for (i=HUSH_LOCALPRICE_CACHESIZE-1; i>0; i--) @@ -1640,9 +1640,9 @@ int32_t hush_heightpricebits(uint64_t *seedp,uint32_t *heightbits,int32_t nHeigh } /* - komodo_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 + 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 komodo_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance) +uint32_t hush_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t tolerance) { uint64_t highprice,lowprice; if ( refprice < 2 ) @@ -1676,13 +1676,13 @@ uint32_t komodo_pricenew(char *maxflagp,uint32_t price,uint32_t refprice,int64_t return(0); } -// komodo_pricecmp() returns -1 if any of the prices are beyond the tolerance -int32_t komodo_pricecmp(int32_t nHeight,int32_t n,char *maxflags,uint32_t *pricebitsA,uint32_t *pricebitsB,int64_t tolerance) +// 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); @@ -1691,14 +1691,14 @@ int32_t komodo_pricecmp(int32_t nHeight,int32_t n,char *maxflags,uint32_t *price return(0); } -// komodo_priceclamp() clamps any price that is beyond tolerance -int32_t komodo_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int64_t tolerance) +// 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; @@ -1707,8 +1707,8 @@ int32_t komodo_priceclamp(int32_t n,uint32_t *pricebits,uint32_t *refprices,int6 return(0); } -// komodo_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight -CScript komodo_mineropret(int32_t nHeight) +// hush_mineropret() returns a valid pricedata to add to the coinbase opreturn for nHeight +CScript hush_mineropret(int32_t nHeight) { CScript opret; char maxflags[HUSH_MAXPRICES]; uint32_t pricebits[HUSH_MAXPRICES],prevbits[HUSH_MAXPRICES]; int32_t maxflag,i,n,numzero=0; if ( Mineropret.size() >= PRICES_SIZEBIT0 ) @@ -1726,7 +1726,7 @@ CScript komodo_mineropret(int32_t nHeight) } if ( numzero != 0 ) { - fprintf(stderr," komodo_mineropret numzero.%d vs n.%d\n",numzero,n); + fprintf(stderr," hush_mineropret numzero.%d vs n.%d\n",numzero,n); hush_cbopretupdate(1); sleep(61); } @@ -1735,10 +1735,10 @@ CScript komodo_mineropret(int32_t nHeight) { memcpy(pricebits,Mineropret.data(),Mineropret.size()); memset(maxflags,0,sizeof(maxflags)); - if ( komodo_pricecmp(0,n,maxflags,pricebits,prevbits,PRICES_ERRORRATE) < 0 ) + if ( hush_pricecmp(0,n,maxflags,pricebits,prevbits,PRICES_ERRORRATE) < 0 ) { // if the new prices are outside tolerance, update Mineropret with clamped prices - komodo_priceclamp(n,pricebits,prevbits,PRICES_ERRORRATE); + hush_priceclamp(n,pricebits,prevbits,PRICES_ERRORRATE); //fprintf(stderr,"update Mineropret to clamped prices\n"); memcpy(Mineropret.data(),pricebits,Mineropret.size()); } @@ -1761,7 +1761,7 @@ CScript komodo_mineropret(int32_t nHeight) */ -void komodo_queuelocalprice(int32_t dir,int32_t height,uint32_t timestamp,uint256 blockhash,int32_t ind,uint32_t pricebits) +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; @@ -1821,7 +1821,7 @@ int32_t hush_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int if ( pricebits[i] == 0 ) pricebits[i] = prevbits[i]; } - if ( komodo_pricecmp(nHeight,n,maxflags,pricebits,prevbits,PRICES_ERRORRATE) < 0 ) + if ( hush_pricecmp(nHeight,n,maxflags,pricebits,prevbits,PRICES_ERRORRATE) < 0 ) { for (i=1; inTime,bhash,i,prevbits[i]); + hush_queuelocalprice(1,nHeight,block->nTime,bhash,i,prevbits[i]); break; } } @@ -1880,7 +1880,7 @@ int32_t hush_opretvalidate(const CBlock *block,CBlockIndex * const previndex,int } if ( j == HUSH_LOCALPRICE_CACHESIZE ) { - komodo_queuelocalprice(-1,nHeight,block->nTime,bhash,i,prevbits[i]); + hush_queuelocalprice(-1,nHeight,block->nTime,bhash,i,prevbits[i]); break; } } @@ -2250,7 +2250,7 @@ void hush_cbopretupdate(int32_t forceflag) if ( (forceflag != 0 || now > lastbtc+120) && get_btcusd(pricebits) == 0 ) { if ( flags == 0 ) - komodo_PriceCache_shift(); + hush_PriceCache_shift(); memcpy(PriceCache[0],pricebits,PRICES_SIZEBIT0); flags |= 1; } @@ -2260,7 +2260,7 @@ void hush_cbopretupdate(int32_t forceflag) { get_dailyfx(forexprices); if ( flags == 0 ) - komodo_PriceCache_shift(); + hush_PriceCache_shift(); flags |= 2; memcpy(&PriceCache[0][size/sizeof(uint32_t)],forexprices,sizeof(forexprices)); } @@ -2272,7 +2272,7 @@ void hush_cbopretupdate(int32_t forceflag) { get_cryptoprices(pricebuf,Cryptos,(int32_t)(sizeof(Cryptos)/sizeof(*Cryptos)),ASSETCHAINS_PRICES); if ( flags == 0 ) - komodo_PriceCache_shift(); + 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 } @@ -2286,7 +2286,7 @@ void hush_cbopretupdate(int32_t forceflag) if ( get_stockprices(now,pricebuf,ASSETCHAINS_STOCKS) == ASSETCHAINS_STOCKS.size() ) { if ( flags == 0 ) - komodo_PriceCache_shift(); + 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 } @@ -2322,7 +2322,7 @@ void hush_cbopretupdate(int32_t forceflag) pending = 0; } -int64_t komodo_pricemult(int32_t ind) +int64_t hush_pricemult(int32_t ind) { int32_t i,j; if ( (ASSETCHAINS_CBOPRET & 1) != 0 && ind < HUSH_MAXPRICES ) @@ -2352,7 +2352,7 @@ int64_t komodo_pricemult(int32_t ind) return(0); } -char *komodo_pricename(char *name,int32_t ind) +char *hush_pricename(char *name,int32_t ind) { strcpy(name,"error"); if ( (ASSETCHAINS_CBOPRET & 1) != 0 && ind < HUSH_MAXPRICES ) @@ -2416,24 +2416,24 @@ char *komodo_pricename(char *name,int32_t ind) return(0); } // finds index for its symbol name -int32_t komodo_priceind(const char *symbol) +int32_t hush_priceind(const char *symbol) { char name[65]; int32_t i,n = (int32_t)(hush_cbopretsize(ASSETCHAINS_CBOPRET) / sizeof(uint32_t)); for (i=1; i= HUSH_MAXPRICES ) return(-1); - mult = komodo_pricemult(ind); + mult = hush_pricemult(ind); if ( nonzprices != 0 ) memset(nonzprices,0,sizeof(*nonzprices)*PRICES_DAYWINDOW); //for (i=0; i 0 ) + if ( (correlated= hush_pricecorrelated(rngval,ind,&ptr32[offset],-numprices,0,PRICES_SMOOTHWIDTH)) > 0 ) { fseek(PRICES[ind].fp,height * sizeof(int64_t) * PRICES_MAXDATAPOINTS,SEEK_SET); memset(buf,0,sizeof(buf)); @@ -2784,7 +2784,7 @@ void komodo_pricesupdate(int32_t height,CBlock *pblock) 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= komodo_priceave(tmpbuf,&ptr64[(PRICES_DAYWINDOW-1)*PRICES_MAXDATAPOINTS+1],-PRICES_MAXDATAPOINTS)) > 0 ) + 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) ) @@ -2793,7 +2793,7 @@ void komodo_pricesupdate(int32_t height,CBlock *pblock) } 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 komodo_pricecorrelated 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); @@ -2803,7 +2803,7 @@ void komodo_pricesupdate(int32_t height,CBlock *pblock) } else fprintf(stderr,"numprices mismatch, height.%d\n",height); } -int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks) +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); diff --git a/src/hush_globals.h b/src/hush_globals.h index 605d78021..ebb074d03 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -26,11 +26,11 @@ int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *not char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port); void hush_init(int32_t height); int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t hush_isrealtime(int32_t *kmdheightp); -uint64_t komodo_paxtotal(); +int32_t hush_isrealtime(int32_t *hushheightp); +uint64_t hush_paxtotal(); int32_t hush_longestchain(); -uint64_t komodo_maxallowed(int32_t baseid); -int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); +uint64_t hush_maxallowed(int32_t baseid); +int32_t hush_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max); int32_t hush_checkvout(int32_t vout,int32_t k,int32_t indallvouts); pthread_mutex_t hush_mutex; diff --git a/src/hush_nSPV_fullnode.h b/src/hush_nSPV_fullnode.h index a33013b6a..be4fbce15 100644 --- a/src/hush_nSPV_fullnode.h +++ b/src/hush_nSPV_fullnode.h @@ -863,7 +863,7 @@ int32_t NSPV_getspentinfo(struct NSPV_spentinfo *ptr,uint256 txid,int32_t vout) return(len); } -void komodo_nSPVreq(CNode *pfrom,std::vector request) // received a request +void hush_nSPVreq(CNode *pfrom,std::vector request) // received a request { int32_t len,slen,ind,reqheight,n; std::vector response; uint32_t timestamp = (uint32_t)time(NULL); if ( (len= request.size()) > 0 ) diff --git a/src/hush_nSPV_superlite.h b/src/hush_nSPV_superlite.h index aaa0c1724..585f905f0 100644 --- a/src/hush_nSPV_superlite.h +++ b/src/hush_nSPV_superlite.h @@ -128,9 +128,9 @@ struct NSPV_ntzsproofresp *NSPV_ntzsproof_add(struct NSPV_ntzsproofresp *ptr) return(&NSPV_ntzsproofresp_cache[i]); } -// komodo_nSPVresp is called from async message processing +// hush_nSPVresp is called from async message processing -void komodo_nSPVresp(CNode *pfrom,std::vector response) // received a response +void hush_nSPVresp(CNode *pfrom,std::vector response) // received a response { struct NSPV_inforesp I; int32_t len; uint32_t timestamp = (uint32_t)time(NULL); strncpy(NSPV_lastpeer,pfrom->addr.ToString().c_str(),sizeof(NSPV_lastpeer)-1); @@ -274,9 +274,9 @@ UniValue NSPV_logout() return(result); } -// komodo_nSPV from main polling loop (really this belongs in its own file, but it is so small, it ended up here) +// hush_nSPV from main polling loop (really this belongs in its own file, but it is so small, it ended up here) -void komodo_nSPV(CNode *pto) // polling loop from SendMessages +void hush_nSPV(CNode *pto) // polling loop from SendMessages { uint8_t msg[256]; int32_t i,len=0; uint32_t timestamp = (uint32_t)time(NULL); if ( NSPV_logintime != 0 && timestamp > NSPV_logintime+NSPV_AUTOLOGOUT ) diff --git a/src/hush_notary.h b/src/hush_notary.h index a8f792f8f..d9aa60860 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -246,7 +246,7 @@ int32_t hush_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,ui //struct hush_state *hush_stateptr(char *symbol,char *dest); -struct notarized_checkpoint *komodo_npptr_for_height(int32_t height, int *idx) +struct notarized_checkpoint *hush_npptr_for_height(int32_t height, int *idx) { char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; int32_t i; struct hush_state *sp; struct notarized_checkpoint *np = 0; if ( (sp= hush_stateptr(symbol,dest)) != 0 ) @@ -263,13 +263,13 @@ struct notarized_checkpoint *komodo_npptr_for_height(int32_t height, int *idx) return(0); } -struct notarized_checkpoint *komodo_npptr(int32_t height) +struct notarized_checkpoint *hush_npptr(int32_t height) { int idx; - return komodo_npptr_for_height(height, &idx); + return hush_npptr_for_height(height, &idx); } -struct notarized_checkpoint *komodo_npptr_at(int idx) +struct notarized_checkpoint *hush_npptr_at(int idx) { char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; struct hush_state *sp; if ( (sp= hush_stateptr(symbol,dest)) != 0 ) @@ -278,7 +278,7 @@ struct notarized_checkpoint *komodo_npptr_at(int idx) return(0); } -int32_t komodo_prevMoMheight() +int32_t hush_prevMoMheight() { static uint256 zero; char symbol[HUSH_SMART_CHAIN_MAXLEN],dest[HUSH_SMART_CHAIN_MAXLEN]; int32_t i; struct hush_state *sp; struct notarized_checkpoint *np = 0; @@ -314,7 +314,7 @@ int32_t hush_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *tx { *hashp = sp->NOTARIZED_HASH; *txidp = sp->NOTARIZED_DESTTXID; - *prevMoMheightp = komodo_prevMoMheight(); + *prevMoMheightp = hush_prevMoMheight(); } return(sp->NOTARIZED_HEIGHT); } else return(0); @@ -342,7 +342,7 @@ int32_t hush_dpowconfs(int32_t txheight,int32_t numconfs) int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { struct notarized_checkpoint *np = 0; - if ( (np= komodo_npptr(height)) != 0 ) + if ( (np= hush_npptr(height)) != 0 ) { *notarized_htp = np->notarized_height; *MoMp = np->MoM; diff --git a/src/hush_pax.h b/src/hush_pax.h index 242e4d0fe..fe2f946ad 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -133,7 +133,7 @@ uint64_t peggy_smooth_coeffs[sizeof(Peggy_inds)/sizeof(*Peggy_inds)] = // numpri 1, 1, 1, 1, 1, 1, 0, 0, // isum 100000000000 }; -uint64_t komodo_maxallowed(int32_t baseid) +uint64_t hush_maxallowed(int32_t baseid) { uint64_t mult,val = COIN * (uint64_t)10000; if ( baseid < 0 || baseid >= 32 ) @@ -144,7 +144,7 @@ uint64_t komodo_maxallowed(int32_t baseid) return(mult * val); } -uint64_t komodo_paxvol(uint64_t volume,uint64_t price) +uint64_t hush_paxvol(uint64_t volume,uint64_t price) { if ( volume < 10000000000 ) return((volume * price) / 1000000000); @@ -170,7 +170,7 @@ void pax_rank(uint64_t *ranked,uint32_t *pvals) int32_t i; uint64_t vals[32],sum = 0; for (i=0; i<32; i++) { - vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); + vals[i] = hush_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); sum += vals[i]; } for (i=0; i<32; i++) @@ -228,11 +228,11 @@ double PAX_val(uint32_t pval,int32_t baseid) return(0.); } -void komodo_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) +void hush_pvals(int32_t height,uint32_t *pvals,uint8_t numpvals) { } -uint64_t komodo_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed) +uint64_t hush_paxcorrelation(uint64_t *votes,int32_t numvotes,uint64_t seed) { int32_t i,j,k,ind,zeroes,wt,nonz; int64_t delta; uint64_t lastprice,tolerance,den,densum,sum=0; for (sum=i=zeroes=nonz=0; i= 0x4c ) @@ -2292,7 +2292,7 @@ void hush_args(char *argv0) extralen += symbol.size(); } } - //komodo_pricesinit(); + //hush_pricesinit(); hush_cbopretupdate(1); // will set Mineropret fprintf(stderr,"This blockchain uses data produced from CoinDesk Bitcoin Price Index\n"); } @@ -2325,7 +2325,7 @@ void hush_args(char *argv0) if ( (baseid = hush_baseid(SMART_CHAIN_SYMBOL)) >= 0 && baseid < 32 ) { - //komodo_maxallowed(baseid); + //hush_maxallowed(baseid); if(fDebug) printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,SMART_CHAIN_SYMBOL,(double)MAX_MONEY/SATOSHIDEN); } @@ -2381,7 +2381,7 @@ void hush_args(char *argv0) if ( ASSETCHAINS_RPCPORT == 0 ) ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; //ASSETCHAINS_NOTARIES = GetArg("-ac_notaries",""); - //komodo_assetchain_pubkeys((char *)ASSETCHAINS_NOTARIES.c_str()); + //hush_assetchain_pubkeys((char *)ASSETCHAINS_NOTARIES.c_str()); dragon_rwnum(1,magic,sizeof(ASSETCHAINS_MAGIC),(void *)&ASSETCHAINS_MAGIC); for (i=0; i<4; i++) sprintf(&magicstr[i<<1],"%02x",magic[i]); diff --git a/src/main.cpp b/src/main.cpp index eabed2626..537016343 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,7 +82,7 @@ int32_t hush_block2pubkey33(uint8_t *pubkey33,CBlock *block); bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); void hush_setactivation(int32_t height); void hush_changeblocktime(); -void komodo_pricesupdate(int32_t height,CBlock *pblock); +void hush_pricesupdate(int32_t height,CBlock *pblock); BlockMap mapBlockIndex; CChain chainActive; CBlockIndex *pindexBestHeader = NULL; @@ -1423,7 +1423,7 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState { static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n; if ( *(int32_t *)&array[0] == 0 ) - numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array))); + numbanned = hush_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array))); n = tx.vin.size(); if ( SMART_CHAIN_SYMBOL[0] == 0 ) { @@ -4041,7 +4041,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * { //fprintf(stderr,"%s: HUSH_NSPV_FULLNODE\n", __FUNCTION__); if ( ASSETCHAINS_CBOPRET != 0 ) - komodo_pricesupdate(pindexNew->GetHeight(),pblock); + hush_pricesupdate(pindexNew->GetHeight(),pblock); if ( ASSETCHAINS_SAPLING <= 0 && pindexNew->nTime > HUSH_SAPING_ACTIVATION - 24*3600 ) hush_activate_sapling(pindexNew); if ( ASSETCHAINS_CC != 0 && HUSH_SNAPSHOT_INTERVAL != 0 && (pindexNew->GetHeight() % HUSH_SNAPSHOT_INTERVAL) == 0 && pindexNew->GetHeight() >= HUSH_SNAPSHOT_INTERVAL ) @@ -4472,7 +4472,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) if (it != mapBlockIndex.end()) { - if ( it->second != 0 ) // vNodes.size() >= HUSH_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work + if ( it->second != 0 ) // vNodes.size() >= HUSH_LIMITED_NETWORKSIZE { // this is the strange case where somehow the hash is in the mapBlockIndex via as yet undetermined process, but the pindex for the hash is not there. Theoretically it is due to processing the block headers, but I have seen it get this case without having received it from the block headers or anywhere else... jl777 //fprintf(stderr,"addtoblockindex already there %p\n",it->second); @@ -4480,7 +4480,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) } if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 ) { - //fprintf(stderr,"edge case of both block and prevblock in the strange state\n"); + fprintf(stderr,"%s: edge case of both block and prevblock in the strange state\n", __func__); return(0); // return here to avoid the state of pindex->GetHeight() not set and pprev NULL } } @@ -7075,7 +7075,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } std::vector payload; vRecv >> payload; - komodo_netevent(payload); + hush_netevent(payload); return(true); } else if (strCommand == "verack") { pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); @@ -7275,7 +7275,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { std::vector payload; vRecv >> payload; - komodo_nSPVreq(pfrom,payload); + hush_nSPVreq(pfrom,payload); } return(true); } else if (strCommand == "nSPV") { @@ -7283,7 +7283,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { std::vector payload; vRecv >> payload; - komodo_nSPVresp(pfrom,payload); + hush_nSPVresp(pfrom,payload); } return(true); } @@ -8010,7 +8010,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } if ( HUSH_NSPV_SUPERLITE ) { - komodo_nSPV(pto); + hush_nSPV(pto); return(true); } BOOST_FOREACH(const CBlockReject& reject, state.rejects) diff --git a/src/miner.cpp b/src/miner.cpp index 2f4b7495e..02d52abcd 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -147,8 +147,8 @@ int32_t hush_is_notarytx(const CTransaction& tx); uint64_t hush_notarypay(CMutableTransaction &txNew, std::vector &NotarizationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); int32_t hush_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len); -CScript komodo_mineropret(int32_t nHeight); -bool komodo_appendACscriptpub(); +CScript hush_mineropret(int32_t nHeight); +bool hush_appendACscriptpub(); CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake) { @@ -167,7 +167,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 } } else pk = _pk; - uint64_t deposits,voutsum=0; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params(); + uint64_t deposits,voutsum=0; int32_t isrealtime,hushheight; uint32_t blocktime; const CChainParams& chainparams = Params(); bool fNotarizationBlock = false; std::vector NotarizationNotaries; //fprintf(stderr,"create new block\n"); @@ -612,7 +612,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if ( ASSETCHAINS_SCRIPTPUB.size() > 1 ) { static bool didinit = false; - if ( !didinit && nHeight > HUSH_EARLYTXID_HEIGHT && HUSH_EARLYTXID != zeroid && komodo_appendACscriptpub() ) + if ( !didinit && nHeight > HUSH_EARLYTXID_HEIGHT && HUSH_EARLYTXID != zeroid && hush_appendACscriptpub() ) { fprintf(stderr, "appended ccopreturn to ASSETCHAINS_SCRIPTPUB.%s\n", ASSETCHAINS_SCRIPTPUB.c_str()); didinit = true; @@ -667,7 +667,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 int32_t numv = (int32_t)txNew.vout.size(); txNew.vout.resize(numv+1); txNew.vout[numv].nValue = 0; - txNew.vout[numv].scriptPubKey = komodo_mineropret(nHeight); + txNew.vout[numv].scriptPubKey = hush_mineropret(nHeight); //printf("autocreate commision/cbopret.%lld vout[%d]\n",(long long)ASSETCHAINS_CBOPRET,(int32_t)txNew.vout.size()); } pblock->vtx[0] = txNew; @@ -879,7 +879,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake); } -void komodo_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,std::vector payload) +void hush_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,std::vector payload) { int32_t numsent = 0; LOCK(cs_vNodes); @@ -956,7 +956,7 @@ static bool ProcessBlockFound(CBlock* pblock) int32_t hush_baseid(char *origbase); int32_t hush_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height); -arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); +arith_uint256 hush_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); int32_t FOUND_BLOCK,HUSH_MAYBEMINED; extern int32_t HUSH_LASTMINED,HUSH_INSYNC; int32_t roundrobin_delay; @@ -1237,7 +1237,7 @@ void static BitcoinMiner() } else Mining_start = 0; //else if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) - // HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); + // HASHTarget_POW = hush_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); gotinvalid = 0; while (true) { @@ -1462,7 +1462,7 @@ void static BitcoinMiner() HASHTarget.SetCompact(pblock->nBits); hashTarget = HASHTarget; savebits = pblock->nBits; - //hashTarget = HASHTarget_POW = komodo_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); + //hashTarget = HASHTarget_POW = hush_adaptivepow_target(Mining_height,HASHTarget,pblock->nTime); } /*if ( NOTARY_PUBKEY33[0] == 0 ) { @@ -1472,7 +1472,7 @@ void static BitcoinMiner() { // Changing pblock->nTime can change work required on testnet: HASHTarget.SetCompact(pblock->nBits); - HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); + HASHTarget_POW = hush_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); } }*/ } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index bf38cc5e2..6bd65e40f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1027,7 +1027,7 @@ UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) return ret; } -int32_t komodo_pending_withdraws(char *opretstr); +int32_t hush_pending_withdraws(char *opretstr); int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); extern char CURRENCIES[][8]; @@ -1037,7 +1037,7 @@ UniValue paxpending(const UniValue& params, bool fHelp, const CPubKey& mypk) if ( fHelp || params.size() != 0 ) throw runtime_error("paxpending needs no args\n"); LOCK(cs_main); - if ( (opretlen= komodo_pending_withdraws(opretbuf)) > 0 ) + if ( (opretlen= hush_pending_withdraws(opretbuf)) > 0 ) ret.push_back(Pair("withdraws", opretbuf)); else ret.push_back(Pair("withdraws", (char *)"")); for (baseid=0; baseid<32; baseid++) @@ -1076,7 +1076,7 @@ UniValue paxprice(const UniValue& params, bool fHelp, const CPubKey& mypk) else height = atoi(params[2].get_str().c_str()); //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) basevolume = 100000; - relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); + relvolume = hush_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); ret.push_back(Pair("base", base)); ret.push_back(Pair("rel", rel)); ret.push_back(Pair("height", height)); diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 375bbfbd5..7de8a5d7a 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -57,8 +57,8 @@ bool EnsureWalletIsAvailable(bool avoidException); int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); -int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height); -struct hush_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); +int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t hushheight,int32_t notarized_height); +struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); uint256 hush_calcMoM(int32_t height,int32_t MoMdepth); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); extern std::string ASSETCHAINS_SELFIMPORT; diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index d179bd590..ab6a75e96 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -52,7 +52,7 @@ using namespace std; extern int32_t ASSETCHAINS_FOUNDERS; uint64_t the_commission(const CBlock *pblock,int32_t height); int32_t hush_blockload(CBlock& block,CBlockIndex *pindex); -arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); +arith_uint256 hush_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc); /** * Return average network hashes per second based on the last 'lookup' blocks, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f7cc48433..c2a8484e0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -614,7 +614,7 @@ int32_t hush_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t extern int32_t HUSH_PAX; int32_t hush_is_issuer(); int32_t dragon_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t hush_isrealtime(int32_t *kmdheightp); +int32_t hush_isrealtime(int32_t *hushheightp); int32_t pax_fiatstatus(uint64_t *available,uint64_t *deposited,uint64_t *issued,uint64_t *withdrawn,uint64_t *approved,uint64_t *redeemed,char *base); int32_t hush_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[DRAGON_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); int32_t hush_kvcmp(uint8_t *refvalue,uint16_t refvaluesize,uint8_t *value,uint16_t valuesize); @@ -768,7 +768,7 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk) UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk) { - uint64_t available,deposited,issued,withdrawn,approved,redeemed,seed,komodoshis = 0; int32_t height; char destaddr[64]; uint8_t i,pubkey37[33]; + uint64_t available,deposited,issued,withdrawn,approved,redeemed,seed,puposhis = 0; int32_t height; char destaddr[64]; uint8_t i,pubkey37[33]; bool fSubtractFeeFromAmount = false; if ( HUSH_PAX == 0 ) { @@ -793,28 +793,28 @@ UniValue paxdeposit(const UniValue& params, bool fHelp, const CPubKey& mypk) fprintf(stderr,"available %llu vs fiatoshis %llu\n",(long long)available,(long long)fiatoshis); throw runtime_error("paxdeposit not enough available inventory"); } - komodoshis = PAX_fiatdest(&seed,0,destaddr,pubkey37,(char *)params[0].get_str().c_str(),height,(char *)base.c_str(),fiatoshis); + puposhis = PAX_fiatdest(&seed,0,destaddr,pubkey37,(char *)params[0].get_str().c_str(),height,(char *)base.c_str(),fiatoshis); dest.append(destaddr); CBitcoinAddress destaddress(CRYPTO555_HUSHADDR); if (!destaddress.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Bitcoin address"); for (i=0; i<33; i++) fprintf(stderr,"%02x",pubkey37[i]); - fprintf(stderr," ht.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu seed.%llx\n",height,(char *)params[0].get_str().c_str(),(char *)base.c_str(),(long long)fiatoshis,destaddr,(long long)komodoshis,(long long)seed); + fprintf(stderr," ht.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) puposhis.%llu seed.%llx\n",height,(char *)params[0].get_str().c_str(),(char *)base.c_str(),(long long)fiatoshis,destaddr,(long long)puposhis,(long long)seed); EnsureWalletIsUnlocked(); CWalletTx wtx; - uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = komodoshis / 1000; + uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = puposhis / 1000; if ( fee < 10000 ) fee = 10000; dragon_rwnum(1,&pubkey37[33],sizeof(height),&height); opretlen = hush_opreturnscript(opretbuf,'D',pubkey37,37); - SendMoney(address.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,komodoshis); + SendMoney(address.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,puposhis); return wtx.GetHash().GetHex(); } UniValue paxwithdraw(const UniValue& params, bool fHelp, const CPubKey& mypk) { - CWalletTx wtx; std::string dest; int32_t kmdheight; uint64_t seed,komodoshis = 0; char destaddr[64]; uint8_t i,pubkey37[37]; bool fSubtractFeeFromAmount = false; + CWalletTx wtx; std::string dest; int32_t hushheight; uint64_t seed,puposhis = 0; char destaddr[64]; uint8_t i,pubkey37[37]; bool fSubtractFeeFromAmount = false; if ( SMART_CHAIN_SYMBOL[0] == 0 ) return(0); if (!EnsureWalletIsAvailable(fHelp)) @@ -822,26 +822,26 @@ UniValue paxwithdraw(const UniValue& params, bool fHelp, const CPubKey& mypk) throw runtime_error("paxwithdraw deprecated"); if (fHelp || params.size() != 2) throw runtime_error("paxwithdraw address fiatamount"); - if ( hush_isrealtime(&kmdheight) == 0 ) + if ( hush_isrealtime(&hushheight) == 0 ) return(0); LOCK2(cs_main, pwalletMain->cs_wallet); CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); int64_t fiatoshis = atof(params[1].get_str().c_str()) * COIN; - komodoshis = PAX_fiatdest(&seed,1,destaddr,pubkey37,(char *)params[0].get_str().c_str(),kmdheight,SMART_CHAIN_SYMBOL,fiatoshis); + puposhis = PAX_fiatdest(&seed,1,destaddr,pubkey37,(char *)params[0].get_str().c_str(),hushheight,SMART_CHAIN_SYMBOL,fiatoshis); dest.append(destaddr); CBitcoinAddress destaddress(CRYPTO555_HUSHADDR); if (!destaddress.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid dest Bitcoin address"); for (i=0; i<33; i++) printf("%02x",pubkey37[i]); - printf(" kmdheight.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) komodoshis.%llu seed.%llx\n",kmdheight,(char *)params[0].get_str().c_str(),SMART_CHAIN_SYMBOL,(long long)fiatoshis,destaddr,(long long)komodoshis,(long long)seed); + printf(" hushheight.%d srcaddr.(%s) %s fiatoshis.%lld -> dest.(%s) puposhis.%llu seed.%llx\n",hushheight,(char *)params[0].get_str().c_str(),SMART_CHAIN_SYMBOL,(long long)fiatoshis,destaddr,(long long)puposhis,(long long)seed); EnsureWalletIsUnlocked(); uint8_t opretbuf[64]; int32_t opretlen; uint64_t fee = fiatoshis / 1000; if ( fee < 10000 ) fee = 10000; - dragon_rwnum(1,&pubkey37[33],sizeof(kmdheight),&kmdheight); + dragon_rwnum(1,&pubkey37[33],sizeof(hushheight),&hushheight); opretlen = hush_opreturnscript(opretbuf,'W',pubkey37,37); SendMoney(destaddress.Get(),fee,fSubtractFeeFromAmount,wtx,opretbuf,opretlen,fiatoshis); return wtx.GetHash().GetHex(); From 4f15626bb0223252854509899d4d97fd0d9ad652 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 14:24:27 -0400 Subject: [PATCH 094/115] Cleanup --- src/hush.h | 4 ++-- src/hush_bitcoind.h | 4 ++-- src/hush_ccdata.h | 24 ++++++++++++------------ src/hush_gateway.h | 18 +++++++++--------- src/hush_globals.h | 2 +- src/hush_notary.h | 8 ++++---- src/hush_structs.h | 4 ++-- src/rpc/blockchain.cpp | 16 ++++++++-------- src/rpc/crosschain.cpp | 12 ++++++------ src/stratum.cpp | 5 ++--- src/zcash/JoinSplit.cpp | 2 -- 11 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/hush.h b/src/hush.h index 63bbf3dbe..ee9f608f2 100644 --- a/src/hush.h +++ b/src/hush.h @@ -653,8 +653,8 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi // MoMoM, depth, numpairs, (notarization ht, MoMoM offset) if ( len+48-opoffset <= opretlen && strcmp(ccdata.symbol,SMART_CHAIN_SYMBOL) == 0 ) { - len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdstarti); - len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdendi); + len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.hushstarti); + len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.hushendi); len += dragon_rwbignum(0,&scriptbuf[len],sizeof(MoMoMdata.MoMoM),(uint8_t *)&MoMoMdata.MoMoM); len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.MoMoMdepth); len += dragon_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.numpairs); diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index df299d6dd..0aefbcccf 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -868,10 +868,10 @@ int32_t hush_minerids(uint8_t *minerids,int32_t height,int32_t width) return(nonz); } -int32_t hush_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) +int32_t hush_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *hushstartip,int32_t *hushendip) { int32_t depth,notarized_ht; uint256 MoM,hushtxid; - depth = hush_MoMdata(¬arized_ht,&MoM,&hushtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,kmdstartip,kmdendip); + depth = hush_MoMdata(¬arized_ht,&MoM,&hushtxid,nHeight,MoMoMp,MoMoMoffsetp,MoMoMdepthp,hushstartip,hushendip); memset(MoMp,0,sizeof(*MoMp)); memset(hushtxidp,0,sizeof(*hushtxidp)); *notarized_heightp = 0; diff --git a/src/hush_ccdata.h b/src/hush_ccdata.h index 420a7243e..498419ab1 100644 --- a/src/hush_ccdata.h +++ b/src/hush_ccdata.h @@ -41,7 +41,7 @@ uint256 hush_calcMoM(int32_t height,int32_t MoMdepth) return BuildMerkleTree(&fMutated, leaves, tree); } -struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi) +struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t hushstarti,int32_t hushendi) { struct hush_ccdata_entry *allMoMs=0; struct hush_ccdata *ccdata,*tmpptr; int32_t i,num,max; bool fMutated; std::vector tree, leaves; @@ -49,7 +49,7 @@ struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmd portable_mutex_lock(&HUSH_CC_mutex); DL_FOREACH_SAFE(CC_data,ccdata,tmpptr) { - if ( ccdata->MoMdata.height <= kmdendi && ccdata->MoMdata.height >= kmdstarti ) + if ( ccdata->MoMdata.height <= hushendi && ccdata->MoMdata.height >= hushstarti ) { if ( num >= max ) { @@ -63,7 +63,7 @@ struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmd strcpy(allMoMs[num].symbol,ccdata->symbol); num++; } - if ( ccdata->MoMdata.height < kmdstarti ) + if ( ccdata->MoMdata.height < hushstarti ) break; } portable_mutex_unlock(&HUSH_CC_mutex); @@ -116,7 +116,7 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda { if ( ccdata->MoMdata.height < hushheight ) { - //fprintf(stderr,"%s notarized.%d kmd.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height); + //fprintf(stderr,"%s notarized.%d HUSH3.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height); if ( strcmp(ccdata->symbol,symbol) == 0 ) { if ( endi == 0 ) @@ -136,8 +136,8 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda } } portable_mutex_unlock(&HUSH_CC_mutex); - mdata->kmdstarti = starti; - mdata->kmdendi = endi; + mdata->hushstarti = starti; + mdata->hushendi = endi; if ( starti != 0 && endi != 0 && endi >= starti ) { if ( (allMoMs= hush_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 ) @@ -151,8 +151,8 @@ int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mda if ( mdata->numpairs > 0 ) { len += dragon_rwnum(1,&hexdata[len],sizeof(CCid),(uint8_t *)&CCid); - len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdstarti); - len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdendi); + len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->hushstarti); + len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->hushendi); len += dragon_rwbignum(1,&hexdata[len],sizeof(mdata->MoMoM),(uint8_t *)&mdata->MoMoM); len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->MoMoMdepth); len += dragon_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->numpairs); @@ -255,12 +255,12 @@ int32_t hush_rwccdata(char *thischain,int32_t rwflag,struct hush_ccdata *ccdata, np->MoMoM = MoMoMdata->MoMoM; np->MoMoMdepth = MoMoMdata->MoMoMdepth; np->MoMoMoffset = MoMoMdata->MoMoMoffset; - np->kmdstarti = MoMoMdata->kmdstarti; - np->kmdendi = MoMoMdata->kmdendi; + np->hushstarti = MoMoMdata->hushstarti; + np->hushendi = MoMoMdata->hushendi; } - else if ( memcmp(&np->MoMoM,&MoMoMdata->MoMoM,sizeof(np->MoMoM)) != 0 || np->MoMoMdepth != MoMoMdata->MoMoMdepth || np->MoMoMoffset != MoMoMdata->MoMoMoffset || np->kmdstarti != MoMoMdata->kmdstarti || np->kmdendi != MoMoMdata->kmdendi ) + else if ( memcmp(&np->MoMoM,&MoMoMdata->MoMoM,sizeof(np->MoMoM)) != 0 || np->MoMoMdepth != MoMoMdata->MoMoMdepth || np->MoMoMoffset != MoMoMdata->MoMoMoffset || np->hushstarti != MoMoMdata->hushstarti || np->hushendi != MoMoMdata->hushendi ) { - fprintf(stderr,"preexisting MoMoM mismatch: %s (%d %d %d %d) vs %s (%d %d %d %d)\n",np->MoMoM.ToString().c_str(),np->MoMoMdepth,np->MoMoMoffset,np->kmdstarti,np->kmdendi,MoMoMdata->MoMoM.ToString().c_str(),MoMoMdata->MoMoMdepth,MoMoMdata->MoMoMoffset,MoMoMdata->kmdstarti,MoMoMdata->kmdendi); + fprintf(stderr,"preexisting MoMoM mismatch: %s (%d %d %d %d) vs %s (%d %d %d %d)\n",np->MoMoM.ToString().c_str(),np->MoMoMdepth,np->MoMoMoffset,np->hushstarti,np->hushendi,MoMoMdata->MoMoM.ToString().c_str(),MoMoMdata->MoMoMdepth,MoMoMdata->MoMoMoffset,MoMoMdata->hushstarti,MoMoMdata->hushendi); } } } diff --git a/src/hush_gateway.h b/src/hush_gateway.h index b52ab8a1e..2f701cfb6 100644 --- a/src/hush_gateway.h +++ b/src/hush_gateway.h @@ -350,7 +350,7 @@ uint64_t hush_paxtotal() //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 kmd.%d ht.%d %.8f -> %.8f/%.8f\n",pax->vout,pax,pax->source,pax->height,pax->otherheight,dstr(pax->fiatoshis),dstr(pax->puposhis),dstr(checktoshis)); + // 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)); } } } @@ -453,7 +453,7 @@ int32_t hush_pending_withdraws(char *opretstr) // todo: enforce deterministic or paxes[n++] = pax; //int32_t j; for (j=0; j<32; j++) // printf("%02x",((uint8_t *)&pax->txid)[j]); - //printf(" %s.(kmdht.%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)); + //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)); } } } @@ -480,7 +480,7 @@ int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t toko 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 *kmdsp = hush_stateptrget((char *)"HUSH3"); + 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 ) @@ -516,14 +516,14 @@ int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t toko #ifdef HUSH_SMART_CHAINS_WAITNOTARIZE if ( pax->height > 236000 ) { - if ( kmdsp != 0 && kmdsp->NOTARIZED_HEIGHT >= pax->height ) + if ( hushsp != 0 && hushsp->NOTARIZED_HEIGHT >= pax->height ) pax->validated = pax->puposhis; - else if ( kmdsp->CURRENT_HEIGHT > pax->height+30 ) + else if ( hushsp->CURRENT_HEIGHT > pax->height+30 ) pax->validated = pax->ready = 0; } else { - if ( kmdsp != 0 && (kmdsp->NOTARIZED_HEIGHT >= pax->height || kmdsp->CURRENT_HEIGHT > pax->height+30) ) // assumes same chain as notarize + 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; } @@ -546,7 +546,7 @@ int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t toko 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,kmdsp->CURRENT_HEIGHT,pax->height); + 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; } @@ -554,7 +554,7 @@ int32_t hush_gateway_deposits(CMutableTransaction *txNew,char *base,int32_t toko continue; if ( pax->type == 'A' && SMART_CHAIN_SYMBOL[0] == 0 ) { - if ( kmdsp != 0 ) + if ( hushsp != 0 ) { if ( (baseid= hush_baseid(pax->symbol)) < 0 || ((1LL << baseid) & sp->RTmask) == 0 ) { @@ -1019,7 +1019,7 @@ const char *hush_opreturn(int32_t height,uint64_t value,uint8_t *opretbuf,int32_ printf("########### %p withdrawn %s += %.8f check %.8f\n",basesp,base,dstr(value),dstr(checktoshis)); } if ( 0 && strcmp(base,"RUB") == 0 && (pax == 0 || pax->approved == 0) ) - printf("notarize %s %.8f -> %.8f kmd.%d other.%d\n",SMART_CHAIN_SYMBOL,dstr(value),dstr(puposhis),hushheight,height); + printf("notarize %s %.8f -> %.8f HUSH3.%d other.%d\n",SMART_CHAIN_SYMBOL,dstr(value),dstr(puposhis),hushheight,height); } hush_gateway_deposit(coinaddr,0,(char *)"HUSH3",value,rmd160,txid,vout,'W',hushheight,height,source,0); if ( (pax= hush_paxfind(txid,vout,'W')) != 0 ) diff --git a/src/hush_globals.h b/src/hush_globals.h index ebb074d03..7e0a4c17f 100644 --- a/src/hush_globals.h +++ b/src/hush_globals.h @@ -21,7 +21,7 @@ void hush_prefetch(FILE *fp); uint32_t hush_heightstamp(int32_t height); void hush_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void hush_init(int32_t height); -int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *hushstartip,int32_t *hushendip); int32_t hush_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); char *hush_issuemethod(char *userpass,char *method,char *params,uint16_t port); void hush_init(int32_t height); diff --git a/src/hush_notary.h b/src/hush_notary.h index d9aa60860..6090b4f86 100644 --- a/src/hush_notary.h +++ b/src/hush_notary.h @@ -339,7 +339,7 @@ int32_t hush_dpowconfs(int32_t txheight,int32_t numconfs) return(numconfs); } -int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) +int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *hushstartip,int32_t *hushendip) { struct notarized_checkpoint *np = 0; if ( (np= hush_npptr(height)) != 0 ) @@ -350,11 +350,11 @@ int32_t hush_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int *MoMoMp = np->MoMoM; *MoMoMoffsetp = np->MoMoMoffset; *MoMoMdepthp = np->MoMoMdepth; - *kmdstartip = np->kmdstarti; - *kmdendip = np->kmdendi; + *hushstartip = np->hushstarti; + *hushendip = np->hushendi; return(np->MoMdepth & 0xffff); } - *notarized_htp = *MoMoMoffsetp = *MoMoMdepthp = *kmdstartip = *kmdendip = 0; + *notarized_htp = *MoMoMoffsetp = *MoMoMdepthp = *hushstartip = *hushendip = 0; memset(MoMp,0,sizeof(*MoMp)); memset(MoMoMp,0,sizeof(*MoMoMp)); memset(hushtxidp,0,sizeof(*hushtxidp)); diff --git a/src/hush_structs.h b/src/hush_structs.h index 1413f7cb3..121100b55 100644 --- a/src/hush_structs.h +++ b/src/hush_structs.h @@ -88,7 +88,7 @@ struct knotaries_entry { int32_t height,numnotaries; struct knotary_entry *Notar struct notarized_checkpoint { uint256 notarized_hash,notarized_desttxid,MoM,MoMoM; - int32_t nHeight,notarized_height,MoMdepth,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; + int32_t nHeight,notarized_height,MoMdepth,MoMoMdepth,MoMoMoffset,hushstarti,hushendi; }; struct hush_ccdataMoM @@ -103,7 +103,7 @@ struct hush_ccdatapair { int32_t notarized_height,MoMoMoffset; }; struct hush_ccdataMoMoM { uint256 MoMoM; - int32_t kmdstarti,kmdendi,MoMoMoffset,MoMoMdepth,numpairs,len; + int32_t hushstarti,hushendi,MoMoMoffset,MoMoMdepth,numpairs,len; struct hush_ccdatapair *pairs; }; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6bd65e40f..5f3a54d2f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -942,18 +942,18 @@ UniValue minerids(const UniValue& params, bool fHelp, const CPubKey& mypk) } for (i=0; i<64; i++) { - UniValue item(UniValue::VOBJ); std::string hex,hushaddress; char *hexstr,kmdaddr[64],*ptr; int32_t m; + UniValue item(UniValue::VOBJ); std::string hex,hushaddress; char *hexstr,hushaddr[64],*ptr; int32_t m; hex.resize(66); hexstr = (char *)hex.data(); for (j=0; j<33; j++) sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]); item.push_back(Pair("notaryid", i)); - bitcoin_address(kmdaddr,60,pubkeys[i],33); - m = (int32_t)strlen(kmdaddr); + bitcoin_address(hushaddr,60,pubkeys[i],33); + m = (int32_t)strlen(hushaddr); hushaddress.resize(m); ptr = (char *)hushaddress.data(); - memcpy(ptr,kmdaddr,m); + memcpy(ptr,hushaddr,m); item.push_back(Pair("HUSHaddress", hushaddress)); item.push_back(Pair("pubkey", hex)); @@ -973,7 +973,7 @@ UniValue minerids(const UniValue& params, bool fHelp, const CPubKey& mypk) UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) { - UniValue a(UniValue::VARR); uint32_t timestamp=0; UniValue ret(UniValue::VOBJ); int32_t i,j,n,m; char *hexstr; uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr; + UniValue a(UniValue::VARR); uint32_t timestamp=0; UniValue ret(UniValue::VOBJ); int32_t i,j,n,m; char *hexstr; uint8_t pubkeys[64][33]; char btcaddr[64],hushaddr[64],*ptr; if ( fHelp || (params.size() != 1 && params.size() != 2) ) throw runtime_error("notaries height timestamp\n"); LOCK(cs_main); @@ -1011,11 +1011,11 @@ UniValue notaries(const UniValue& params, bool fHelp, const CPubKey& mypk) memcpy(ptr,btcaddr,m); item.push_back(Pair("BTCaddress", btcaddress)); - bitcoin_address(kmdaddr,60,pubkeys[i],33); - m = (int32_t)strlen(kmdaddr); + bitcoin_address(hushaddr,60,pubkeys[i],33); + m = (int32_t)strlen(hushaddr); hushaddress.resize(m); ptr = (char *)hushaddress.data(); - memcpy(ptr,kmdaddr,m); + memcpy(ptr,hushaddr,m); item.push_back(Pair("HUSHaddress", hushaddress)); a.push_back(item); } diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 7de8a5d7a..d3e54dc68 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -56,9 +56,9 @@ int32_t ensure_CCrequirements(uint8_t evalcode); bool EnsureWalletIsAvailable(bool avoidException); -int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); +int32_t hush_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *hushtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *hushstartip,int32_t *hushendip); int32_t hush_MoMoMdata(char *hexstr,int32_t hexsize,struct hush_ccdataMoMoM *mdata,char *symbol,int32_t hushheight,int32_t notarized_height); -struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi); +struct hush_ccdata_entry *hush_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t hushstarti,int32_t hushendi); uint256 hush_calcMoM(int32_t height,int32_t MoMdepth); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); extern std::string ASSETCHAINS_SELFIMPORT; @@ -93,7 +93,7 @@ UniValue crosschainproof(const UniValue& params, bool fHelp, const CPubKey& mypk UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) { - int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,hushtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); + int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,hushstarti,hushendi; uint256 MoM,MoMoM,hushtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); if ( fHelp || params.size() != 1 ) throw runtime_error("height_MoM height\n"); LOCK(cs_main); @@ -108,7 +108,7 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) height = chainActive.Tip()->GetHeight(); } //fprintf(stderr,"height_MoM height.%d\n",height); - depth = hush_MoM(¬arized_height,&MoM,&hushtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&kmdstarti,&kmdendi); + depth = hush_MoM(¬arized_height,&MoM,&hushtxid,height,&MoMoM,&MoMoMoffset,&MoMoMdepth,&hushstarti,&hushendi); ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH" : SMART_CHAIN_SYMBOL))); ret.push_back(Pair("height",height)); ret.push_back(Pair("timestamp",(uint64_t)timestamp)); @@ -123,8 +123,8 @@ UniValue height_MoM(const UniValue& params, bool fHelp, const CPubKey& mypk) ret.push_back(Pair("MoMoM",MoMoM.GetHex())); ret.push_back(Pair("MoMoMoffset",MoMoMoffset)); ret.push_back(Pair("MoMoMdepth",MoMoMdepth)); - ret.push_back(Pair("kmdstarti",kmdstarti)); - ret.push_back(Pair("kmdendi",kmdendi)); + ret.push_back(Pair("hushstarti",hushstarti)); + ret.push_back(Pair("hushendi",hushendi)); } } else ret.push_back(Pair("error",(char *)"no MoM for height")); diff --git a/src/stratum.cpp b/src/stratum.cpp index 4dd30f524..cf5ee5ac6 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -2080,8 +2080,7 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP } else { if (ParseDouble(param_str, &hush_diff)) { - // kmd diff as a str passed - + // hush diff as a str passed // difficulty = difficulty_1_target / current_target arith_uint256 target; ccminer::hush_diff_to_target_equi((uint32_t *)&target, hush_diff); @@ -2091,7 +2090,7 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid difficulty (not hex target, not hush_diff)"); } } else if (params[0].getType() == UniValue::VNUM) { - // kmd diff as a num passed + // hush diff as a num passed hush_diff = params[0].get_real(); // difficulty = difficulty_1_target / current_target diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index d381f3f4b..823d37d06 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -4,10 +4,8 @@ #include "JoinSplit.hpp" #include "prf.h" #include "sodium.h" - #include #include - #include "librustzcash.h" namespace libzcash { From 6bca401f93a492ab55bfdcb5012651fd994c9251 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 22:51:45 -0400 Subject: [PATCH 095/115] Bump version to 3.9.0 --- configure.ac | 4 ++-- src/clientversion.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4f369aebd..42b4cfa0f 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) -define(_CLIENT_VERSION_MINOR, 8) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_MINOR, 9) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/src/clientversion.h b/src/clientversion.h index 375f82690..a6ec2819c 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -29,7 +29,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it // Must be kept in sync with configure.ac , ugh! #define CLIENT_VERSION_MAJOR 3 -#define CLIENT_VERSION_MINOR 8 +#define CLIENT_VERSION_MINOR 9 #define CLIENT_VERSION_REVISION 0 #define CLIENT_VERSION_BUILD 50 From 0f45150aa4aa9431424ca83cf791eb60b65bfb23 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 22:57:42 -0400 Subject: [PATCH 096/115] Update dev docs --- doc/developer-notes.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 26be1e262..e453c762b 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -9,19 +9,28 @@ A fresh sync preserves peers.dat, so it will always be faster than a "fresh clon One way to do a fresh sync is: ``` -cd ~/.komodo/HUSH3 +cd ~/.hush/HUSH3 rm blocks chainstate database notarizations hushstate ``` +NOTE: The legacy directory is ~/.komodo/HUSH3 and hushd will use data from either, or ~/.hush/HUSH3 if both exist. + If you are using `zindex=1` then you need to also delete zindex.dat ``` -cd ~/.komodo/HUSH3 +cd ~/.hush/HUSH3 rm zindex.dat blocks chainstate database notarizations hushstate ``` It's possible to confused hush if you ran old code, stop, restart, and then write out zindex.dat that is incorrect, with later hushds will load from disk and believe. +# Making a new release of Hush + + * Update version in configure.ac and src/clientversion.h + * Run ./contrib/devtools/gen-manpages.sh, commit + push results + * Update checkpoints + * Update protocol version if necessary + # Testing a Branch @@ -37,17 +46,17 @@ git checkout zindexdb # we want to test a fresh sync, so backup current data TIME=`perl -e "print time"` -mv ~/.komodo/{HUSH3,HUSH3-backup-$TIME} -mkdir ~/.komodo/HUSH3 +mv ~/.hush/{HUSH3,HUSH3-backup-$TIME} +mkdir ~/.hush/HUSH3 # Use your previous config as a base -cp ~/.komodo/{HUSH3-backup-$TIME,HUSH3}/HUSH3.conf +cp ~/.hush/{HUSH3-backup-$TIME,HUSH3}/HUSH3.conf # Add zindex to your node -echo "zindex=1" >> ~/.komodo/HUSH3/HUSH3.conf +echo "zindex=1" >> ~/.hush/HUSH3/HUSH3.conf # This is optional but will likely speed up sync time greatly -cp ~/.komodo/{HUSH3-backup,HUSH3}/peers.dat +cp ~/.hush/{HUSH3-backup,HUSH3}/peers.dat # This log file is helpful for debugging more and will contain a history of the # size of the anonset at every block height @@ -77,7 +86,7 @@ These values should match on all nodes: We should also check a recent block height to verify it's working correctly. The big "test" for this `zindexdb` branch is: * If you stop a node, and restart, are the stats from `getchaintxtstats` correct, i.e. the anonset stats? For instance, `shielded_pool_size` should be close to 500000, if it's close to or exactly 0, something is wrong. - * Is there a new file called `zindex.dat` in `~/.komodo/HUSH3/` ? + * Is there a new file called `zindex.dat` in `~/.hush/HUSH3/` ? * Is `zindex.dat` 149 bytes ? # Coding From c1fa2fb723a6ef12c58d9b9be82f78c8840df185 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 22:58:40 -0400 Subject: [PATCH 097/115] dev docs --- doc/developer-notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index e453c762b..2f8d7bfdf 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -30,6 +30,8 @@ It's possible to confused hush if you ran old code, stop, restart, and then writ * Run ./contrib/devtools/gen-manpages.sh, commit + push results * Update checkpoints * Update protocol version if necessary + * Make Gitea release + * Make Git Tag (Gitea can do this) # Testing a Branch From b0a1395f21aece667c7e2a1073c5235ea391cf4e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 23:02:09 -0400 Subject: [PATCH 098/115] Fix unix manpage stuff --- doc/man/Makefile.am | 2 +- doc/man/komodo-cli.1 | 90 ------ doc/man/komodo-tx.1 | 103 ------- doc/man/komodod.1 | 637 ------------------------------------------- 4 files changed, 1 insertion(+), 831 deletions(-) delete mode 100644 doc/man/komodo-cli.1 delete mode 100644 doc/man/komodo-tx.1 delete mode 100644 doc/man/komodod.1 diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 98a1278d8..13be3322e 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1 +1 @@ -dist_man1_MANS=komodod.1 komodo-cli.1 komodo-tx.1 +dist_man1_MANS=hushd.1 hush-cli.1 hush-tx.1 diff --git a/doc/man/komodo-cli.1 b/doc/man/komodo-cli.1 deleted file mode 100644 index b7d195400..000000000 --- a/doc/man/komodo-cli.1 +++ /dev/null @@ -1,90 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH KOMODO-CLI "1" "December 2019" "komodo-cli v3.3.0" "User Commands" -.SH NAME -komodo-cli \- manual page for komodo-cli v3.3.0 -.SH DESCRIPTION -Komodo RPC client version v3.3.0\-bde7744d9 -.PP -In order to ensure you are adequately protecting your privacy when using Hush, -please see . -.SS "Usage:" -.TP -komodo\-cli [options] [params] -Send command to Komodo -.TP -komodo\-cli [options] help -List commands -.TP -komodo\-cli [options] help -Get help for a command -.SH OPTIONS -.HP -\-? -.IP -This help message -.HP -\fB\-conf=\fR -.IP -Specify configuration file (default: komodo.conf) -.HP -\fB\-datadir=\fR -.IP -Specify data directory -.HP -\fB\-testnet\fR -.IP -Use the test network -.HP -\fB\-regtest\fR -.IP -Enter regression test mode, which uses a special chain in which blocks -can be solved instantly. This is intended for regression testing tools -and app development. -.HP -\fB\-rpcconnect=\fR -.IP -Send commands to node running on (default: 127.0.0.1) -.HP -\fB\-rpcport=\fR -.IP -Connect to JSON\-RPC on (default: 8232 or testnet: 18232) -.HP -\fB\-rpcwait\fR -.IP -Wait for RPC server to start -.HP -\fB\-rpcuser=\fR -.IP -Username for JSON\-RPC connections -.HP -\fB\-rpcpassword=\fR -.IP -Password for JSON\-RPC connections -.HP -\fB\-rpcclienttimeout=\fR -.IP -Timeout in seconds during HTTP requests, or 0 for no timeout. (default: -900) -.HP -\fB\-stdin\fR -.IP -Read extra arguments from standard input, one per line until EOF/Ctrl\-D -(recommended for sensitive information such as passphrases) -.SH COPYRIGHT - -In order to ensure you are adequately protecting your privacy when using Hush, -please see . - -Copyright (C) 2009-2019 The Bitcoin Core Developers -Copyright (C) 2015-2019 The Zcash Developers -Copyright (C) 2015-2019 jl777 and SuperNET developers -Copyright (C) 2018-2019 The Hush developers - -This is experimental software!!! - -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young. diff --git a/doc/man/komodo-tx.1 b/doc/man/komodo-tx.1 deleted file mode 100644 index 511ce5158..000000000 --- a/doc/man/komodo-tx.1 +++ /dev/null @@ -1,103 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH KOMODO-TX "1" "December 2019" "komodo-tx v3.3.0" "User Commands" -.SH NAME -komodo-tx \- manual page for komodo-tx v3.3.0 -.SH DESCRIPTION -Hush komodo\-tx utility version v3.3.0\-bde7744d9 -.SS "Usage:" -.TP -komodo\-tx [options] [commands] -Update hex\-encoded zcash transaction -.TP -komodo\-tx [options] \fB\-create\fR [commands] -Create hex\-encoded zcash transaction -.SH OPTIONS -.HP -\-? -.IP -This help message -.HP -\fB\-create\fR -.IP -Create new, empty TX. -.HP -\fB\-json\fR -.IP -Select JSON output -.HP -\fB\-txid\fR -.IP -Output only the hex\-encoded transaction id of the resultant transaction. -.HP -\fB\-regtest\fR -.IP -Enter regression test mode, which uses a special chain in which blocks -can be solved instantly. -.HP -\fB\-testnet\fR -.IP -Use the test network -.PP -Commands: -.IP -delin=N -.IP -Delete input N from TX -.IP -delout=N -.IP -Delete output N from TX -.IP -in=TXID:VOUT(:SEQUENCE_NUMBER) -.IP -Add input to TX -.IP -locktime=N -.IP -Set TX lock time to N -.IP -nversion=N -.IP -Set TX version to N -.IP -outaddr=VALUE:ADDRESS -.IP -Add address\-based output to TX -.IP -outscript=VALUE:SCRIPT -.IP -Add raw script output to TX -.IP -sign=HEIGHT:SIGHASH\-FLAGS -.IP -Add zero or more signatures to transaction. This command requires JSON -registers:prevtxs=JSON object, privatekeys=JSON object. See -signrawtransaction docs for format of sighash flags, JSON objects. -.PP -Register Commands: -.IP -load=NAME:FILENAME -.IP -Load JSON file FILENAME into register NAME -.IP -set=NAME:JSON\-STRING -.IP -Set register NAME to given JSON\-STRING -.SH COPYRIGHT - -In order to ensure you are adequately protecting your privacy when using Hush, -please see . - -Copyright (C) 2009-2019 The Bitcoin Core Developers -Copyright (C) 2015-2019 The Zcash Developers -Copyright (C) 2015-2019 jl777 and SuperNET developers -Copyright (C) 2018-2019 The Hush developers - -This is experimental software!!! - -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young. diff --git a/doc/man/komodod.1 b/doc/man/komodod.1 deleted file mode 100644 index 9f7c9b6f1..000000000 --- a/doc/man/komodod.1 +++ /dev/null @@ -1,637 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH KOMODOD "1" "December 2019" "komodod v3.3.0" "User Commands" -.SH NAME -komodod \- manual page for komodod v3.3.0 -.SH DESCRIPTION -Hush Daemon version v3.3.0\-bde7744d9 -.PP -In order to ensure you are adequately protecting your privacy when using Hush, -please see . -.SS "Usage:" -.TP -komodod [options] -Start Hush\-flavored Komodo Daemon -.SH OPTIONS -.HP -\-? -.IP -This help message -.HP -\fB\-alerts\fR -.IP -Receive and display P2P network alerts (default: 1) -.HP -\fB\-alertnotify=\fR -.IP -Execute command when a relevant alert is received or we see a really -long fork (%s in cmd is replaced by message) -.HP -\fB\-blocknotify=\fR -.IP -Execute command when the best block changes (%s in cmd is replaced by -block hash) -.HP -\fB\-checkblocks=\fR -.IP -How many blocks to check at startup (default: 288, 0 = all) -.HP -\fB\-checklevel=\fR -.IP -How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) -.HP -\fB\-clientname=\fR -.IP -Full node client name, default 'MagicBean' -.HP -\fB\-conf=\fR -.IP -Specify configuration file (default: komodo.conf) -.HP -\fB\-daemon\fR -.IP -Run in the background as a daemon and accept commands -.HP -\fB\-datadir=\fR -.IP -Specify data directory -.HP -\fB\-exportdir=\fR -.IP -Specify directory to be used when exporting data -.HP -\fB\-dbcache=\fR -.IP -Set database cache size in megabytes (4 to 16384, default: 450) -.HP -\fB\-loadblock=\fR -.IP -Imports blocks from external blk000??.dat file on startup -.HP -\fB\-maxorphantx=\fR -.IP -Keep at most unconnectable transactions in memory (default: 100) -.HP -\fB\-mempooltxinputlimit=\fR -.IP -[DEPRECATED FROM OVERWINTER] Set the maximum number of transparent -inputs in a transaction that the mempool will accept (default: 0 = no -limit applied) -.HP -\fB\-par=\fR -.IP -Set the number of script verification threads (\fB\-8\fR to 16, 0 = auto, <0 = -leave that many cores free, default: 0) -.HP -\fB\-pid=\fR -.IP -Specify pid file (default: komodod.pid) -.HP -\fB\-prune=\fR -.IP -Reduce storage requirements by pruning (deleting) old blocks. This mode -disables wallet support and is incompatible with \fB\-txindex\fR. Warning: -Reverting this setting requires re\-downloading the entire blockchain. -(default: 0 = disable pruning blocks, >550 = target size in MiB to use -for block files) -.HP -\fB\-reindex\fR -.IP -Rebuild block chain index from current blk000??.dat files on startup -.HP -\fB\-sysperms\fR -.IP -Create new files with system default permissions, instead of umask 077 -(only effective with disabled wallet functionality) -.HP -\fB\-txindex\fR -.IP -Maintain a full transaction index, used by the getrawtransaction rpc -call (default: 0) -.HP -\fB\-addressindex\fR -.IP -Maintain a full address index, used to query for the balance, txids and -unspent outputs for addresses (default: 0) -.HP -\fB\-timestampindex\fR -.IP -Maintain a timestamp index for block hashes, used to query blocks hashes -by a range of timestamps (default: 0) -.HP -\fB\-spentindex\fR -.IP -Maintain a full spent index, used to query the spending txid and input -index for an outpoint (default: 0) -.HP -\fB\-zindex\fR -.IP -Maintain extra statistics about shielded transactions and payments -(default: 0) -.PP -Connection options: -.HP -\fB\-addnode=\fR -.IP -Add a node to connect to and attempt to keep the connection open -.HP -\fB\-banscore=\fR -.IP -Threshold for disconnecting misbehaving peers (default: 100) -.HP -\fB\-bantime=\fR -.IP -Number of seconds to keep misbehaving peers from reconnecting (default: -86400) -.HP -\fB\-bind=\fR -.IP -Bind to given address and always listen on it. Use [host]:port notation -for IPv6 -.HP -\fB\-connect=\fR -.IP -Connect only to the specified node(s) -.HP -\fB\-discover\fR -.IP -Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR -or \fB\-proxy\fR) -.HP -\fB\-dns\fR -.IP -Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) -.HP -\fB\-dnsseed\fR -.IP -Query for peer addresses via DNS lookup, if low on addresses (default: 1 -unless \fB\-connect\fR) -.HP -\fB\-externalip=\fR -.IP -Specify your own public address -.HP -\fB\-forcednsseed\fR -.IP -Always query for peer addresses via DNS lookup (default: 0) -.HP -\fB\-listen\fR -.IP -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) -.HP -\fB\-listenonion\fR -.IP -Automatically create Tor hidden service (default: 1) -.HP -\fB\-maxconnections=\fR -.IP -Maintain at most connections to peers (default: 384) -.HP -\fB\-maxreceivebuffer=\fR -.IP -Maximum per\-connection receive buffer, *1000 bytes (default: 5000) -.HP -\fB\-maxsendbuffer=\fR -.IP -Maximum per\-connection send buffer, *1000 bytes (default: 1000) -.HP -\fB\-onion=\fR -.IP -Use separate SOCKS5 proxy to reach peers via Tor hidden services -(default: \fB\-proxy\fR) -.HP -\fB\-onlynet=\fR -.IP -Only connect to nodes in network (ipv4, ipv6 or onion) -.HP -\fB\-permitbaremultisig\fR -.IP -Relay non\-P2SH multisig (default: 1) -.HP -\fB\-peerbloomfilters\fR -.IP -Support filtering of blocks and transaction with Bloom filters (default: -1) -.HP -\fB\-port=\fR -.IP -Listen for connections on (default: 7770 or testnet: 17770) -.HP -\fB\-proxy=\fR -.IP -Connect through SOCKS5 proxy -.HP -\fB\-proxyrandomize\fR -.IP -Randomize credentials for every proxy connection. This enables Tor -stream isolation (default: 1) -.HP -\fB\-seednode=\fR -.IP -Connect to a node to retrieve peer addresses, and disconnect -.HP -\fB\-timeout=\fR -.IP -Specify connection timeout in milliseconds (minimum: 1, default: 5000) -.HP -\fB\-torcontrol=\fR: -.IP -Tor control port to use if onion listening enabled (default: -127.0.0.1:9051) -.HP -\fB\-torpassword=\fR -.IP -Tor control port password (default: empty) -.HP -\fB\-whitebind=\fR -.IP -Bind to given address and whitelist peers connecting to it. Use -[host]:port notation for IPv6 -.HP -\fB\-whitelist=\fR -.IP -Whitelist peers connecting from the given netmask or IP address. Can be -specified multiple times. Whitelisted peers cannot be DoS banned and -their transactions are always relayed, even if they are already in the -mempool, useful e.g. for a gateway -.PP -Wallet options: -.HP -\fB\-disablewallet\fR -.IP -Do not load the wallet and disable wallet RPC calls -.HP -\fB\-keypool=\fR -.IP -Set key pool size to (default: 100) -.HP -\fB\-paytxfee=\fR -.IP -Fee (in KMD/kB) to add to transactions you send (default: 0.00) -.HP -\fB\-rescan\fR -.IP -Rescan the block chain for missing wallet transactions on startup -.HP -\fB\-salvagewallet\fR -.IP -Attempt to recover private keys from a corrupt wallet.dat on startup -.HP -\fB\-sendfreetransactions\fR -.IP -Send transactions as zero\-fee transactions if possible (default: 0) -.HP -\fB\-spendzeroconfchange\fR -.IP -Spend unconfirmed change when sending transactions (default: 1) -.HP -\fB\-txconfirmtarget=\fR -.IP -If paytxfee is not set, include enough fee so transactions begin -confirmation on average within n blocks (default: 2) -.HP -\fB\-txexpirydelta\fR -.IP -Set the number of blocks after which a transaction that has not been -mined will become invalid (default: 200) -.HP -\fB\-maxtxfee=\fR -.IP -Maximum total fees (in KMD) to use in a single wallet transaction; -setting this too low may abort large transactions (default: 0.10) -.HP -\fB\-upgradewallet\fR -.IP -Upgrade wallet to latest format on startup -.HP -\fB\-wallet=\fR -.IP -Specify wallet file (within data directory) (default: wallet.dat) -.HP -\fB\-walletbroadcast\fR -.IP -Make the wallet broadcast transactions (default: 1) -.HP -\fB\-walletnotify=\fR -.IP -Execute command when a wallet transaction changes (%s in cmd is replaced -by TxID) -.HP -\fB\-whitelistaddress=\fR -.IP -Enable the wallet filter for notary nodes and add one Raddress to the -whitelist of the wallet filter. If \fB\-whitelistaddress=\fR is used, then the -wallet filter is automatically activated. Several Raddresses can be -defined using several \fB\-whitelistaddress=\fR (similar to \fB\-addnode\fR). The -wallet filter will filter the utxo to only ones coming from my own -Raddress (derived from pubkey) and each Raddress defined using -\fB\-whitelistaddress=\fR this option is mostly for Notary Nodes). -.HP -\fB\-zapwallettxes=\fR -.IP -Delete all wallet transactions and only recover those parts of the -blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. -account owner and payment request information, 2 = drop tx meta data) -.PP -ZeroMQ notification options: -.HP -\fB\-zmqpubhashblock=\fR
    -.IP -Enable publish hash block in
    -.HP -\fB\-zmqpubhashtx=\fR
    -.IP -Enable publish hash transaction in
    -.HP -\fB\-zmqpubrawblock=\fR
    -.IP -Enable publish raw block in
    -.HP -\fB\-zmqpubrawtx=\fR
    -.IP -Enable publish raw transaction in
    -.PP -Debugging/Testing options: -.HP -\fB\-debug=\fR -.IP -Output debugging information (default: 0, supplying is -optional). If is not supplied or if = 1, output -all debugging information. can be: addrman, alert, bench, -coindb, db, estimatefee, http, libevent, lock, mempool, net, -partitioncheck, pow, proxy, prune, rand, reindex, rpc, selectcoins, tor, -zmq, zrpc, zrpcunsafe (implies zrpc). -.HP -\fB\-experimentalfeatures\fR -.IP -Enable use of experimental features -.HP -\fB\-help\-debug\fR -.IP -Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) -.HP -\fB\-logips\fR -.IP -Include IP addresses in debug output (default: 0) -.HP -\fB\-logtimestamps\fR -.IP -Prepend debug output with timestamp (default: 1) -.HP -\fB\-minrelaytxfee=\fR -.IP -Fees (in KMD/kB) smaller than this are considered zero fee for relaying -(default: 0.000001) -.HP -\fB\-printtoconsole\fR -.IP -Send trace/debug info to console instead of debug.log file -.HP -\fB\-shrinkdebugfile\fR -.IP -Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) -.HP -\fB\-testnet\fR -.IP -Use the test network -.PP -Node relay options: -.HP -\fB\-datacarrier\fR -.IP -Relay and mine data carrier transactions (default: 1) -.HP -\fB\-datacarriersize\fR -.IP -Maximum size of data in data carrier transactions we relay and mine -(default: 8192) -.PP -Block creation options: -.HP -\fB\-blockminsize=\fR -.IP -Set minimum block size in bytes (default: 0) -.HP -\fB\-blockmaxsize=\fR -.IP -Set maximum block size in bytes (default: 2000000) -.HP -\fB\-blockprioritysize=\fR -.IP -Set maximum size of high\-priority/low\-fee transactions in bytes -(default: 1000000) -.PP -Mining options: -.HP -\fB\-mint\fR -.IP -Mint/stake coins automatically (default: 0) -.HP -\fB\-gen\fR -.IP -Mine/generate coins (default: 0) -.HP -\fB\-genproclimit=\fR -.IP -Set the number of threads for coin mining if enabled (\fB\-1\fR = all cores, -default: 0) -.HP -\fB\-equihashsolver=\fR -.IP -Specify the Equihash solver to be used if enabled (default: "default") -.HP -\fB\-mineraddress=\fR -.IP -Send mined coins to a specific single address -.HP -\fB\-minetolocalwallet\fR -.IP -Require that mined blocks use a coinbase address in the local wallet -(default: 1) -.PP -RPC server options: -.HP -\fB\-server\fR -.IP -Accept command line and JSON\-RPC commands -.HP -\fB\-rest\fR -.IP -Accept public REST requests (default: 0) -.HP -\fB\-rpcbind=\fR -.IP -Bind to given address to listen for JSON\-RPC connections. Use -[host]:port notation for IPv6. This option can be specified multiple -times (default: bind to all interfaces) -.HP -\fB\-rpcuser=\fR -.IP -Username for JSON\-RPC connections -.HP -\fB\-rpcpassword=\fR -.IP -Password for JSON\-RPC connections -.HP -\fB\-rpcport=\fR -.IP -Listen for JSON\-RPC connections on (default: 7771 or testnet: -17771) -.HP -\fB\-rpcallowip=\fR -.IP -Allow JSON\-RPC connections from specified source. Valid for are a -single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) -or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified -multiple times -.HP -\fB\-rpcthreads=\fR -.IP -Set the number of threads to service RPC calls (default: 4) -.PP -Metrics Options (only if \fB\-daemon\fR and \fB\-printtoconsole\fR are not set): -.HP -\fB\-showmetrics\fR -.IP -Show metrics on stdout (default: 1 if running in a console, 0 otherwise) -.HP -\fB\-metricsui\fR -.IP -Set to 1 for a persistent metrics screen, 0 for sequential metrics -output (default: 1 if running in a console, 0 otherwise) -.HP -\fB\-metricsrefreshtime\fR -.IP -Number of seconds between metrics refreshes (default: 1 if running in a -console, 600 otherwise) -.PP -Komodo Asset Chain options: -.HP -\fB\-ac_algo\fR -.IP -Choose PoW mining algorithm, default is Equihash -.HP -\fB\-ac_blocktime\fR -.IP -Block time in seconds, default is 60 -.HP -\fB\-ac_cc\fR -.IP -Cryptoconditions, default 0 -.HP -\fB\-ac_beam\fR -.IP -BEAM integration -.HP -\fB\-ac_coda\fR -.IP -CODA integration -.HP -\fB\-ac_cclib\fR -.IP -Cryptoconditions dynamicly loadable library -.HP -\fB\-ac_ccenable\fR -.IP -Cryptoconditions to enable -.HP -\fB\-ac_ccactivate\fR -.IP -Block height to enable Cryptoconditions -.HP -\fB\-ac_decay\fR -.IP -Percentage of block reward decrease at each halving -.HP -\fB\-ac_end\fR -.IP -Block height at which block rewards will end -.HP -\fB\-ac_eras\fR -.IP -Block reward eras -.HP -\fB\-ac_founders\fR -.IP -Number of blocks between founders reward payouts -.HP -\fB\-ac_halving\fR -.IP -Number of blocks between each block reward halving -.HP -\fB\-ac_name\fR -.IP -Name of asset chain -.HP -\fB\-ac_notarypay\fR -.IP -Pay notaries, default 0 -.HP -\fB\-ac_perc\fR -.IP -Percentage of block rewards paid to the founder -.HP -\fB\-ac_private\fR -.IP -Shielded transactions only (except coinbase + notaries), default is 0 -.HP -\fB\-ac_pubkey\fR -.IP -Public key for receiving payments on the network -.HP -\fB\-ac_public\fR -.IP -Transparent transactions only, default 0 -.HP -\fB\-ac_reward\fR -.IP -Block reward in satoshis, default is 0 -.HP -\fB\-ac_sapling\fR -.IP -Sapling activation block height -.HP -\fB\-ac_script\fR -.IP -P2SH/multisig address to receive founders rewards -.HP -\fB\-ac_staked\fR -.IP -Percentage of blocks that are Proof\-Of\-Stake, default 0 -.HP -\fB\-ac_supply\fR -.IP -Starting supply, default is 0 -.HP -\fB\-ac_timelockfrom\fR -.IP -Timelocked coinbase start height -.HP -\fB\-ac_timelockgte\fR -.IP -Timelocked coinbase minimum amount to be locked -.HP -\fB\-ac_timelockto\fR -.IP -Timelocked coinbase stop height -.HP -\fB\-ac_txpow\fR -.IP -Enforce transaction\-rate limit, default 0 -.SH COPYRIGHT - -In order to ensure you are adequately protecting your privacy when using Hush, -please see . - -Copyright (C) 2009-2019 The Bitcoin Core Developers -Copyright (C) 2015-2019 The Zcash Developers -Copyright (C) 2015-2019 jl777 and SuperNET developers -Copyright (C) 2018-2019 The Hush developers - -This is experimental software!!! - -Distributed under the MIT software license, see the accompanying file COPYING -or . - -This product includes software developed by the OpenSSL Project for use in the -OpenSSL Toolkit and cryptographic software written -by Eric Young. From ff1c90ffc8c140b2d308612926766e70f4cd8962 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 23:04:38 -0400 Subject: [PATCH 099/115] update docs --- doc/wallet-backup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/wallet-backup.md b/doc/wallet-backup.md index b229211ab..e1173f0da 100644 --- a/doc/wallet-backup.md +++ b/doc/wallet-backup.md @@ -16,7 +16,7 @@ These instructions are specific for the officially supported Hush Linux client. There are multiple ways to make sure you have at least one other copy of the private keys needed to spend your HUSH and view your shielded HUSH. -For all methods, you will need to include an export directory setting in your config file (`HUSH3.conf` located in the data directory which is `~/.komodo/HUSH3` unless it's been overridden with `datadir=` setting): +For all methods, you will need to include an export directory setting in your config file (`HUSH3.conf` located in the data directory which is `~/.hush/HUSH3` or `~/.komodo/HUSH3` (Legacy Location) unless it's been overridden with `datadir=` setting): `exportdir=path/to/chosen/export/directory` From 7e8b8795be5eb1a1c902f439c67ececad330e9cc Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 23:13:44 -0400 Subject: [PATCH 100/115] Update protocol version --- src/clientversion.cpp | 2 +- src/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clientversion.cpp b/src/clientversion.cpp index dd52311bb..5702fbb95 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -32,7 +32,7 @@ * for both bitcoind and bitcoin-core, to make it harder for attackers to * target servers or GUI users specifically. */ -const std::string CLIENT_NAME = GetArg("-clientname", "jl777sRemorse"); +const std::string CLIENT_NAME = GetArg("-clientname", "GoldenSandtrout"); /** * Client version number diff --git a/src/version.h b/src/version.h index 3c8f28347..a08199ef3 100644 --- a/src/version.h +++ b/src/version.h @@ -21,7 +21,7 @@ #define HUSH_VERSION_H // network protocol versioning -static const int PROTOCOL_VERSION = 1987423; +static const int PROTOCOL_VERSION = 1987424; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; //! In this version, 'getheaders' was introduced. From 2c2684374340c5a0512d8f8f60f39e3fb7d10402 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Sep 2021 23:19:28 -0400 Subject: [PATCH 101/115] More dev notes --- doc/developer-notes.md | 7 ++++--- src/sync.cpp | 3 --- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 2f8d7bfdf..3e5c42cfc 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -29,7 +29,7 @@ It's possible to confused hush if you ran old code, stop, restart, and then writ * Update version in configure.ac and src/clientversion.h * Run ./contrib/devtools/gen-manpages.sh, commit + push results * Update checkpoints - * Update protocol version if necessary + * Update protocol version in src/version.h if necessary * Make Gitea release * Make Git Tag (Gitea can do this) @@ -146,8 +146,9 @@ on all categories (and give you a very large debug.log file). **testnet and regtest modes** -Run with the -testnet option to run with "play zcash" on the test network, if you -are testing multi-machine code that needs to operate across the internet. +Run with the -testnet option to run with "play HUSH" on the test network, if you +are testing multi-machine code that needs to operate across the internet. You can +also make a Hush Smart Chain "testcoin" with a single command: `hushd -ac_name=COIN ...` If you are testing something that can run on one machine, run with the -regtest option. In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests diff --git a/src/sync.cpp b/src/sync.cpp index 6b8fd38f9..209dd9edb 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -19,12 +19,9 @@ ******************************************************************************/ #include "sync.h" - #include "util.h" #include "utilstrencodings.h" - #include - #include #include From cd2f366496cd0a58310ca6baf2136b6dcbe14bcc Mon Sep 17 00:00:00 2001 From: jahway603 Date: Fri, 17 Sep 2021 14:45:50 -0400 Subject: [PATCH 102/115] clarified Linux binary install from user feedback --- INSTALL-BIN.md | 9 +++++++++ INSTALL.md | 21 +++++---------------- README.md | 8 ++++++-- 3 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 INSTALL-BIN.md diff --git a/INSTALL-BIN.md b/INSTALL-BIN.md new file mode 100644 index 000000000..d73d138cb --- /dev/null +++ b/INSTALL-BIN.md @@ -0,0 +1,9 @@ +# Installing Hush binaries + +To install a Debian package: + + `dpkg -i hush-3.6.2-amd4.deb` + +To uninstall: + + `apt-get remove hush` diff --git a/INSTALL.md b/INSTALL.md index 0b2f084e7..474bb88ce 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,14 +1,6 @@ # Installing Hush -## Installing Binaries - -To install a Debian package: - - dpkg -i hush-3.6.2-amd4.deb - -To uninstall: - - apt-get remove hush +Instructions to compile Hush yourself. ## Build HUSH dependencies @@ -29,7 +21,6 @@ sudo swapon /swapfile ## Build on Linux: - ```sh # install build depedencies sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \ @@ -42,7 +33,7 @@ cd hush3 ./build.sh -j$(nproc) ``` -## Building On Ubuntu 16.04 and older systems +### Building On Ubuntu 16.04 and older systems Some older compilers may not be able to compile modern code, such as gcc 5.4 which comes with Ubuntu 16.04 by default. Here is how to install gcc 7 on Ubuntu 16.04. Run these commands as root: @@ -56,6 +47,8 @@ apt-get install -y gcc-7 g++-7 && \ ## Run a HUSH Node +After you have compiled Hush, then you can run it with the following command: + ```sh ./src/hushd ``` @@ -81,11 +74,7 @@ cd hush ./src/hushd ``` -Currently Linux, Windows and Mac OS X are our supported platforms. If you -are interested in porting Hush to a new operating system, we are interested -to talk with you. Experimental FreeBSD support is in progress, thanks to radix42. - -We aim to support all platforms, but there is only so much time in the day. +## ARM Architecture Currently, any ARMv7 machine will not be able to build this repo, because the underlying tech (zcash and the zksnark library) do not support that instruction diff --git a/README.md b/README.md index 5014b8eef..8476fbdcd 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ coin takes over 24 hours to sync their full nodes because of Sprout Transactions In working on this release, Duke Leto was suspended from Github, which gave Hush developers the impetus to completely leave that racist and censorship-loving platform. -Hush now has it's own git.hush.is Gitea instance, +Hush now has it's own [git.hush.is](https://git.hush.is/hush) Gitea instance, because we will not be silenced by Microsoft. All Hush software will be released from git.hush.is and hush.is, downloads from any other @@ -32,7 +32,11 @@ domains should be assumed to be backdoored. ## Installing -See [INSTALL.md](https://git.hush.is/hush/hush3/src/branch/master/INSTALL.md) +You can either compile it yourself or you can install a binary which was compiled by us. +Please refer to the instructions which apply to you below: + +* See [INSTALL.md](INSTALL.md) to compile from source on Linux and to cross-compile for Windows +* See [INSTALL-BIN.md](INSTALL-BIN.md) to install pre-compiled binary on Linux ### Claiming Funds From Old Hush Wallets From d398666aa1c8723b2d656e1fae2271951da15596 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Fri, 17 Sep 2021 16:22:00 -0400 Subject: [PATCH 103/115] minor changes to INSTALL-BIN.md --- INSTALL-BIN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL-BIN.md b/INSTALL-BIN.md index d73d138cb..1af184428 100644 --- a/INSTALL-BIN.md +++ b/INSTALL-BIN.md @@ -1,9 +1,9 @@ # Installing Hush binaries -To install a Debian package: +To install a Debian package (change the version to what to downloaded): - `dpkg -i hush-3.6.2-amd4.deb` + dpkg -i hush-3.6.2-amd4.deb To uninstall: - `apt-get remove hush` + apt-get remove hush From e00dabb79b1afdad3f1180342dbc65183625069d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 18 Sep 2021 11:25:13 -0400 Subject: [PATCH 104/115] Fix bug in listaddresses RPC --- src/wallet/rpcwallet.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c2a8484e0..76f160968 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -443,8 +443,6 @@ UniValue listaddresses(const UniValue& params, bool fHelp, const CPubKey& mypk) LOCK2(cs_main, pwalletMain->cs_wallet); - string strAccount = AccountFromValue(params[0]); - // Find all taddrs UniValue ret(UniValue::VARR); for (const std::pair& item : pwalletMain->mapAddressBook) { From 63e29ac20af76bd4e8dbfe624a8a9c642e07a105 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 18 Sep 2021 11:25:59 -0400 Subject: [PATCH 105/115] TUSH gonna TUSH --- src/tushd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tushd b/src/tushd index ad5fafa21..9089ffe8c 100755 --- a/src/tushd +++ b/src/tushd @@ -10,5 +10,6 @@ cd $DIR DIR="$( cd "$( dirname "$( readlink "${BASH_SOURCE[0]}" )" )" && pwd )" cd $DIR -./hushd -ac_name=TUSH -ac_private=1 -gen=1 -testnode=1 +# ./hushd -ac_name=TUSH -ac_private=1 -gen=1 -testnode=1 +./hushd -ac_name=TUSH -ac_private=1 -ac_supply=55555 From 451b7ab0b0763e13f8215ca68fa69b63e31b54c8 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Sun, 19 Sep 2021 18:39:45 -0400 Subject: [PATCH 106/115] added systemd script for sysadmin --- README.md | 7 ++++++- doc/hushd-systemd.md | 26 ++++++++++++++++++++++++++ doc/hushd.service | 9 +++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 doc/hushd-systemd.md create mode 100644 doc/hushd.service diff --git a/README.md b/README.md index 8476fbdcd..31e5cbb61 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,16 @@ If you have an older wallet, then refer to [OLD_WALLETS.md](OLD_WALLETS.md). ### Official Explorer -The link for the Official Hush explorer is: explorer.hush.is +The link for the Official Hush explorer is: [explorer.hush.is](https://explorer.hush.is) We are looking for alternate explorers to be run on Tor, i2P and other TLDs, if you are interested please join Telegram and ask questions. +### For system admins + +There is a new systemd user service script so you can easily start/stop/restart your hushd service on your server. +[Try it out today](doc/hushd-systemd.md) and the systemd script is located in the doc directory of the source tree. + ## Support and Socials Please feel free to join us on Telegram for official support: diff --git a/doc/hushd-systemd.md b/doc/hushd-systemd.md new file mode 100644 index 000000000..0c63be3d2 --- /dev/null +++ b/doc/hushd-systemd.md @@ -0,0 +1,26 @@ +# Systemd script for the Hush daemon + +## Set it up + +First set it up as follows: +* Copy hushd.service to the /usr/lib/systemd/user directory (on Arch Linux, but I believe it's the same for the others too) + +## Basic Usage + +How to start the script: +`systemctl start --user hushd.service` + +How to stop the script: +`systemctl stop --user hushd.service` + +How to restart the script: +`systemctl stop --user hushd.service` + +## How to watch it as it starts + +Use the following: +`watch systemctl status --user hushd.service` + +## Troubleshooting + +Don't run it with sudo or root, or it won't work with the wallet. diff --git a/doc/hushd.service b/doc/hushd.service new file mode 100644 index 000000000..d93d4ede3 --- /dev/null +++ b/doc/hushd.service @@ -0,0 +1,9 @@ +[Unit] +Description=Hush daemon +After=network.target + +[Service] +ExecStart=/usr/bin/hushd + +[Install] +WantedBy=default.target From 70dcfad54341d2d4dc27af10f23373cd603646ac Mon Sep 17 00:00:00 2001 From: jahway603 Date: Sun, 19 Sep 2021 22:31:31 -0400 Subject: [PATCH 107/115] systemd script doc minor update --- doc/hushd-systemd.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/hushd-systemd.md b/doc/hushd-systemd.md index 0c63be3d2..c63def8f5 100644 --- a/doc/hushd-systemd.md +++ b/doc/hushd-systemd.md @@ -3,7 +3,7 @@ ## Set it up First set it up as follows: -* Copy hushd.service to the /usr/lib/systemd/user directory (on Arch Linux, but I believe it's the same for the others too) +* Copy hushd.service to the systemd user directory, which is /usr/lib/systemd/user directory ## Basic Usage @@ -23,4 +23,8 @@ Use the following: ## Troubleshooting -Don't run it with sudo or root, or it won't work with the wallet. +* Don't run it with sudo or root, or it won't work with the wallet. + +### To-do + +* determine best method to get logs when using on Ubuntu server as it is not displayed when watching it or when start/stopping the systemd service (testd on Ubuntu server 20.04 running on VPS) From 4ecfed5f3335f4d0c0a78b072820fa4a08a86f6f Mon Sep 17 00:00:00 2001 From: jahway603 Date: Fri, 24 Sep 2021 13:50:41 -0400 Subject: [PATCH 108/115] minor documenation update --- INSTALL-BIN.md | 8 +++++--- doc/hushd-systemd.md | 11 ++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/INSTALL-BIN.md b/INSTALL-BIN.md index 1af184428..4207024a3 100644 --- a/INSTALL-BIN.md +++ b/INSTALL-BIN.md @@ -1,9 +1,11 @@ # Installing Hush binaries -To install a Debian package (change the version to what to downloaded): +1. First [download the release](https://git.hush.is/hush/hush3/releases) you want to install. It will have a .deb file extension. - dpkg -i hush-3.6.2-amd4.deb +1. Next install the Debian package (change the version to what you downloaded above): -To uninstall: + dpkg -i hush-3.8.0-amd64.deb + +1. If you want to remove it, then run this to uninstall: apt-get remove hush diff --git a/doc/hushd-systemd.md b/doc/hushd-systemd.md index c63def8f5..8877fe127 100644 --- a/doc/hushd-systemd.md +++ b/doc/hushd-systemd.md @@ -14,17 +14,22 @@ How to stop the script: `systemctl stop --user hushd.service` How to restart the script: -`systemctl stop --user hushd.service` +`systemctl restart --user hushd.service` ## How to watch it as it starts -Use the following: +Use the following on most Linux distros: `watch systemctl status --user hushd.service` +If you're using Ubuntu 20.04, then try this instead as the above did not work for me on Ubuntu 20.04 server: +`tail -f ~/.hush/HUSH3/debug.log` + ## Troubleshooting * Don't run it with sudo or root, or it won't work with the wallet. ### To-do -* determine best method to get logs when using on Ubuntu server as it is not displayed when watching it or when start/stopping the systemd service (testd on Ubuntu server 20.04 running on VPS) +* Determine why Ubuntu 20.04 didn't produce the expected outcome with watch and systemctl +* Create the hushd rc.d script +* Create the hushd runit script From b89518403de1416022d80a21c4748380aea46712 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Fri, 24 Sep 2021 13:54:11 -0400 Subject: [PATCH 109/115] minor doc update --- INSTALL-BIN.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL-BIN.md b/INSTALL-BIN.md index 4207024a3..38c8e5a7d 100644 --- a/INSTALL-BIN.md +++ b/INSTALL-BIN.md @@ -4,8 +4,8 @@ 1. Next install the Debian package (change the version to what you downloaded above): - dpkg -i hush-3.8.0-amd64.deb + `dpkg -i hush-3.8.0-amd64.deb` 1. If you want to remove it, then run this to uninstall: - apt-get remove hush + `apt-get remove hush` From 945010066f58b47326173c20568a874b200f6d75 Mon Sep 17 00:00:00 2001 From: onryo Date: Tue, 19 Oct 2021 13:06:30 +0000 Subject: [PATCH 110/115] Update 'INSTALL.md' --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 474bb88ce..eba94faa0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ sudo swapon /swapfile ## Build on Linux: ```sh -# install build depedencies +# install build dependencies sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \ autoconf libtool ncurses-dev unzip git python zlib1g-dev wget \ bsdmainutils automake curl unzip nano libsodium-dev From cff49eef2e0a82e94a19e6197817ad3bef1efb3f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 20 Oct 2021 20:06:03 -0400 Subject: [PATCH 111/115] Update checkpoints --- src/chainparams.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index df85bdf23..664208b32 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -961,9 +961,49 @@ void *chainparams_commandline() { (663000, uint256S("0x000000076756708535e3daeaca6bc32aa1dc360228af6a0c5e5e07b5d9f5f00b")) (664000, uint256S("0x000000181806c17b47bb843537cc91c95ca1e3596bb9e049d18c2e73c1026258")) (665000, uint256S("0x0000001e966c9edae76c40262e65a6c9ab764a09154eb802fb892ceebc2d1935")), - (int64_t) 1631750258, // time of last checkpointed block - (int64_t) 1064407, // total txs - (double) 1402 // txs in the last day before block 665685 + (666000, uint256S("0x0000000b7594c1e8f6ccdf1559e230fdc6c276e8df0a800b7f7c82a237a6c14e")) + (667000, uint256S("0x000000101801a801c21a2e50d4a5173e494f2e9ee604cec5886a8547680accaa")) + (668000, uint256S("0x00000001ee22e21a6d5a5b322ea1ec69231b35d72d54f9fbdfa5dfdc5c7e2f4a")) + (669000, uint256S("0x0000000f8fa48f7244099f17c8dbf79982f5dec586b5b32d0fa30f18540081ca")) + (670000, uint256S("0x00000008d3b0a1f5286574ba5fe05c3151144cd7f330f2f1ec3f2009d4b82687")) + (671000, uint256S("0x0000000dd430c9a8e3d83f123f0bc6b6ba11e774ec6bdcf1a13c216b8e071d3e")) + (672000, uint256S("0x0000000326bd2c2465754ee03f2a9d82d902a19e7d92aef3c9967cbbbdd37da9")) + (673000, uint256S("0x000000053e15e2ee0f6fdb5d6a096fb3b785f82165f5126805fb785d884bef7c")) + (674000, uint256S("0x0000000472c24f87b24de8e091ae9b191d0a114ecaecf7487c5ccd88680b4799")) + (675000, uint256S("0x00000007bc716ae47620f86f7f38010b43a92560b4d901cd4fa945c20ffeee4a")) + (676000, uint256S("0x00000011506c87f327448ff75a37168ee0a31f199dc8f42499247f4af5f84a71")) + (677000, uint256S("0x00000007e26fe6537984fc6f7d9164a6edcd9fa1c92a0ba1f2bafed491c50976")) + (678000, uint256S("0x00000013a790e855c1722c648e930302366b15c78f6f2a9d0bc01ce0c8faec69")) + (679000, uint256S("0x0000000f8519548ca86c8689fc4282e1ce7ab34a39680c7dde40846e49235299")) + (680000, uint256S("0x000000060f172b876390a65c27ad87360e16b8710a4b184b11ed09844b5327fd")) + (681000, uint256S("0x00000001a43cafd9c0858e23c62e629609f9e73905fe8f6de14b0db5c8811f31")) + (682000, uint256S("0x0000000b8330e95dc616e2b455de087d541e4ab8f17bff162b08d66b113ccee0")) + (683000, uint256S("0x000000082fdac13fff52ef28e0b288963b091b991be5fec2684092664340d05b")) + (684000, uint256S("0x00000037cde1f403c7fadb6042d63bec2b04de94d6a9c6202dc371146d4c4745")) + (685000, uint256S("0x00000010795f12db65a60d307bedf42692c1b09a909cc0963bf73df8960c6d3d")) + (686000, uint256S("0x0000000b1aec6e706333d02892de401375820a71a307b49671667b10738f92fb")) + (687000, uint256S("0x00000014ba8dc2c0e5a40a4787ca257a220627ebc183ee460d8ae7fb6ddd3ce0")) + (688000, uint256S("0x0000000edade4f635276a397c9704ea83bdf006d6ee8c8a2fe0f2a41b1e1a2c7")) + (689000, uint256S("0x0000001834d62f37506d7729df7784ff6aa082f227a8c248bfc7d646856cfb2d")) + (690000, uint256S("0x00000007f1fc92391ef45142f537991b974151eff532aa3832adadf3b46bcb95")) + (691000, uint256S("0x0000000ef2ee7f7801125026414f2e1b98571f8a5f74615447ba2f62c24b4a22")) + (692000, uint256S("0x0000000b4640658900c7265b94dae90370de8d1673a909239629b26bd2fd5b06")) + (693000, uint256S("0x00000012c16de95e8a827c6337de6ab2e04c94eb12a97aa20fac3acc479bd703")) + (694000, uint256S("0x0000000a6ccfa9999373584068cab8a9670b287905d7f095d8144ca03694bbf8")) + (695000, uint256S("0x000000132069bbd8a9dd0cec996879b949b2a9862fdfa907c3559929865372ce")) + (696000, uint256S("0x00000005dc30a87aafed1a5703403573234529a8fc0e7f4cb789d3b22406476e")) + (697000, uint256S("0x00000004f7fc3367c3483d0ac17ef6c30148c31d0dd7ec14503c69e79212aaf2")) + (698000, uint256S("0x000000116f56e8cf6e7ed759f8095f0b7bd48c5aec6d35615bfd479a042cf094")) + (699000, uint256S("0x000000096cc740eada81deca2d6a2f2fb30e5a5f15bce44f206e9a15c374ee84")) + (700000, uint256S("0x0000000ebb5da3d51a7897c9224fc236bd8085fbd0e1ac4eb08063eef04c1326")) + (701000, uint256S("0x000000032acf386d4ac320303d8d3d5e6885dd384417a5d0b994c8fe101405c5")) + (702000, uint256S("0x00000000f135d58892ddb7f17a7d1d34d108b177152bce2adde48d58a72480cd")) + (703000, uint256S("0x0000000a469db4ff74c9bdf7903981a3247cb11cbc6ece12fb0e8d34206ba583")) + (704000, uint256S("0x000000024f09cabdd6fbdd379b74d4535c20d5bc78f78725f2d87b257ab3a64d")) + (705000, uint256S("0x0000000c122244118777ca474fe3f30151849ff253ae730dc433900aea5616c5")) + (int64_t) 1634769309, // time of last checkpointed block + (int64_t) 1119376, // total txs + (double) 1529 // txs in the last day before block 705072 }; } else { checkpointData = //(Checkpoints::CCheckpointData) From 54e708ef83491d5daab5653c4a2bfe886e9b2f13 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 20 Oct 2021 20:06:31 -0400 Subject: [PATCH 112/115] Add missing copyrights --- src/netbase.cpp | 1 + src/validationinterface.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index be81264e0..034bbe8f2 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2016-2021 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 /****************************************************************************** diff --git a/src/validationinterface.h b/src/validationinterface.h index 4944e94e7..08be11730 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2016-2021 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 @@ -7,7 +8,6 @@ #define HUSH_VALIDATIONINTERFACE_H #include - #include "zcash/IncrementalMerkleTree.hpp" class CBlock; From 271fd0bd0fcff68700988c4272f0c5c052af3115 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 20 Oct 2021 20:18:37 -0400 Subject: [PATCH 113/115] Fix location of comma --- src/chainparams.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 664208b32..8af988d9b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -960,7 +960,7 @@ void *chainparams_commandline() { (662000, uint256S("0x00000011c4659f0bbe3559c32ff24588d78a3822e8b0e31bb9298a16213fe154")) (663000, uint256S("0x000000076756708535e3daeaca6bc32aa1dc360228af6a0c5e5e07b5d9f5f00b")) (664000, uint256S("0x000000181806c17b47bb843537cc91c95ca1e3596bb9e049d18c2e73c1026258")) - (665000, uint256S("0x0000001e966c9edae76c40262e65a6c9ab764a09154eb802fb892ceebc2d1935")), + (665000, uint256S("0x0000001e966c9edae76c40262e65a6c9ab764a09154eb802fb892ceebc2d1935")) (666000, uint256S("0x0000000b7594c1e8f6ccdf1559e230fdc6c276e8df0a800b7f7c82a237a6c14e")) (667000, uint256S("0x000000101801a801c21a2e50d4a5173e494f2e9ee604cec5886a8547680accaa")) (668000, uint256S("0x00000001ee22e21a6d5a5b322ea1ec69231b35d72d54f9fbdfa5dfdc5c7e2f4a")) @@ -1000,7 +1000,7 @@ void *chainparams_commandline() { (702000, uint256S("0x00000000f135d58892ddb7f17a7d1d34d108b177152bce2adde48d58a72480cd")) (703000, uint256S("0x0000000a469db4ff74c9bdf7903981a3247cb11cbc6ece12fb0e8d34206ba583")) (704000, uint256S("0x000000024f09cabdd6fbdd379b74d4535c20d5bc78f78725f2d87b257ab3a64d")) - (705000, uint256S("0x0000000c122244118777ca474fe3f30151849ff253ae730dc433900aea5616c5")) + (705000, uint256S("0x0000000c122244118777ca474fe3f30151849ff253ae730dc433900aea5616c5")), (int64_t) 1634769309, // time of last checkpointed block (int64_t) 1119376, // total txs (double) 1529 // txs in the last day before block 705072 From 44999b1a8b5a016184e52dc141597e7d03c9a92d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 20 Oct 2021 22:19:59 -0400 Subject: [PATCH 114/115] Add relnotes for 3.9.0 Unusual Ursid --- doc/relnotes/README.md | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 19b35a59b..8bfdc7717 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -10,6 +10,56 @@ 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. +# Hush 3.9.0 "Unusual Ursid" +``` + 136 files changed, 3881 insertions(+), 3156 deletions(-) +``` + +This is a MANDATORY release, please update as soon as you can! At some point, full nodes older than 3.9.0 +will no longer be able to sync the current HUSH network correctly. More details will be given in a future update. + + * hushd/hush-cli/hush-tx are now true binaries instead of shell scripts + * This means hushd.bat, hush-cli.bat and hush-tx.bat are no longer needed on Windows + and simplifies the maintenance of internals + * New official location for full node data is ~/.hush ! + * New full nodes will install and use ~/.hush + * Existing full nodes will continue to use the legacy ~/.komodo directory + * If both ~/.hush/HUSH3 and ~/.komodo/HUSH3 exist, the ~/.hush directory will be used + * Hush full nodes will now attempt to talk to two more nodes by default: + * node1.hush.land + * node2.hush.land + * New RPCs: + * listaddresses - Show all taddrs in this wallet.dat + * rpcinfo - Shows stats about RPC internals + * These RPCs can now be run during RPC warmup: + * listaddresses + * z\_exportwallet + * signmessage + * decoderawtransaction + * getnetworkinfo + * New doc/hushd.service to use hushd with systemd + * Learn more at doc/hushd-systemd.md + * Many updates to Hush Smart Chains and Hush internals + * Optimize zaddrs by only building witness caches for blocks that involve our wallet + * When RPC connection fails hush-cli now tells you which port it was trying to connect to + * Calculation of HSC "network magic" has changed as of 3.9.0 + * If using or developing an HSC, all nodes must use either 3.8.0 or earlier, or + preferably, all use 3.9.0 code or later. HSC networks using both 3.8.0 and 3.9.0 will not work. + * This was required by internals changes and we do not plan to do this again. + * New Stratum API so you can Solo mine with your full node! + * This is an optional feature that defaults to disabled. Enable it with `-stratum=1` + * Example usage: `hushd -stratum=1 -stratumport=31337 -stratumallowip=192.168.0.0/24' + * This allows mining connections from your local network where computers have IPs like 192.168.0.x . + * Your ASICs must be able to connect to the IP and port of your full node. Firewall rules may be needed. + * It offers the highest privacy for miners, since mining pools know your IP and address metadata and can be + hacked or coerced into giving that data. Solo mining with your own full node gives the absolute least metadata + to third parties. + * This is also the cheapest possible way to mine HUSH, since there are NO POOL FEES and NO PAYOUT TRANSACTION FEES! :smile: + * Miners can mine entire HUSH blocks from the privacy of their own server + * As many ASICs as you like can be used with a single Hush full node, just use an address inside a wallet you control, + and set your pool to the IP and port of your Hush full node with Stratum enabled. + * The hush-smart-chain script is now installed in Debian packages + # Hush 3.8.0 "Chuckling Chupacabra" ``` From 3df7def9c999e830d3631059ca973a49e374d60d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 20 Oct 2021 22:24:46 -0400 Subject: [PATCH 115/115] emojify 3.9.0 relnotes --- doc/relnotes/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 8bfdc7717..bcdc2629e 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -18,35 +18,35 @@ evil organizations. This is a MANDATORY release, please update as soon as you can! At some point, full nodes older than 3.9.0 will no longer be able to sync the current HUSH network correctly. More details will be given in a future update. - * hushd/hush-cli/hush-tx are now true binaries instead of shell scripts + * :rainbow: hushd/hush-cli/hush-tx are now true binaries instead of shell scripts * This means hushd.bat, hush-cli.bat and hush-tx.bat are no longer needed on Windows and simplifies the maintenance of internals - * New official location for full node data is ~/.hush ! + * :tada: New official location for full node data is ~/.hush ! * New full nodes will install and use ~/.hush * Existing full nodes will continue to use the legacy ~/.komodo directory * If both ~/.hush/HUSH3 and ~/.komodo/HUSH3 exist, the ~/.hush directory will be used - * Hush full nodes will now attempt to talk to two more nodes by default: + * :kiss: Hush full nodes will now attempt to talk to two more nodes by default: * node1.hush.land * node2.hush.land - * New RPCs: + * :fork_and_knife: New RPCs: * listaddresses - Show all taddrs in this wallet.dat * rpcinfo - Shows stats about RPC internals - * These RPCs can now be run during RPC warmup: + * :unicorn: These RPCs can now be run during RPC warmup: * listaddresses * z\_exportwallet * signmessage * decoderawtransaction * getnetworkinfo - * New doc/hushd.service to use hushd with systemd + * :sweat_drops: New doc/hushd.service to use hushd with systemd * Learn more at doc/hushd-systemd.md - * Many updates to Hush Smart Chains and Hush internals + * :rocket: Many updates to Hush Smart Chains and Hush internals * Optimize zaddrs by only building witness caches for blocks that involve our wallet * When RPC connection fails hush-cli now tells you which port it was trying to connect to * Calculation of HSC "network magic" has changed as of 3.9.0 * If using or developing an HSC, all nodes must use either 3.8.0 or earlier, or preferably, all use 3.9.0 code or later. HSC networks using both 3.8.0 and 3.9.0 will not work. * This was required by internals changes and we do not plan to do this again. - * New Stratum API so you can Solo mine with your full node! + * :hammer: New Stratum API so you can Solo mine with your full node! * This is an optional feature that defaults to disabled. Enable it with `-stratum=1` * Example usage: `hushd -stratum=1 -stratumport=31337 -stratumallowip=192.168.0.0/24' * This allows mining connections from your local network where computers have IPs like 192.168.0.x . @@ -58,7 +58,7 @@ will no longer be able to sync the current HUSH network correctly. More details * Miners can mine entire HUSH blocks from the privacy of their own server * As many ASICs as you like can be used with a single Hush full node, just use an address inside a wallet you control, and set your pool to the IP and port of your Hush full node with Stratum enabled. - * The hush-smart-chain script is now installed in Debian packages + * :nerd_face: The hush-smart-chain script is now installed in Debian packages # Hush 3.8.0 "Chuckling Chupacabra"

    l$B%n4!q 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ÏM^5I}zG-j5OY}ieC-saDn>Cv!_(XxRp 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 Date: Wed, 21 Jul 2021 00:29:06 -0400 Subject: [PATCH 037/115] no sprout round here --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index e33ec9065..9222fbd0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1553,7 +1553,6 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio //fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase); if (iscoinbase == 0 && txout.nValue > 0) { - // TODO: if we are upgraded to Sapling, we can allow Sprout sourced funds to sit in a transparent address char destaddr[65]; Getscriptaddress(destaddr,txout.scriptPubKey); if ( hush_isnotaryvout(destaddr,tiptime) == 0 ) From 8d9ff5fecf3945a49bc5a71e2c444b5be442e9b9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 21 Jul 2021 00:38:44 -0400 Subject: [PATCH 038/115] Report invalid taddrs to stderr --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 9222fbd0a..7e06fc512 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1558,6 +1558,7 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio if ( hush_isnotaryvout(destaddr,tiptime) == 0 ) { invalid_private_taddr = 1; + fprintf(stderr,"%s: invalid taddr %s on private chain!\n", __func__, destaddr); //return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain"); } } From 29cc0e0fdbba40df0f71f1aec6bc7fd88e0f7339 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 21 Jul 2021 00:51:56 -0400 Subject: [PATCH 039/115] New directory structure for windoze --- src/util.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index a470448bb..8295bec69 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -514,11 +514,20 @@ boost::filesystem::path GetDefaultDataDir() // an old wallet.dat from the Ice Ages :) #ifdef _WIN32 // Windows - pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol; + pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol; + // Always use .hush/HUSH3, if it exists (even if .komodo/HUSH3 exists) if(fs::is_directory(pathRet)) { - // legacy directory, use that + return pathRet; } else { - pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol; + pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Komodo" / symbol; + if(fs::is_directory(pathRet)) { + // existing legacy directory, use that for backward compat + return pathRet; + } else { + // For new clones, use Hush/HUSH3 + pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol; + return pathRet; + } } return pathRet; #else From b7e8ad73aede3f0b7dbabf59cb4acfe6dd41d6e9 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 26 Jul 2021 18:49:02 -0400 Subject: [PATCH 040/115] . --- src/rpc/register.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rpc/register.h b/src/rpc/register.h index 8d0f8b6aa..2493e447b 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -37,8 +37,6 @@ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); /** Register test transaction RPC commands */ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); -/** Register stratum RPC commands */ -void RegisterStratumRPCCommands(CRPCTable &tableRPC); static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) @@ -51,7 +49,6 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) #ifdef TESTMODE RegisterTesttransactionsRPCCommands(tableRPC); #endif - RegisterStratumRPCCommands(tableRPC); } #endif From 54c0e4c83e6a18254dd4b05a80cb9967f6c70bd9 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 26 Jul 2021 18:59:39 -0400 Subject: [PATCH 041/115] added hush-smart-chain to deb pkg script --- zcutil/build-debian-package.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/zcutil/build-debian-package.sh b/zcutil/build-debian-package.sh index af013cd9f..4a3b63cae 100755 --- a/zcutil/build-debian-package.sh +++ b/zcutil/build-debian-package.sh @@ -57,6 +57,7 @@ strip $DEB_BIN/hush-komodo-tx cp $SRC_PATH/src/hushd $DEB_BIN cp $SRC_PATH/src/hush-cli $DEB_BIN cp $SRC_PATH/src/hush-tx $DEB_BIN +cp $SRC_PATH/src/hush-smart-chain $DEB_BIN #cp $SRC_DEB/changelog $DEB_DOC/changelog.Debian cp $SRC_DEB/copyright $DEB_DOC cp -r $SRC_DEB/examples $DEB_DOC From 1ccf40851527cdd08c99b4aea054bc5324285159 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 5 Aug 2021 12:04:53 -0400 Subject: [PATCH 042/115] Prefer Hush/HUSH3 to Komodo/HUSH3 if both exist, mac edition --- src/util.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 8295bec69..41e346b75 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -512,6 +512,8 @@ boost::filesystem::path GetDefaultDataDir() // ~/.hush was actually used by the original 1.x version of Hush, but we will // only make subdirectories inside of it, so we won't be able to overwrite // an old wallet.dat from the Ice Ages :) + + fs::path pathRet; #ifdef _WIN32 // Windows pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol; @@ -531,7 +533,6 @@ boost::filesystem::path GetDefaultDataDir() } return pathRet; #else - fs::path pathRet; char* pszHome = getenv("HOME"); if (pszHome == NULL || strlen(pszHome) == 0) pathRet = fs::path("/"); @@ -543,17 +544,27 @@ boost::filesystem::path GetDefaultDataDir() TryCreateDirectory(pathRet); fs::path tmppath; tmppath = pathRet; - tmppath /= "Komodo"; - if(fs::is_directory(pathRet)) { - //legacy directory, use that - TryCreateDirectory(tmppath); + tmppath /= "Hush"; + + // create Library/Application Support/Hush if it doesn't exist + TryCreateDirectory(tmppath); + + // Always use Hush/HUSH3 if it exists + if(fs::is_directory(tmppath / symbol)) { return tmppath / symbol; } else { - // New directory :) + // Check for legacy dir tmppath = pathRet; - tmppath /= "Hush"; - TryCreateDirectory(tmppath); - return tmppath / symbol; + tmppath /= "Komodo"; + //TryCreateDirectory(tmppath); + if(fs::is_directory( tmppath / symbol) { + // Found legacy dir, use that + return tmppath / symbol; + } else { + // For new clones, use Hush/HUSH3 + tmppath = pathRet / "Hush" / HUSH3; + } + return tmppath; } #else // Unix From 236d79b3f8c7f372de5d83aa67b87d468c679d26 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 5 Aug 2021 12:44:30 -0400 Subject: [PATCH 043/115] Add rpcinfo rpc to debug deadlocks We seem to have deadlock bugs in our RPC system, most likely inherited from ZEC or BTC. Since some Hush RPC's take longer (such as anything with Sietch protections), the deadlocks are more likely to occur. Eventually all RPC slots are used up and no more RPC commands can be sent to hushd. This is why the "plz_stop" feature was implemented, but that is just a workaround to restart the server. We must find and fix the root cause. This rpc will allow us to see when we are getting close to our maximum work queue depth and hopefully help us learn exactly what is happening. --- src/httpserver.cpp | 15 +++++++++++++++ src/httpserver.h | 3 +++ src/rpc/misc.cpp | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 0e4e42c2b..59b8eeb1d 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -157,6 +157,11 @@ public: boost::unique_lock lock(cs); return queue.size(); } + size_t MaxDepth() + { + boost::unique_lock lock(cs); + return maxDepth; + } }; struct HTTPPathHandler @@ -186,6 +191,16 @@ std::vector pathHandlers; //! Bound listening sockets std::vector boundSockets; + +int getWorkQueueDepth() +{ + return workQueue->Depth(); +} +int getWorkQueueMaxDepth() +{ + return workQueue->MaxDepth(); +} + /** Check if a network address is allowed to access the HTTP server */ static bool ClientAllowed(const CNetAddr& netaddr) { diff --git a/src/httpserver.h b/src/httpserver.h index b903f91cd..7000bd45f 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -24,6 +24,9 @@ struct event_base; class CService; class HTTPRequest; +int getWorkQueueDepth(); +int getWorkQueueMaxDepth(); + /** Initialize HTTP server. * Call this before RegisterHTTPHandler or EventBase(). */ diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fb1b3116c..37c27831a 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -178,6 +178,26 @@ UniValue geterablockheights(const UniValue& params, bool fHelp, const CPubKey& m return(ret); } +extern int getWorkQueueDepth(); +extern int getWorkQueueMaxDepth(); + +UniValue rpcinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + UniValue result(UniValue::VOBJ); + if (fHelp || params.size() != 0) { + throw runtime_error( + "rpcinfo\n" + "Returns an object containing various RPC state info.\n" + ); + } + LOCK(cs_main); + int depth = getWorkQueueDepth(); + + result.push_back(Pair("work_queue_depth", depth)); + result.push_back(Pair("work_queue_max_depth", getWorkQueueMaxDepth() )); + return result; +} + UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) { uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,longestchain,hushnotarized_height,txid_height; @@ -1556,6 +1576,7 @@ static const CRPCCommand commands[] = { "util", "z_validateaddress", &z_validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, { "util", "verifymessage", &verifymessage, true }, + { "util", "rpcinfo", &rpcinfo, true }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true }, From 89a4226965d42f6a297fadef3bfba340701b9014 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 5 Aug 2021 15:55:34 -0400 Subject: [PATCH 044/115] Report rpc port in error when unable to connect --- src/bitcoin-cli.cpp | 18 ++++++++++++------ src/chainparamsbase.cpp | 8 +++----- src/init.cpp | 4 ++-- src/wallet-utility.cpp | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index b804e26bc..e9623f9bd 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -28,9 +28,13 @@ #include #include #include "support/events.h" + +uint16_t ASSETCHAINS_RPCPORT = 18031; uint16_t BITCOIND_RPCPORT = 18031; char SMART_CHAIN_SYMBOL[65]; +extern uint16_t ASSETCHAINS_RPCPORT; + #include using namespace std; @@ -252,14 +256,16 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) event_base_dispatch(base.get()); - if (response.status == 0) - throw CConnectionFailed(strprintf("couldn't connect to server: %s (code %d)\n(make sure server is running and you are connecting to the correct RPC port)", http_errorstring(response.error), response.error)); - else if (response.status == HTTP_UNAUTHORIZED) + if (response.status == 0) { + throw CConnectionFailed(strprintf("couldn't connect to server at port %d : %s (code %d)\n(make sure server is running and you are connecting to the correct RPC port)", + ASSETCHAINS_RPCPORT, http_errorstring(response.error), response.error)); + } else if (response.status == HTTP_UNAUTHORIZED) { throw std::runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); - else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) + } else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) { throw std::runtime_error(strprintf("server returned HTTP error %d", response.status)); - else if (response.body.empty()) - throw std::runtime_error("no response from server"); + } else if (response.body.empty()) { + throw std::runtime_error(strprintf("no response from server at port %d", ASSETCHAINS_RPCPORT )); + } // Parse reply UniValue valReply(UniValue::VSTR); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 2c15f8ffc..1f0eb7740 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2016-2021 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 © 2014-2019 The SuperNET Developers. * * * @@ -19,9 +19,7 @@ ******************************************************************************/ #include "chainparamsbase.h" - #include "util.h" - #include /** @@ -32,7 +30,7 @@ class CBaseMainParams : public CBaseChainParams public: CBaseMainParams() { - nRPCPort = 7771; + nRPCPort = 18031; } }; static CBaseMainParams mainParams; @@ -45,7 +43,7 @@ class CBaseTestNetParams : public CBaseChainParams public: CBaseTestNetParams() { - nRPCPort = 17771; + nRPCPort = 28031; strDataDir = "testnet3"; } }; diff --git a/src/init.cpp b/src/init.cpp index 3e699a7cf..faa1a9f5f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -568,7 +568,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcbind=", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 7771, 17771)); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), ASSETCHAINS_RPCPORT, 10000 + ASSETCHAINS_RPCPORT)); strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); if (showDebug) { @@ -583,7 +583,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600)); } strUsage += HelpMessageGroup(_("Hush Smart Chain options:")); - strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash")); + strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash (200,9)")); strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60")); strUsage += HelpMessageOpt("-ac_cc", _("Cryptoconditions, default 0")); strUsage += HelpMessageOpt("-ac_beam", _("BEAM integration")); diff --git a/src/wallet-utility.cpp b/src/wallet-utility.cpp index 32dad9c42..a82dfa3b7 100644 --- a/src/wallet-utility.cpp +++ b/src/wallet-utility.cpp @@ -13,7 +13,7 @@ char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; int64_t MAX_MONEY = 200000000 * 100000000LL; uint64_t ASSETCHAINS_SUPPLY; -uint16_t BITCOIND_RPCPORT = 7771; +uint16_t BITCOIND_RPCPORT = 18031; uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC; uint32_t ASSETCHAINS_MAGIC = 2387029918; From 63e1ede1628df2ae0267db24fe558315a5fba8f7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 11:51:25 -0400 Subject: [PATCH 045/115] Also report work queue threads in rpcinfo --- src/httpserver.cpp | 11 +++++++++++ src/httpserver.h | 1 + src/rpc/misc.cpp | 2 ++ 3 files changed, 14 insertions(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 59b8eeb1d..58cc9ca45 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -162,6 +162,11 @@ public: boost::unique_lock lock(cs); return maxDepth; } + int NumThreads() + { + boost::unique_lock lock(cs); + return numThreads; + } }; struct HTTPPathHandler @@ -196,11 +201,17 @@ int getWorkQueueDepth() { return workQueue->Depth(); } + int getWorkQueueMaxDepth() { return workQueue->MaxDepth(); } +int getWorkQueueNumThreads() +{ + return workQueue->NumThreads(); +} + /** Check if a network address is allowed to access the HTTP server */ static bool ClientAllowed(const CNetAddr& netaddr) { diff --git a/src/httpserver.h b/src/httpserver.h index 7000bd45f..348ccda2b 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -26,6 +26,7 @@ class HTTPRequest; int getWorkQueueDepth(); int getWorkQueueMaxDepth(); +int getWorkQueueNumThreads(); /** Initialize HTTP server. * Call this before RegisterHTTPHandler or EventBase(). diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 37c27831a..02ba41fbc 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -180,6 +180,7 @@ UniValue geterablockheights(const UniValue& params, bool fHelp, const CPubKey& m extern int getWorkQueueDepth(); extern int getWorkQueueMaxDepth(); +extern int getWorkQueueNumThreads(); UniValue rpcinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -195,6 +196,7 @@ UniValue rpcinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) result.push_back(Pair("work_queue_depth", depth)); result.push_back(Pair("work_queue_max_depth", getWorkQueueMaxDepth() )); + result.push_back(Pair("work_queue_num_threads", getWorkQueueNumThreads() )); return result; } From 7a9dfb89a73d80015a2f862d4e8d6b47d2fa04bc Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 12:30:36 -0400 Subject: [PATCH 046/115] Debug for -testnode=1 --- src/chainparams.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index a26f8955c..26f4e8488 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -542,8 +542,11 @@ void *chainparams_commandline() { pCurrentParams->SetNValue(ASSETCHAINS_NK[0]); pCurrentParams->SetKValue(ASSETCHAINS_NK[1]); } - if ( HUSH_TESTNODE != 0 ) + if ( HUSH_TESTNODE != 0 ) { + fprintf(stderr,"%s: This is a test node, mining will not require peers!\n", __func__); pCurrentParams->SetMiningRequiresPeers(false); + } + if ( ASSETCHAINS_RPCPORT == 0 ) ASSETCHAINS_RPCPORT = ASSETCHAINS_P2PPORT + 1; pCurrentParams->pchMessageStart[0] = ASSETCHAINS_MAGIC & 0xff; From 2471ce20db9fb455761ca7c495d737f7e5e9aa3c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 17:40:17 -0400 Subject: [PATCH 047/115] Improve handling of custom addnodes --- src/hush_utils.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index d7f56ea87..194a6559d 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1810,7 +1810,14 @@ void hush_args(char *argv0) vector HUSH_nodes= {"node1.hush.is","node2.hush.is","node3.hush.is", "node4.hush.is","node5.hush.is","node6.hush.is", "node7.hush.is","node8.hush.is"}; - mapMultiArgs["-addnode"] = HUSH_nodes; + vector more_nodes = mapMultiArgs["-addnode"]; + if (more_nodes.size() > 0) { + fprintf(stderr,"Adding %d more nodes via custom -addnode arguments", more_nodes.size() ); + } + // Add default HUSH nodes after custom addnodes + more_nodes.insert( more_nodes.end(), HUSH_nodes.begin(), HUSH_nodes.end() ); + + mapMultiArgs["-addnode"] = more_nodes; HUSH_STOPAT = GetArg("-stopat",0); MAX_REORG_LENGTH = GetArg("-maxreorg",MAX_REORG_LENGTH); WITNESS_CACHE_SIZE = MAX_REORG_LENGTH+10; From c29e741109a9f1d2832f52d7f2afba7f3b28b8e8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 17:40:35 -0400 Subject: [PATCH 048/115] Show the actual correct config file name that cannot be found --- src/bitcoind.cpp | 2 +- src/musigtest.py | 17 ++++++++--------- src/util.cpp | 4 ++-- src/util.h | 4 ++-- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b9dd4723b..26998168e 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -169,7 +169,7 @@ bool AppInit(int argc, char* argv[]) { fprintf(stderr, "%s reading config file\n", __FUNCTION__); ReadConfigFile(mapArgs, mapMultiArgs); - } catch (const missing_zcash_conf& e) { + } catch (const missing_hush_conf& e) { fprintf(stderr, (_("Before starting hushd, you need to create a configuration file:\n" "%s\n" diff --git a/src/musigtest.py b/src/musigtest.py index a452b7e97..9e99da51d 100755 --- a/src/musigtest.py +++ b/src/musigtest.py @@ -16,15 +16,14 @@ def def_credentials(chain): rpcport = ''; operating_system = platform.system() if operating_system == 'Darwin': - ac_dir = os.environ['HOME'] + '/Library/Application Support/Komodo' + ac_dir = os.environ['HOME'] + '/Library/Application Support/Hush' elif operating_system == 'Linux': - ac_dir = os.environ['HOME'] + '/.komodo' + ac_dir = os.environ['HOME'] + '/.hush' elif operating_system == 'Windows': - ac_dir = '%s/komodo/' % os.environ['APPDATA'] - if chain == 'KMD': - coin_config_file = str(ac_dir + '/komodo.conf') - else: - coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') + ac_dir = '%s/hush/' % os.environ['APPDATA'] + + coin_config_file = str(ac_dir + '/' + chain + '/' + chain + '.conf') + with open(coin_config_file, 'r') as f: for line in f: l = line.rstrip() @@ -35,8 +34,8 @@ def def_credentials(chain): elif re.search('rpcport', l): rpcport = l.replace('rpcport=', '') if len(rpcport) == 0: - if chain == 'KMD': - rpcport = 7771 + if chain == 'HUSH3': + rpcport = 18031 else: print("rpcport not in conf file, exiting") print("check " + coin_config_file) diff --git a/src/util.cpp b/src/util.cpp index 41e346b75..a2940a0a3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -722,14 +722,14 @@ void ReadConfigFile(map& mapSettingsRet, { boost::filesystem::ifstream streamConfig(GetConfigFile()); if (!streamConfig.good()) - throw missing_zcash_conf(); + throw missing_hush_conf(); set setOptions; setOptions.insert("*"); for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) { - // Don't overwrite existing settings so command line settings override komodo.conf + // Don't overwrite existing settings so command line settings override HUSH3.conf string strKey = string("-") + it->string_key; if (mapSettingsRet.count(strKey) == 0) { diff --git a/src/util.h b/src/util.h index ba2feb38e..7dd63b5bb 100644 --- a/src/util.h +++ b/src/util.h @@ -145,9 +145,9 @@ boost::filesystem::path GetConfigFile(); boost::filesystem::path GetPidFile(); void CreatePidFile(const boost::filesystem::path &path, pid_t pid); #endif -class missing_zcash_conf : public std::runtime_error { +class missing_hush_conf : public std::runtime_error { public: - missing_zcash_conf() : std::runtime_error("Missing komodo.conf") { } + missing_hush_conf() : std::runtime_error(strprintf("Missing %s",GetConfigFile().string() )) { } }; void ReadConfigFile(std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); #ifdef _WIN32 From d74d6d26c0216f7b5ec551dd106f12aab6e52e02 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 17:44:27 -0400 Subject: [PATCH 049/115] . --- 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 194a6559d..827203b79 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1812,7 +1812,7 @@ void hush_args(char *argv0) "node7.hush.is","node8.hush.is"}; vector more_nodes = mapMultiArgs["-addnode"]; if (more_nodes.size() > 0) { - fprintf(stderr,"Adding %d more nodes via custom -addnode arguments", more_nodes.size() ); + fprintf(stderr,"Adding %lu more nodes via custom -addnode arguments", more_nodes.size() ); } // Add default HUSH nodes after custom addnodes more_nodes.insert( more_nodes.end(), HUSH_nodes.begin(), HUSH_nodes.end() ); From aede5cd013d7762a2d0e406dcaf18d3497bb63f6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 20:37:09 -0400 Subject: [PATCH 050/115] Correctly report HSC name when starting --- src/hush_utils.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hush_utils.h b/src/hush_utils.h index 827203b79..c02f14d6f 100644 --- a/src/hush_utils.h +++ b/src/hush_utils.h @@ -1792,7 +1792,10 @@ void hush_args(char *argv0) } } + name = GetArg("-ac_name","HUSH3"); + fprintf(stderr,".oO Starting %s Full Node (Extreme Privacy!) with genproc=%d notary=%d\n",name.c_str(),HUSH_MININGTHREADS, IS_HUSH_NOTARY); + if ( argv0 != 0 ) { len = (int32_t)strlen(argv0); @@ -1807,12 +1810,13 @@ void hush_args(char *argv0) } } } + vector HUSH_nodes= {"node1.hush.is","node2.hush.is","node3.hush.is", "node4.hush.is","node5.hush.is","node6.hush.is", "node7.hush.is","node8.hush.is"}; vector more_nodes = mapMultiArgs["-addnode"]; if (more_nodes.size() > 0) { - fprintf(stderr,"Adding %lu more nodes via custom -addnode arguments", more_nodes.size() ); + fprintf(stderr,"%s: Adding %lu more nodes via custom -addnode arguments\n", __func__, more_nodes.size() ); } // Add default HUSH nodes after custom addnodes more_nodes.insert( more_nodes.end(), HUSH_nodes.begin(), HUSH_nodes.end() ); @@ -1830,7 +1834,6 @@ void hush_args(char *argv0) HUSH_SNAPSHOT_INTERVAL = GetArg("-ac_snapshot",0); Split(GetArg("-ac_nk",""), sizeof(ASSETCHAINS_NK)/sizeof(*ASSETCHAINS_NK), ASSETCHAINS_NK, 0); - fprintf(stderr,".oO Starting HUSH Full Node (Extreme Privacy!) with genproc=%d notary=%d\n",HUSH_MININGTHREADS, IS_HUSH_NOTARY); // -ac_ccactivateht=evalcode,height,evalcode,height,evalcode,height.... Split(GetArg("-ac_ccactivateht",""), sizeof(ccEnablesHeight)/sizeof(*ccEnablesHeight), ccEnablesHeight, 0); From b84883d9b9a3aec00158280937e36107b1a49f3b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 21:04:20 -0400 Subject: [PATCH 051/115] Hushify stratum --- src/stratum.cpp | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/src/stratum.cpp b/src/stratum.cpp index 97179303e..9bbeb1a12 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -65,7 +65,7 @@ #include -extern uint16_t ASSETCHAINS_RPCPORT; // don't want to include komodo_globals.h +extern uint16_t ASSETCHAINS_RPCPORT; // don't want to include hush_globals.h UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); // rpc/blockchain.cpp bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); // src/core_read.cpp @@ -286,7 +286,7 @@ namespace ccminer { } } - void kmd_diff_to_target_equi(uint32_t *target, double diff) + void hush_diff_to_target_equi(uint32_t *target, double diff) { uint64_t m; int k; @@ -797,27 +797,27 @@ std::string GetWorkUnit(StratumClient& client) arith_uint256 hashTarget; bool fNegative,fOverflow; /* - // Targets Table Example: komodo diff and ccminer diff are different (!), + // Targets Table Example: hush diff and ccminer diff are different (!), // Hush diff = NiceHash diff, ccminer_diff = Yiimp diff. hashTarget.SetCompact(HUSH_MINDIFF_NBITS,&fNegative,&fOverflow); // blkhdr.nBits hashTarget = UintToArith256(uint256S("0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f")); hashTarget.SetHex("0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); - hashTarget.SetHex("00ffff0000000000000000000000000000000000000000000000000000000000"); // komodo_diff = 15.0591, ccminer_diff = 1 - hashTarget.SetHex("003fffc000000000000000000000000000000000000000000000000000000000"); // komodo_diff = 60.2362, ccminer_diff = 4 - hashTarget.SetHex("0007fff800000000000000000000000000000000000000000000000000000000"); // komodo_diff = 481.89, ccminer_diff = 31.9999 - hashTarget.SetHex("c7ff3800ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // komodo_diff = 0.0752956, ccminer_diff = 1.00303 - hashTarget.SetHex("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); // komodo_diff = 1, ccminer_diff = 16.9956 + hashTarget.SetHex("00ffff0000000000000000000000000000000000000000000000000000000000"); // hush_diff = 15.0591, ccminer_diff = 1 + hashTarget.SetHex("003fffc000000000000000000000000000000000000000000000000000000000"); // hush_diff = 60.2362, ccminer_diff = 4 + hashTarget.SetHex("0007fff800000000000000000000000000000000000000000000000000000000"); // hush_diff = 481.89, ccminer_diff = 31.9999 + hashTarget.SetHex("c7ff3800ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // hush_diff = 0.0752956, ccminer_diff = 1.00303 + hashTarget.SetHex("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); // hush_diff = 1, ccminer_diff = 16.9956 */ arith_uint256 aHashTarget = instance_of_cstratumparams.getTarget(); // arith_uint256 aHashTarget = UintToArith256(uint256S("00ffff0000000000000000000000000000000000000000000000000000000000")); // 1.0 - // aHashTarget = aHashTarget / 8704; // komodo_diff = 131074 (NiceHash), ccminer_diff = 8704 (Yiimp) + // aHashTarget = aHashTarget / 8704; // hush_diff = 131074 (NiceHash), ccminer_diff = 8704 (Yiimp) /* here we can adjust diff by some algo, note that 00ffff0000000000000000000000000000000000000000000000000000000000 / 8704 = - 0000078780000000000000000000000000000000000000000000000000000000, which is equivalent to komodo_diff = 131074 (NiceHash), + 0000078780000000000000000000000000000000000000000000000000000000, which is equivalent to hush_diff = 131074 (NiceHash), ccminer_diff = 8704 (Yiimp) */ @@ -827,7 +827,7 @@ std::string GetWorkUnit(StratumClient& client) if (instance_of_cstratumparams.fstdErrDebugOutput) { std::cerr << DateTimeStrPrecise() << __func__ << ": " << __FILE__ << "," << __LINE__ << - strprintf(" target = %s, komodo_diff = %g, ccminer_diff = %g", + strprintf(" target = %s, hush_diff = %g, ccminer_diff = %g", strTarget, GetDifficultyFromBits(hashTarget.GetCompact(false)), ccminer::equi_stratum_target_to_diff(strTarget)) << std::endl; } } @@ -1022,11 +1022,11 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork CBlockIndex tmp_index; tmp_index.nBits = blkhdr.nBits; - double kmd_target_diff = GetDifficulty(&tmp_index); // diff from nbits (target) + double hush_target_diff = GetDifficulty(&tmp_index); // diff from nbits (target) tmp_index.nBits = UintToArith256(hash).GetCompact(); - double kmd_real_diff = GetDifficulty(&tmp_index); // real diff (from hash) + double hush_real_diff = GetDifficulty(&tmp_index); // real diff (from hash) tmp_index.nBits = arith_uint256(current_work.local_diff).GetCompact(); - double kmd_local_diff = GetDifficulty(&tmp_index); // local diff (from local port diff) + double hush_local_diff = GetDifficulty(&tmp_index); // local diff (from local port diff) double ccminer_real_diff = ccminer::equi_stratum_target_to_diff(hash.ToString()); double ccminer_target_diff = ccminer::equi_stratum_target_to_diff(arith_uint256().SetCompact(blkhdr.nBits).ToString()); @@ -1040,7 +1040,7 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork // TODO: we need to check hash > local port diff, and if it's true -> throw an exception -> diff too low (!) if (!instance_of_cstratumparams.fAllowLowDiffShares) if (UintToArith256(blkhdr.GetHash()) > arith_uint256(current_work.local_diff)) - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Low diff share (diff %g, local %g)", kmd_real_diff, kmd_local_diff)); + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Low diff share (diff %g, local %g)", hush_real_diff, hush_local_diff)); if (finish > start) { @@ -1056,12 +1056,10 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork std::cerr << DateTimeStrPrecise() << strprintf("%saccepted: %" PRIu64 "/%" PRIu64 "%s ", ColorTypeNames[cl_WHT], counter_TotalBlocks, counter_TotalShares, ColorTypeNames[cl_N] ); if (fDisplayDiffKMD) { - /* komodod diff display */ - std::cerr << strprintf("%slocal %g%s ", "\x1B[90m", kmd_local_diff, ColorTypeNames[cl_N]) << - strprintf("%s(diff %g, target %g) %s ", ColorTypeNames[cl_WHT], kmd_real_diff, kmd_target_diff, ColorTypeNames[cl_N]); - } - else - { /* ccminer diff display */ + /* hushd diff display */ + std::cerr << strprintf("%slocal %g%s ", "\x1B[90m", hush_local_diff, ColorTypeNames[cl_N]) << + strprintf("%s(diff %g, target %g) %s ", ColorTypeNames[cl_WHT], hush_real_diff, hush_target_diff, ColorTypeNames[cl_N]); + } else { /* ccminer diff display */ std::cerr << strprintf("%slocal %.3f%s ", "\x1B[90m", ccminer_local_diff, ColorTypeNames[cl_N]) << strprintf("%s(diff %.3f, target %.3f) %s", ColorTypeNames[cl_WHT], ccminer_real_diff, ccminer_target_diff, ColorTypeNames[cl_N]); // ccminer diff } @@ -2005,14 +2003,14 @@ UniValue rpc_stratum_getdifficulty (const UniValue& params, bool fHelp, const CP CBlockIndex tmp_index; tmp_index.nBits = arith_uint256(strTarget).GetCompact(); - double kmd_diff = GetDifficulty(&tmp_index); + double hush_diff = GetDifficulty(&tmp_index); double ccminer_diff = ccminer::equi_stratum_target_to_diff(strTarget); obj.push_back(Pair("target", strTarget)); obj.push_back(Pair("target_compact", strprintf("%08x",tmp_index.nBits))); - obj.push_back(Pair("kmd_diff_str", strprintf("%g",kmd_diff))); + obj.push_back(Pair("hush_diff_str", strprintf("%g",hush_diff))); obj.push_back(Pair("ccminer_diff_str", strprintf("%g", ccminer_diff))); - obj.push_back(Pair("kmd_diff", kmd_diff)); + obj.push_back(Pair("hush_diff", hush_diff)); obj.push_back(Pair("ccminer_diff", ccminer_diff)); return obj; @@ -2035,7 +2033,7 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP - bits -> difficulty (GetDifficulty() in bitcoin/src/rpc/blockchain.cpp) - target -> bits (GetCompact() in bitcoin/src/arith_uint256.cpp) - target -> difficulty (same as target -> bits -> difficulty) - - difficulty -> bits (not done in bitcoin/src) -> we will use kmd_diff_to_target_equi for that + - difficulty -> bits (not done in bitcoin/src) -> we will use hush_diff_to_target_equi for that - difficulty -> target (same as difficulty -> bits -> target) */ if (fHelp || params.size() != 1) @@ -2047,11 +2045,11 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP + HelpExampleRpc("stratum_setdifficulty", "") ); - // diff can be accepted in two ways: as a hex target or as a kmd_diff, both variants assume + // diff can be accepted in two ways: as a hex target or as a hush_diff, both variants assume // passing a string with 32 bytes hex target or string (!) with a double value, or double // value as a double - double kmd_diff; // calculated value: diff_str -> kmd_diff + double hush_diff; // calculated value: diff_str -> hush_diff std::string diff_str = instance_of_cstratumparams.getTarget().ToString(); if (params[0].getType() == UniValue::VSTR) { @@ -2061,24 +2059,24 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP diff_str = param_str; } else { - if (ParseDouble(param_str, &kmd_diff)) { + if (ParseDouble(param_str, &hush_diff)) { // kmd diff as a str passed // difficulty = difficulty_1_target / current_target arith_uint256 target; - ccminer::kmd_diff_to_target_equi((uint32_t *)&target, kmd_diff); + ccminer::hush_diff_to_target_equi((uint32_t *)&target, hush_diff); diff_str = target.ToString(); } else - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid difficulty (not hex target, not kmd_diff)"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid difficulty (not hex target, not hush_diff)"); } } else if (params[0].getType() == UniValue::VNUM) { // kmd diff as a num passed - kmd_diff = params[0].get_real(); + hush_diff = params[0].get_real(); // difficulty = difficulty_1_target / current_target arith_uint256 target; - ccminer::kmd_diff_to_target_equi((uint32_t *)&target, kmd_diff); + ccminer::hush_diff_to_target_equi((uint32_t *)&target, hush_diff); diff_str = target.ToString(); } else @@ -2092,9 +2090,9 @@ UniValue rpc_stratum_setdifficulty (const UniValue& params, bool fHelp, const CP CBlockIndex tmp_index; tmp_index.nBits = arith_uint256(diff_str).GetCompact(); - double new_kmd_diff = GetDifficulty(&tmp_index); - obj.push_back(Pair("kmd_diff_str", strprintf("%g",new_kmd_diff))); - obj.push_back(Pair("kmd_diff", new_kmd_diff)); + double new_hush_diff = GetDifficulty(&tmp_index); + obj.push_back(Pair("hush_diff_str", strprintf("%g",new_hush_diff))); + obj.push_back(Pair("hush_diff", new_hush_diff)); return obj; }; From 0b6d76616320e8ace5e8a22f82a9f880a7994217 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Aug 2021 21:30:29 -0400 Subject: [PATCH 052/115] More useful stratum thread names --- src/stratum.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stratum.cpp b/src/stratum.cpp index 9bbeb1a12..a74583634 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -1176,7 +1176,7 @@ UniValue stratum_mining_subscribe(StratumClient& client, const UniValue& params) // Please note that Stratum use hex encoding, so you have to convert NONCE_1 from hex to binary before. // ["CONNECT_HOST", CONNECT_PORT, "MINER_USER_AGENT", "SESSION_ID"] - // ["NiceHash/1.0.0", null, "stratum3.decker.host", 18776] // ua, session_id, host, port? + // ["NiceHash/1.0.0", null, "stratum.hush.is", 28030] // ua, session_id, host, port? // ["ccminer/2.3.1"] UniValue ret(UniValue::VARR); @@ -1622,7 +1622,7 @@ static bool g_shutdown = false; void BlockWatcher() { - RenameThread("blkwatcher"); + RenameThread("hush-stratum-blkwatcher"); boost::unique_lock lock(csBestBlock); boost::system_time checktxtime; boost::system_time starttime = boost::get_system_time(); @@ -1735,7 +1735,7 @@ void BlockWatcher() void SendKeepAlivePackets() { - RenameThread("sockklv"); + RenameThread("hush-stratum-keepalive"); while (true) { // Run the notifier on an integer second in the steady clock. auto now = std::chrono::steady_clock::now().time_since_epoch(); From e6a650ff3ed564342daf3d5bb5a46cb03643431d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 10 Aug 2021 12:50:34 -0400 Subject: [PATCH 053/115] Add some stratum spices --- src/init.cpp | 2 +- src/stratum.cpp | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 337cd3997..96aecf308 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -512,7 +512,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)"); } - string debugCategories = "addrman, alert, bench, coindb, db, deletetx, estimatefee, http, libevent, lock, mempool, net, tls, partitioncheck, pow, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these + string debugCategories = "addrman, alert, bench, coindb, db, deletetx, estimatefee, http, libevent, lock, mempool, net, tls, partitioncheck, pow, proxy, prune, rand, reindex, rpc, selectcoins, stratum, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied or if = 1, output all debugging information.") + " " + _(" can be:") + " " + debugCategories + "."); strUsage += HelpMessageOpt("-experimentalfeatures", _("Enable use of experimental features")); diff --git a/src/stratum.cpp b/src/stratum.cpp index a74583634..233277520 100644 --- a/src/stratum.cpp +++ b/src/stratum.cpp @@ -312,10 +312,10 @@ namespace ccminer { /* compute nbits to get the network diff */ double equi_network_diff(uint32_t nbits) { - //KMD bits: "1e 015971", - //KMD target: "00 00 015971000000000000000000000000000000000000000000000000000000", - //KMD bits: "1d 686aaf", - //KMD target: "00 0000 686aaf0000000000000000000000000000000000000000000000000000", + //HUSH bits: "1e 015971", + //HUSH target: "00 00 015971000000000000000000000000000000000000000000000000000000", + //HUSH bits: "1d 686aaf", + //HUSH target: "00 0000 686aaf0000000000000000000000000000000000000000000000000000", // uint32_t nbits = work->data[26]; uint32_t bits = (nbits & 0xffffff); @@ -1051,11 +1051,11 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork // std::cerr << strprintf("%f ms - %" PRIu64 "", elapsed.count(), shares_accepted_since_last) << std::endl; } - bool fDisplayDiffKMD = true; // otherwise it will display ccminer diff + bool fDisplayDiffHUSH = true; // otherwise it will display ccminer diff std::cerr << DateTimeStrPrecise() << strprintf("%saccepted: %" PRIu64 "/%" PRIu64 "%s ", ColorTypeNames[cl_WHT], counter_TotalBlocks, counter_TotalShares, ColorTypeNames[cl_N] ); - if (fDisplayDiffKMD) { + if (fDisplayDiffHUSH) { /* hushd diff display */ std::cerr << strprintf("%slocal %g%s ", "\x1B[90m", hush_local_diff, ColorTypeNames[cl_N]) << strprintf("%s(diff %g, target %g) %s ", ColorTypeNames[cl_WHT], hush_real_diff, hush_target_diff, ColorTypeNames[cl_N]); @@ -1205,7 +1205,7 @@ UniValue stratum_mining_subscribe(StratumClient& client, const UniValue& params) ret.push_back(NullUniValue); ret.push_back(sExtraNonce1); - // On mining.subscribe we don't need ti send anything else, we will send + // On mining.subscribe we don't need to send anything else, we will send // mining.set_target and mining.notify bit later, inside GetWorkUnit. // Scheme is the following: // 1. stratum_read_cb(bufferevent * bev, void * ctx) @@ -1417,7 +1417,6 @@ static void stratum_read_cb(bufferevent *bev, void *ctx) free(cstr); LogPrint("stratum", "Received stratum request from %s : %s\n", client.GetPeer().ToString(), line); - //JSONRPCRequest jreq; JSONRequest jreq; std::string reply; @@ -1426,11 +1425,11 @@ static void stratum_read_cb(bufferevent *bev, void *ctx) UniValue valRequest; if (!valRequest.read(line)) { // Not JSON; is this even a stratum miner? - throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); + throw JSONRPCError(RPC_PARSE_ERROR, strprintf("Invalid JSON, Parse error on: %s",line) ); } if (!valRequest.isObject()) { // Not a JSON object; don't know what to do. - throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); + throw JSONRPCError(RPC_PARSE_ERROR, "Not a JSON object"); } if (valRequest.exists("result")) { // JSON-RPC reply. Ignore. @@ -1809,7 +1808,10 @@ void SendKeepAlivePackets() bool InitStratumServer() { LOCK(cs_stratum); - fprintf(stderr,"%s: Starting built-in stratum server\n",__func__); + + int stratumPort = BaseParams().StratumPort(); + int defaultPort = GetArg("-stratumport", stratumPort); + fprintf(stderr,"%s: Starting built-in stratum server on port %d\n",__func__, defaultPort ); if (!InitStratumAllowList(stratum_allow_subnets)) { @@ -1834,14 +1836,12 @@ bool InitStratumServer() LogPrint("stratum", "Initialized stratum server\n"); } - stratum_method_dispatch["mining.subscribe"] = stratum_mining_subscribe; - stratum_method_dispatch["mining.authorize"] = stratum_mining_authorize; - stratum_method_dispatch["mining.configure"] = stratum_mining_configure; - stratum_method_dispatch["mining.submit"] = stratum_mining_submit; - stratum_method_dispatch["mining.extranonce.subscribe"] = - stratum_mining_extranonce_subscribe; - stratum_method_dispatch["mining.multi_version"] = - stratum_mining_multi_version; + stratum_method_dispatch["mining.subscribe"] = stratum_mining_subscribe; + stratum_method_dispatch["mining.authorize"] = stratum_mining_authorize; + stratum_method_dispatch["mining.configure"] = stratum_mining_configure; + stratum_method_dispatch["mining.submit"] = stratum_mining_submit; + stratum_method_dispatch["mining.extranonce.subscribe"] = stratum_mining_extranonce_subscribe; + stratum_method_dispatch["mining.multi_version"] = stratum_mining_multi_version; // Start thread to wait for block notifications and send updated @@ -1902,7 +1902,6 @@ UniValue rpc_stratum_updatework(const UniValue& params, bool fHelp, const CPubKe uint64_t skipped = 0; // send updated work to miners - // if (cs_stratum.try_lock()) { LOCK(cs_stratum); @@ -1935,6 +1934,7 @@ UniValue rpc_stratum_updatework(const UniValue& params, bool fHelp, const CPubKe // Ignore clients that aren't authorized yet. if (!client.m_authorized && client.m_aux_addr.empty()) { + fprintf(stderr,"%s: Ignoring unauthorized client\n", __func__); continue; } From 056f3140329f339da20825421e0cc26d0e9ce309 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 11 Aug 2021 14:04:14 -0400 Subject: [PATCH 054/115] Add copyright --- src/wallet/db.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index d9d1312a9..ec312a6d0 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2016-2021 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 © 2014-2019 The SuperNET Developers. * * * @@ -19,13 +19,11 @@ ******************************************************************************/ #include "db.h" - #include "addrman.h" #include "hash.h" #include "protocol.h" #include "util.h" #include "utilstrencodings.h" - #include #ifndef _WIN32 @@ -38,13 +36,9 @@ using namespace std; - unsigned int nWalletDBUpdated; - -// // CDB -// CDBEnv bitdb; From 40715561a181a1d8e1fc5b11cf0fdc84a08f44ba Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 19 Aug 2021 09:28:59 -0400 Subject: [PATCH 055/115] Add copyright --- src/httprpc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 799d2fbe6..fd6849e61 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -1,3 +1,6 @@ +// Copyright (c) 2016-2021 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 © 2014-2019 The SuperNET Developers. * * * @@ -12,9 +15,7 @@ * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ - #include "httprpc.h" - #include "chainparams.h" #include "httpserver.h" #include "key_io.h" @@ -25,7 +26,6 @@ #include "util.h" #include "utilstrencodings.h" #include "ui_interface.h" - #include // boost::trim // WWW-Authenticate to present with 401 Unauthorized response From ced3ba591dd75535e6d614eea913d01d02bd0f94 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 19 Aug 2021 19:09:05 -0400 Subject: [PATCH 056/115] Fix coredump when running hush-cli during RPC warmup --- src/rpc/blockchain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 609f26420..f6a1f6dde 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1567,7 +1567,6 @@ inline CBlockIndex* LookupBlockIndex(const uint256& hash) UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk) { - THROW_IF_SYNCING(HUSH_INSYNC); if (fHelp || params.size() > 2) throw runtime_error( @@ -1631,6 +1630,8 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk + HelpExampleRpc("getchaintxstats", "2016") ); + THROW_IF_SYNCING(HUSH_INSYNC); + const CBlockIndex* pindex; int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month From 40853af3352562d03421d474b9df038fc4a9bb1a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 19 Aug 2021 19:30:03 -0400 Subject: [PATCH 057/115] Remove things related to PoS --- src/chain.cpp | 25 ++++++------------------- src/chain.h | 30 ++++++------------------------ src/main.cpp | 14 ++++++-------- src/miner.cpp | 2 +- src/pow.cpp | 4 ++-- src/script/standard.h | 39 --------------------------------------- 6 files changed, 21 insertions(+), 93 deletions(-) diff --git a/src/chain.cpp b/src/chain.cpp index e90466a62..d2b7382d9 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -1,10 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2016-2021 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 © 2014-2019 The SuperNET Developers. * * * @@ -80,15 +78,13 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { CChainPower::CChainPower(CBlockIndex *pblockIndex) { - nHeight = pblockIndex->GetHeight(); - chainStake = arith_uint256(0); + nHeight = pblockIndex->GetHeight(); chainWork = arith_uint256(0); } -CChainPower::CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &stake, const arith_uint256 &work) +CChainPower::CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &work) { - nHeight = pblockIndex->GetHeight(); - chainStake = stake; + nHeight = pblockIndex->GetHeight(); chainWork = work; } @@ -96,38 +92,29 @@ bool operator==(const CChainPower &p1, const CChainPower &p2) { arith_uint256 bigZero = arith_uint256(0); arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1); - arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1); // use up 16 bits for precision - return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) == - ((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor); + return ((p1.chainWork << 16) / workDivisor == ((p2.chainWork << 16) / workDivisor)); } bool operator<(const CChainPower &p1, const CChainPower &p2) { arith_uint256 bigZero = arith_uint256(0); arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1); - arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1); // use up 16 bits for precision - return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) < - ((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor); + return ((p1.chainWork << 16) / workDivisor < ((p2.chainWork << 16) / workDivisor)); } bool operator<=(const CChainPower &p1, const CChainPower &p2) { arith_uint256 bigZero = arith_uint256(0); arith_uint256 workDivisor = p1.chainWork > p2.chainWork ? p1.chainWork : (p2.chainWork != bigZero ? p2.chainWork : 1); - arith_uint256 stakeDivisor = p1.chainStake > p2.chainStake ? p1.chainStake : (p2.chainStake != bigZero ? p2.chainStake : 1); // use up 16 bits for precision - return ((p1.chainWork << 16) / workDivisor + (p1.chainStake << 16) / stakeDivisor) <= - ((p2.chainWork << 16) / workDivisor + (p2.chainStake << 16) / stakeDivisor); + return ((p1.chainWork << 16) / workDivisor <= ((p2.chainWork << 16) / workDivisor)); } - - - /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ int static inline InvertLowestOne(int n) { return n & (n - 1); } diff --git a/src/chain.h b/src/chain.h index bb0b2897f..3162f6634 100644 --- a/src/chain.h +++ b/src/chain.h @@ -127,31 +127,23 @@ static const BlockStatus BLOCK_VALID_CONSENSUS = BLOCK_VALID_SCRIPTS; class CBlockIndex; -// This class provides an accumulator for both the chainwork and the chainPOS value -// CChainPower's can be compared, and the comparison ensures that work and proof of stake power -// are both used equally to determine which chain has the most work. This makes an attack -// that involves mining in secret completely ineffective, even before dPOW, unless a large part -// of the staking supply is also controlled. It also enables a faster deterministic convergence, -// aided by both POS and POW. -// TODO: delete this junk +// This class provides an accumulator for chainwork class CChainPower { public: arith_uint256 chainWork; - arith_uint256 chainStake; int32_t nHeight; - CChainPower() : nHeight(0), chainStake(0), chainWork(0) {} + CChainPower() : nHeight(0), chainWork(0) {} CChainPower(CBlockIndex *pblockIndex); - CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &stake, const arith_uint256 &work); - CChainPower(int32_t height) : nHeight(height), chainStake(0), chainWork(0) {} - CChainPower(int32_t height, const arith_uint256 &stake, const arith_uint256 &work) : - nHeight(height), chainStake(stake), chainWork(work) {} + CChainPower(CBlockIndex *pblockIndex, const arith_uint256 &work); + CChainPower(int32_t height) : nHeight(height), chainWork(0) {} + CChainPower(int32_t height, const arith_uint256 &work) : + nHeight(height), chainWork(work) {} CChainPower &operator=(const CChainPower &chainPower) { chainWork = chainPower.chainWork; - chainStake = chainPower.chainStake; nHeight = chainPower.nHeight; return *this; } @@ -159,7 +151,6 @@ class CChainPower CChainPower &operator+=(const CChainPower &chainPower) { this->chainWork += chainPower.chainWork; - this->chainStake += chainPower.chainStake; return *this; } @@ -167,7 +158,6 @@ class CChainPower { CChainPower result = CChainPower(chainPowerA); result.chainWork += chainPowerB.chainWork; - result.chainStake += chainPowerB.chainStake; return result; } @@ -175,7 +165,6 @@ class CChainPower { CChainPower result = CChainPower(chainPowerA); result.chainWork -= chainPowerB.chainWork; - result.chainStake -= chainPowerB.chainStake; return result; } @@ -183,16 +172,9 @@ class CChainPower { CChainPower result = CChainPower(chainPower); result.chainWork *= x; - result.chainStake *= x; return result; } - CChainPower &addStake(const arith_uint256 &nChainStake) - { - chainStake += nChainStake; - return *this; - } - CChainPower &addWork(const arith_uint256 &nChainWork) { chainWork += nChainWork; diff --git a/src/main.cpp b/src/main.cpp index 7e06fc512..eff2ebaaa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4207,19 +4207,17 @@ static bool ActivateBestChainStep(bool fSkipdpow, CValidationState &state, CBloc if ( reorgLength > MAX_REORG_LENGTH) { auto msg = strprintf(_( - "A block chain reorganization has been detected that would roll back %d blocks! " + "A block chain reorganization has been detected that would roll back %d blocks!!! " "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety." ), reorgLength, MAX_REORG_LENGTH) + "\n\n" + _("Reorganization details") + ":\n" + - "- " + strprintf(_("Current tip: %s, height %d, work %s\nstake %s"), - pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex(), - pindexOldTip->chainPower.chainStake.GetHex()) + "\n" + - "- " + strprintf(_("New tip: %s, height %d, work %s\nstake %s"), - pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex(), - pindexMostWork->chainPower.chainStake.GetHex()) + "\n" + + "- " + strprintf(_("Current tip: %s, height %d, work %s\n"), + pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex()) + "\n" + + "- " + strprintf(_("New tip: %s, height %d, work %s\n"), + pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex()) + "\n" + "- " + strprintf(_("Fork point: %s %s, height %d"), SMART_CHAIN_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" + - _("Please help, human!"); + _("Please help me, wise human!"); LogPrintf("*** %s\nif you launch with -maxreorg=%d it might be able to resolve this automatically", msg,reorgLength+10); fprintf(stderr,"*** %s\nif you launch with -maxreorg=%d it might be able to resolve this automatically", msg.c_str(),reorgLength+10); uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); diff --git a/src/miner.cpp b/src/miner.cpp index 93f019d7f..fb3a574f0 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -583,7 +583,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //pblock->nTime = blocktime + 1; pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); - LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x stake.%i\n", nBlockSize,blocktime,pblock->nBits,isStake); + LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits); // Create coinbase tx CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, nHeight); diff --git a/src/pow.cpp b/src/pow.cpp index 0838f6e2b..8b23c993f 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -749,7 +749,7 @@ bool CheckProofOfWork(const CBlockHeader &blkHeader, uint8_t *pubkey33, int32_t CChainPower GetBlockProof(const CBlockIndex& block) { - arith_uint256 bnWorkTarget, bnStakeTarget = arith_uint256(0); + arith_uint256 bnWorkTarget; bool fNegative; bool fOverflow; @@ -758,7 +758,7 @@ CChainPower GetBlockProof(const CBlockIndex& block) if (fNegative || fOverflow || bnWorkTarget == 0) return CChainPower(0); - return CChainPower(0, bnStakeTarget, (~bnWorkTarget / (bnWorkTarget + 1)) + 1); + return CChainPower(0, (~bnWorkTarget / (bnWorkTarget + 1)) + 1); } int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) diff --git a/src/script/standard.h b/src/script/standard.h index 601b9e5cd..697150372 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -117,45 +117,6 @@ class COptCCParams std::vector AsVector(); }; -class CStakeParams -{ - public: - static const uint32_t STAKE_MINPARAMS = 4; - static const uint32_t STAKE_MAXPARAMS = 5; - - uint32_t srcHeight; - uint32_t blkHeight; - uint256 prevHash; - CPubKey pk; - - CStakeParams() : srcHeight(0), blkHeight(0), prevHash(), pk() {} - - CStakeParams(const std::vector> &vData); - - CStakeParams(uint32_t _srcHeight, uint32_t _blkHeight, const uint256 &_prevHash, const CPubKey &_pk) : - srcHeight(_srcHeight), blkHeight(_blkHeight), prevHash(_prevHash), pk(_pk) {} - - std::vector AsVector() - { - std::vector ret; - CScript scr = CScript(); - scr << OPRETTYPE_STAKEPARAMS; - scr << srcHeight; - scr << blkHeight; - scr << std::vector(prevHash.begin(), prevHash.end()); - - if (pk.IsValid()) - { - scr << std::vector(pk.begin(), pk.end()); - } - - ret = std::vector(scr.begin(), scr.end()); - return ret; - } - - bool IsValid() { return srcHeight != 0; } -}; - /** Check whether a CTxDestination is a CNoDestination. */ bool IsValidDestination(const CTxDestination& dest); From b5056604898793ad016cf7b99f3de7a2e0ba082d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 22 Aug 2021 14:57:49 -0400 Subject: [PATCH 058/115] Clarify some docs related to Overwinter, which HUSH and all HSCs have --- src/init.cpp | 2 +- src/main.cpp | 2 ++ src/wallet/rpcwallet.cpp | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 96aecf308..c5f7b7bb2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -394,7 +394,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); - strUsage += HelpMessageOpt("-mempooltxinputlimit=", _("[DEPRECATED FROM OVERWINTER] Set the maximum number of transparent inputs in a transaction that the mempool will accept (default: 0 = no limit applied)")); + strUsage += HelpMessageOpt("-mempooltxinputlimit=", _("[DEPRECATED/IGNORED] Set the maximum number of transparent inputs in a transaction that the mempool will accept (default: 0 = no limit applied)")); strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef _WIN32 diff --git a/src/main.cpp b/src/main.cpp index eff2ebaaa..625c27361 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1758,6 +1758,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Node operator can choose to reject tx by number of transparent inputs static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0); + + // Limit is ignored if Overwinter is active, which is the case on HUSH3 and all HSC's if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { limit = 0; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 42589b38e..b3a6ff55f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4996,8 +4996,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp "\nShield transparent coinbase funds by sending to a shielded zaddr. This is an asynchronous operation and utxos" "\nselected for shielding will be locked. If there is an error, they are unlocked. The RPC call `listlockunspent`" "\ncan be used to return a list of locked utxos. The number of coinbase utxos selected for shielding can be limited" - "\nby the caller. If the limit parameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit" - "\noption will determine the number of uxtos. Any limit is constrained by the consensus rule defining a maximum" + "\nby the caller. If the limit parameter is set to zero, as many as will fit will be used." + "\nAny limit is constrained by the consensus rule defining a maximum" "\ntransaction size of " + strprintf("%d bytes.", MAX_TX_SIZE_AFTER_SAPLING) + HelpRequiringPassphrase() + "\n" "\nArguments:\n" @@ -5006,7 +5006,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp "3. fee (numeric, optional, default=" + strprintf("%s", FormatMoney(SHIELD_COINBASE_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" "4. limit (numeric, optional, default=" - + strprintf("%d", SHIELD_COINBASE_DEFAULT_LIMIT) + ") Limit on the maximum number of utxos to shield. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n" + + strprintf("%d", SHIELD_COINBASE_DEFAULT_LIMIT) + ") Limit on the maximum number of utxos to shield. Set to 0 to use as many as will fit in the transaction.\n" "\nResult:\n" "{\n" " \"remainingUTXOs\": xxx (numeric) Number of coinbase utxos still available for shielding.\n" From 30001d42539cb63e7ffc6898c328058a34fc9642 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 22 Aug 2021 17:34:44 -0400 Subject: [PATCH 059/115] Comment out a z2z check that isn't quite correct --- 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 04d700c44..762d50021 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -194,9 +194,11 @@ 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); From d8d9f655a713dfa2e8f2724dc9ae3e7c893d18f0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 26 Aug 2021 00:00:38 -0400 Subject: [PATCH 060/115] More relay debug info --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index def0145ab..ae61ea51b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2120,7 +2120,7 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss) random_shuffle( vRelayNodes.begin(), vRelayNodes.end(), GetRandInt ); vRelayNodes.resize(newSize); - fprintf(stderr, "%s: Relaying to %lu peers\n", __func__, newSize); + fprintf(stderr, "%s: Relaying to %lu of %lu peers\n", __func__, newSize, vNodes.size() ); // Only relay to randomly chosen 50% of peers BOOST_FOREACH(CNode* pnode, vRelayNodes) From e424a997a79e1b4c05adf2ab995b5744c4e57eca Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 26 Aug 2021 00:08:37 -0400 Subject: [PATCH 061/115] Cleanup --- src/hush.h | 4 ++-- src/hush_bitcoind.h | 14 +++++++------- src/hush_pax.h | 4 ++-- src/main.cpp | 2 +- src/miner.cpp | 4 ++-- src/rpc/misc.cpp | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hush.h b/src/hush.h index f4a871947..cb8a60a6c 100644 --- a/src/hush.h +++ b/src/hush.h @@ -780,7 +780,7 @@ int32_t hush_voutupdate(bool fJustCheck,int32_t *isratificationp,int32_t notaryi int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid,int32_t n); -int32_t komodo_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys[64][33],int32_t numnotaries,uint8_t rmd160[20]) +int32_t hush_notarycmp(uint8_t *scriptPubKey,int32_t scriptlen,uint8_t pubkeys[64][33],int32_t numnotaries,uint8_t rmd160[20]) { int32_t i; if ( scriptlen == 25 && memcmp(&scriptPubKey[3],rmd160,20) == 0 ) @@ -858,7 +858,7 @@ int32_t hush_connectblock(bool fJustCheck, CBlockIndex *pindex,CBlock& block) continue; if ( (scriptlen= gettxout_scriptPubKey(scriptPubKey,sizeof(scriptPubKey),block.vtx[i].vin[j].prevout.hash,block.vtx[i].vin[j].prevout.n)) > 0 ) { - if ( (k= komodo_notarycmp(scriptPubKey,scriptlen,pubkeys,numnotaries,rmd160)) >= 0 ) + if ( (k= hush_notarycmp(scriptPubKey,scriptlen,pubkeys,numnotaries,rmd160)) >= 0 ) signedmask |= (1LL << k); else if ( 0 && numvins >= 17 ) { diff --git a/src/hush_bitcoind.h b/src/hush_bitcoind.h index b41d3b85a..4fa823997 100644 --- a/src/hush_bitcoind.h +++ b/src/hush_bitcoind.h @@ -578,7 +578,7 @@ CScript hush_makeopret(CBlock *pblock, bool fNew) uint256 _hush_getblockhash(int32_t height);*/ -uint64_t komodo_seed(int32_t height) +uint64_t hush_seed(int32_t height) { uint64_t seed = 0; /*if ( 0 ) // problem during init time, seeds are needed for loading blockindex, so null seeds... @@ -659,7 +659,7 @@ bool hush_hardfork_active(uint32_t time) return isactive; } -int32_t komodo_isPoS(CBlock *pblock,int32_t height,bool fJustCheck) +int32_t hush_isPoS(CBlock *pblock,int32_t height,bool fJustCheck) { return(0); } @@ -1424,7 +1424,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he // lulz int32_t komodo_is_PeiceOfShit() { return(1); } -uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount) +uint64_t hush_notarypayamount(int32_t nHeight, int64_t notarycount) { int8_t curEra = 0; int64_t ret = 0; // if we have an end block in the first era, find our current era @@ -1441,7 +1441,7 @@ uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount) if ( notarycount == 0 ) { - fprintf(stderr, "komodo_notarypayamount failed num notaries is 0!\n"); + fprintf(stderr, "hush_notarypayamount failed num notaries is 0!\n"); return(0); } // Because of reorgs we cannot use the notarized height value. @@ -1471,7 +1471,7 @@ int32_t hush_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *scri return(notarizedheight); } -uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarizationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len) +uint64_t hush_notarypay(CMutableTransaction &txNew, std::vector &NotarizationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len) { // fetch notary pubkey array. uint64_t total = 0, AmountToPay = 0; @@ -1491,7 +1491,7 @@ uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &Notar txNew.vout.resize(NotarizationNotaries.size()+1); // Calcualte the amount to pay according to the current era. - AmountToPay = komodo_notarypayamount(height,NotarizationNotaries.size()); + AmountToPay = hush_notarypayamount(height,NotarizationNotaries.size()); if ( AmountToPay == 0 ) return(0); @@ -1566,7 +1566,7 @@ uint64_t hush_checknotarypay(CBlock *pblock,int32_t height) { // Create the coinbase tx again, using the extracted data, this is the same function the miner uses, with the same data. // This allows us to know exactly that the coinbase is correct. - totalsats = komodo_notarypay(txNew, NotarizationNotaries, pblock->nTime, height, script, scriptlen); + totalsats = hush_notarypay(txNew, NotarizationNotaries, pblock->nTime, height, script, scriptlen); } else { diff --git a/src/hush_pax.h b/src/hush_pax.h index 6e2ae4447..3ccbc2d74 100644 --- a/src/hush_pax.h +++ b/src/hush_pax.h @@ -650,7 +650,7 @@ uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uin } return(0); } - *seedp = komodo_seed(height); + *seedp = hush_seed(height); portable_mutex_lock(&hush_mutex); for (i=0; i<17; i++) { @@ -725,7 +725,7 @@ void komodo_paxpricefeed(int32_t height,uint8_t *pricefeed,int32_t opretlen) uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t height,char *origbase,int64_t fiatoshis) { uint8_t shortflag = 0; char base[4]; int32_t i,baseid; uint8_t addrtype,rmd160[20]; int64_t komodoshis = 0; - *seedp = komodo_seed(height); + *seedp = hush_seed(height); if ( (baseid= hush_baseid(origbase)) < 0 || baseid == MAX_CURRENCIES ) { if ( 0 && origbase[0] != 0 ) diff --git a/src/main.cpp b/src/main.cpp index 625c27361..26ffff8ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3845,7 +3845,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { CValidationState stateDummy; // don't keep staking or invalid transactions - if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) + if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && hush_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0)) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) { mempool.remove(tx, removed, true); } diff --git a/src/miner.cpp b/src/miner.cpp index fb3a574f0..388bd7c37 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -145,7 +145,7 @@ uint64_t the_commission(const CBlock *block,int32_t height); int32_t hush_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33, void *ptr); int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex); int32_t hush_is_notarytx(const CTransaction& tx); -uint64_t komodo_notarypay(CMutableTransaction &txNew, std::vector &NotarizationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len); +uint64_t hush_notarypay(CMutableTransaction &txNew, std::vector &NotarizationNotaries, uint32_t timestamp, int32_t height, uint8_t *script, int32_t len); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); int32_t hush_getnotarizedheight(uint32_t timestamp,int32_t height, uint8_t *script, int32_t len); CScript komodo_mineropret(int32_t nHeight); @@ -649,7 +649,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 int32_t scriptlen = (int32_t)pblock->vtx[1].vout[1].scriptPubKey.size(); if ( script[0] == OP_RETURN ) { - uint64_t totalsats = komodo_notarypay(txNew, NotarizationNotaries, pblock->nTime, nHeight, script, scriptlen); + uint64_t totalsats = hush_notarypay(txNew, NotarizationNotaries, pblock->nTime, nHeight, script, scriptlen); if ( totalsats == 0 ) { fprintf(stderr, "Could not create notary payment, trying again.\n"); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 02ba41fbc..0d48071b7 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -67,7 +67,7 @@ extern char SMART_CHAIN_SYMBOL[HUSH_SMART_CHAIN_MAXLEN]; uint32_t hush_segid32(char *coinaddr); int64_t hush_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *hushnotarized_heightp); -uint64_t komodo_notarypayamount(int32_t nHeight, int64_t notarycount); +uint64_t hush_notarypayamount(int32_t nHeight, int64_t notarycount); int32_t hush_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; @@ -1211,7 +1211,7 @@ UniValue getnotarypayinfo(const UniValue& params, bool fHelp, const CPubKey& myp balance = checkburnaddress(received, TotalNotaryPay, height, "REDVp3ox1pbcWYCzySadfHhk8UU3HM4k5x"); notarycount = hush_notaries(notarypubkeys, height, chainActive[height]->GetBlockTime()); - NotaryPay = komodo_notarypayamount(height, notarycount)*notarycount; + NotaryPay = hush_notarypayamount(height, notarycount)*notarycount; bool spent = (received != balance); if ( !spent ) { From cdbf1fc5d6c32ee6e776624ec1ac1624674f5777 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 27 Aug 2021 11:36:44 -0400 Subject: [PATCH 062/115] Add -stratumaddress and better stratum error logging --- src/init.cpp | 4 +++- src/stratum.cpp | 32 ++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index c5f7b7bb2..2aaa490a0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -589,10 +589,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Stratum server options:")); strUsage += HelpMessageOpt("-stratum", _("Enable stratum server (default: off)")); - strUsage += HelpMessageOpt("-stratumbind=", _("Bind to given address to listen for Stratum work requests. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); + strUsage += HelpMessageOpt("-stratumaddress=