hygiene: Phase 5 — correct stale comments + name safe magic numbers
Fifth phase of the code-hygiene remediation, done per-file (18 files) via an 18-agent Workflow with strict guardrails. No consensus or security VALUES changed (verified: pow/hush_utils/hush_bitcoind/net.h/crypter/stratum have zero non-comment numeric changes); built clean, self-mined, verifychain=true. Totals: 57 stale comments corrected, 46 user-facing branding fixes, 6 behavior-preserving named constants, 4 stratum warnings, 77 items deliberately left (consensus/security values, copyright headers). - Stale comments -> DragonX: corrected HUSH3/HUSH/Komodo/Equihash/Arrakis leftovers that misdescribed the active chain (pow AWT/lwma notes, txdb "Equihash solution" -> RandomX, wallet CLTV/overwinter/Sapling@1 notes, util datadir provenance, crypter's stale mapSproutSpendingKeys invariant). Replaced unprofessional/editorializing comments (profane TODOs, "developers are elite") with neutral technical notes, preserving the real design info. - User-facing branding: dumpwallet header "created by Hush" -> "DragonX"; RPC help text hushd/hush-cli/hushprivkey/hushaddress/Agama -> dragonx*; rebranded provably-dead "HUSH3" symbol-fallback literals to DRAGONX. - Named constants (same values, non-consensus/non-security): addrman peer-selection factors (kChanceFactorGrowth/kChanceScale/deprioritize), sietch MIN_ZOUTS, an init notarization-DB cache size. - Left the security macros (ECC/TFM_TIMING_RESISTANT=420, comment-clarified only), the consensus subsidy/commission literals + 128/129 TRANSITION (comment only), and copyright headers untouched. - Added a prominent WARNING that the stratum server is Equihash-era and NOT updated for DragonX's RandomX PoW (flagged, not rewritten). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -478,6 +478,20 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
const int kRetriesBetweenSleep = 1000;
|
||||
const int kRetrySleepInterval = 100; // milliseconds
|
||||
|
||||
// Peer-selection tuning factors (networking heuristics, not consensus).
|
||||
// On each rejected candidate the running chance factor is scaled up by this
|
||||
// amount so the loop is guaranteed to eventually accept a peer.
|
||||
const double kChanceFactorGrowth = 1.2;
|
||||
// Candidates on unreachable networks are deprioritized to this fraction of
|
||||
// their base chance.
|
||||
const double kUnreachableDeprioritize = 0.25;
|
||||
// Candidates that were just tried are deprioritized to this fraction of
|
||||
// their base chance.
|
||||
const double kJustTriedDeprioritize = 0.10;
|
||||
// Fixed-point scale for the acceptance probability test: draw a random int in
|
||||
// [0, kChanceScale) and accept if it falls below (factors * chance) * kChanceScale.
|
||||
const int kChanceScale = 1 << 30;
|
||||
|
||||
if (newOnly && nNew == 0)
|
||||
return CAddrInfo();
|
||||
|
||||
@@ -513,15 +527,15 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (info.IsReachableNetwork()) {
|
||||
//deprioritize unreachable networks
|
||||
fReachableFactor = 0.25;
|
||||
fReachableFactor = kUnreachableDeprioritize;
|
||||
}
|
||||
if (info.IsJustTried()) {
|
||||
//deprioritize entries just tried
|
||||
fJustTried = 0.10;
|
||||
fJustTried = kJustTriedDeprioritize;
|
||||
}
|
||||
if (RandomInt(1 << 30) < fChanceFactor * fReachableFactor * fJustTried * info.GetChance() * (1 << 30))
|
||||
if (RandomInt(kChanceScale) < fChanceFactor * fReachableFactor * fJustTried * info.GetChance() * kChanceScale)
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
fChanceFactor *= kChanceFactorGrowth;
|
||||
}
|
||||
} else {
|
||||
// use a new node
|
||||
@@ -553,15 +567,15 @@ CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (info.IsReachableNetwork()) {
|
||||
//deprioritize unreachable networks
|
||||
fReachableFactor = 0.25;
|
||||
fReachableFactor = kUnreachableDeprioritize;
|
||||
}
|
||||
if (info.IsJustTried()) {
|
||||
//deprioritize entries just tried
|
||||
fJustTried = 0.10;
|
||||
fJustTried = kJustTriedDeprioritize;
|
||||
}
|
||||
if (RandomInt(1 << 30) < fChanceFactor * fReachableFactor * fJustTried * info.GetChance() * (1 << 30))
|
||||
if (RandomInt(kChanceScale) < fChanceFactor * fReachableFactor * fJustTried * info.GetChance() * kChanceScale)
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
fChanceFactor *= kChanceFactorGrowth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,11 @@
|
||||
|
||||
/// \cond INTERNAL
|
||||
#define CC_MAXVINS 1024
|
||||
#define CC_REQUIREMENTS_MSG (HUSH_NSPV_SUPERLITE?"to use CC contracts you need to nspv_login first\n":"to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n")
|
||||
// NOTE: CryptoConditions (CC) contracts are inherited from the Komodo/Hush lineage and are
|
||||
// largely vestigial on DragonX (ac_private=1 fully-shielded chain). This user-facing message
|
||||
// still describes the legacy prerequisites for using CC contracts (nspv_login in superlite
|
||||
// mode, or launching dragonxd with a valid -pubkey=).
|
||||
#define CC_REQUIREMENTS_MSG (HUSH_NSPV_SUPERLITE?"to use CC contracts you need to nspv_login first\n":"to use CC contracts, you need to launch dragonxd with valid -pubkey= for an address in your wallet\n")
|
||||
|
||||
#define SMALLVAL 0.000000000000001
|
||||
#define SATOSHIDEN ((uint64_t)100000000L)
|
||||
@@ -58,7 +62,8 @@ struct CC_utxo
|
||||
/// \endcond
|
||||
|
||||
|
||||
/// CC contract (Antara module) info structure that contains data used for signing and validation of cc contract transactions
|
||||
/// CC (CryptoConditions) contract info structure that contains data used for signing and validation of cc contract transactions.
|
||||
/// NOTE: the CC framework (historically called "Antara modules" in the Komodo/Hush lineage) is largely vestigial on DragonX.
|
||||
struct CCcontract_info
|
||||
{
|
||||
uint8_t evalcode; //!< cc contract eval code, set by CCinit function
|
||||
@@ -101,7 +106,7 @@ struct CCcontract_info
|
||||
bool(*validate)(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
/// checks if the value of evalcode in cp object is present in the scriptSig parameter,
|
||||
/// that is, the vin for this scriptSig will be validated by the cc contract (Antara module) defined by the eval code in this CCcontract_info object
|
||||
/// that is, the vin for this scriptSig will be validated by the cc contract defined by the eval code in this CCcontract_info object
|
||||
/// @param scriptSig scriptSig to check\n
|
||||
/// Example:
|
||||
/// \code
|
||||
@@ -283,7 +288,7 @@ bool ExtractTokensCCVinPubkeys(const CTransaction &tx, std::vector<CPubKey> &vin
|
||||
/// cp = CCinit(&C, EVAL_ASSETS);
|
||||
/// CPubKey ccAssetsPk = GetUnspendable(cp, ccAssetsPriv);
|
||||
/// \endcode
|
||||
/// Now ccAssetsPk has Antara 'Assets' module global pubkey and ccAssetsPriv has its publicly available private key
|
||||
/// Now ccAssetsPk has the 'Assets' CC module global pubkey and ccAssetsPriv has its publicly available private key
|
||||
CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv);
|
||||
|
||||
// CCutils
|
||||
@@ -373,7 +378,7 @@ int64_t CCfullsupply(uint256 tokenid);
|
||||
/// @returns true if success
|
||||
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey);
|
||||
|
||||
/// Returns my pubkey, that is set by -pubkey hushd parameter
|
||||
/// Returns my pubkey, that is set by the -pubkey dragonxd parameter
|
||||
/// @returns public key as byte array
|
||||
std::vector<uint8_t> Mypubkey();
|
||||
|
||||
@@ -404,8 +409,8 @@ extern std::vector<CPubKey> NULL_pubkeys; //!< constant value for use in functio
|
||||
std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey mypk,uint64_t txfee,CScript opret,std::vector<CPubKey> pubkeys = NULL_pubkeys);
|
||||
|
||||
/// FinalizeCCTx is a very useful function that will properly sign both CC and normal inputs, adds normal change and might add an opreturn output.
|
||||
/// This allows for Antara module transaction creation rpc functions to create an CMutableTransaction object, add the appropriate vins and vouts to it and use FinalizeCCTx to properly sign the transaction.
|
||||
/// By using -addressindex=1 of hushd daemon, it allows tracking of all the CC addresses.
|
||||
/// This allows for CC module transaction creation rpc functions to create an CMutableTransaction object, add the appropriate vins and vouts to it and use FinalizeCCTx to properly sign the transaction.
|
||||
/// By using -addressindex=1 of the dragonxd daemon, it allows tracking of all the CC addresses.
|
||||
///
|
||||
/// For signing the vins the function builds several default probe scriptPubKeys and checks them against the referred previous transactions (vintx) vouts.
|
||||
/// For cryptocondition vins the function creates a basic set of probe cryptconditions with mypk and module global pubkey, both for coins and tokens cases.
|
||||
@@ -473,7 +478,7 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
int64_t AddNormalinputsLocal(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs);
|
||||
|
||||
/// AddNormalinputs2 adds normal (not cc) inputs to the transaction object vin array for the specified total amount using utxos on my pubkey's TX_PUBKEY address (my pubkey is set by -pubkey command line parameter), to fund the transaction.
|
||||
/// 'My pubkey' is the -pubkey parameter of hushd.
|
||||
/// 'My pubkey' is the -pubkey parameter of dragonxd.
|
||||
/// @param mtx mutable transaction object
|
||||
/// @param total amount of inputs to add. If total equals to 0 the function does not add inputs but returns amount of all available normal inputs in the wallet
|
||||
/// @param maxinputs maximum number of inputs to add
|
||||
|
||||
@@ -38,7 +38,8 @@ 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<uint8_t> opret;
|
||||
symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"HUSH3" : SMART_CHAIN_SYMBOL;
|
||||
// Notarization symbol; the empty-symbol fallback is dead on DragonX (SMART_CHAIN_SYMBOL is always "DRAGONX", never empty)
|
||||
symbol = (SMART_CHAIN_SYMBOL[0] == 0) ? (char *)"DRAGONX" : SMART_CHAIN_SYMBOL;
|
||||
memset(args,0,sizeof(*args));
|
||||
if ( dir > 0 )
|
||||
height += 10;
|
||||
|
||||
@@ -1447,7 +1447,10 @@ uint32_t hush_smartmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t
|
||||
LogPrintf("DragonX raw magic extralen=%d crc0=%x\n",extralen,crc0);
|
||||
}
|
||||
|
||||
//TODO: why is this needed?
|
||||
// Legacy special case: HUSH3 mainnet had a hardcoded network magic (HUSH_MAGIC)
|
||||
// rather than the crc32-derived value used by every other chain. This branch is
|
||||
// dead on DragonX (SMART_CHAIN_SYMBOL is "DRAGONX", never "HUSH3"); it is kept only
|
||||
// so the function still reproduces HUSH3's magic if ever run with that symbol.
|
||||
const bool ishush3 = strncmp(symbol, "HUSH3",5) == 0 ? true : false;
|
||||
if(ishush3) {
|
||||
return HUSH_MAGIC;
|
||||
@@ -1493,16 +1496,19 @@ uint64_t hush_max_money()
|
||||
return hush_current_supply(10000000);
|
||||
}
|
||||
|
||||
// This implements the Hush Emission Curve, the miner subsidy part,
|
||||
// and must be kept in sync with hush_commision() in hush_bitcoind.h!
|
||||
// Changing these functions are consensus changes!
|
||||
// Here Be Dragons! -- Duke Leto
|
||||
// This implements the emission curve (miner subsidy part) and must be kept in
|
||||
// sync with hush_commission() in hush_bitcoind.h! Changing these functions,
|
||||
// including the height literals below, is a CONSENSUS change.
|
||||
// NOTE: this TRANSITION boundary is 128 here, while hush_commission() uses 129.
|
||||
// This off-by-one between the two curves is a historical consensus quirk and is
|
||||
// deliberately left as-is: changing either value would be a consensus change.
|
||||
uint64_t hush_block_subsidy(int height)
|
||||
{
|
||||
uint64_t subsidy = 0;
|
||||
int32_t HALVING1 = GetArg("-z2zheight",340000);
|
||||
//TODO: support INTERVAL :(
|
||||
//int32_t INTERVAL = GetArg("-ac_halving1",840000);
|
||||
// Consensus: TRANSITION is 128 here vs 129 in hush_commission(); do not change (see note above).
|
||||
int32_t TRANSITION = 128;
|
||||
|
||||
if (height < TRANSITION) {
|
||||
@@ -1585,7 +1591,9 @@ uint64_t hush_block_subsidy(int height)
|
||||
return subsidy;
|
||||
}
|
||||
|
||||
// wrapper for more general supply curves of Hush Arrakis Chains
|
||||
// Wrapper for the more general supply curves used by assetchains (era/halving/decay driven).
|
||||
// On DragonX the reward comes from the -ac_reward/-ac_halving parameters set in hush_args();
|
||||
// the ishush3 branch below is a legacy special case that is dead on DragonX.
|
||||
uint64_t hush_sc_block_subsidy(int nHeight)
|
||||
{
|
||||
// Find current era, start from beginning reward, and determine current subsidy
|
||||
@@ -1593,6 +1601,8 @@ uint64_t hush_sc_block_subsidy(int nHeight)
|
||||
int64_t subsidyDifference;
|
||||
int32_t numhalvings = 0, curEra = 0, sign = 1;
|
||||
static uint64_t cached_subsidy; static int32_t cached_numhalvings; static int cached_era;
|
||||
// Legacy-HUSH3 detection: dead on DragonX (SMART_CHAIN_SYMBOL is "DRAGONX"), used only
|
||||
// to route HUSH3 mainnet through its bespoke hush_block_subsidy() emission curve below.
|
||||
const bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false;
|
||||
|
||||
// check for backwards compat, older chains with no explicit rewards had 0.0001 block reward
|
||||
@@ -1629,7 +1639,9 @@ uint64_t hush_sc_block_subsidy(int nHeight)
|
||||
if(fDebug)
|
||||
fprintf(stderr,"%s: HUSH3 subsidy=%ld at height=%d\n",__func__,subsidy,nHeight);
|
||||
} else if ( (numhalvings = ((nHeight - nStart) / ASSETCHAINS_HALVING[curEra])) > 0 ) {
|
||||
// The code below is not compatible with HUSH3 mainnet
|
||||
// Generic halving/decay path used by DragonX and other assetchains.
|
||||
// (Legacy HUSH3 mainnet did NOT use this path; it took the ishush3
|
||||
// branch above, which reproduces its bespoke emission curve.)
|
||||
if ( ASSETCHAINS_DECAY[curEra] == 0 ) {
|
||||
subsidy >>= numhalvings;
|
||||
} else if ( ASSETCHAINS_DECAY[curEra] == 100000000 && ASSETCHAINS_ENDSUBSIDY[curEra] != 0 ) {
|
||||
@@ -1991,7 +2003,8 @@ void hush_args(char *argv0)
|
||||
uint8_t prevCCi = 0;
|
||||
ASSETCHAINS_CCLIB = GetArg("-ac_cclib","hush3");
|
||||
|
||||
// these are the enabled CCs on HUSH3 mainnet
|
||||
// Default CC set inherited from legacy HUSH3 mainnet; only used when a chain
|
||||
// enables CryptoConditions and does not override -ac_ccenable.
|
||||
Split(GetArg("-ac_ccenable","228,234,235,236,241"), sizeof(ccenables)/sizeof(*ccenables), ccenables, 0);
|
||||
for (i=nonz=0; i<0x100; i++)
|
||||
{
|
||||
@@ -2376,6 +2389,9 @@ void hush_args(char *argv0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Legacy fallback path taken only when no -ac_name is set (SMART_CHAIN_SYMBOL empty).
|
||||
// Dead on DragonX, which always runs with -ac_name=DRAGONX. The HUSH3/Bitcoin conf
|
||||
// paths and default ports below are historical and left as-is for backwards compat.
|
||||
char fname[512],username[512],password[4096]; int32_t iter; FILE *fp;
|
||||
ASSETCHAINS_P2PPORT = 7770;
|
||||
ASSETCHAINS_RPCPORT = 7771;
|
||||
|
||||
44
src/init.cpp
44
src/init.cpp
@@ -121,7 +121,11 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
|
||||
|
||||
static const char* DEFAULT_ASMAP_FILENAME="asmap.dat";
|
||||
|
||||
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
|
||||
// LevelDB read-cache size (bytes) for the notarizations (dPoW) DB. Non-consensus: just the
|
||||
// in-memory cache the DB is opened with; the value here does not affect validation.
|
||||
static const size_t NOTARIZATION_DB_CACHE_BYTES = 100 * 1024 * 1024; // 100 MiB
|
||||
|
||||
CClientUIInterface uiInterface; // global UI callback dispatcher (declared extern in ui_interface.h)
|
||||
|
||||
// Shutdown
|
||||
//
|
||||
@@ -622,7 +626,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-stratumport=<port>", strprintf(_("Listen for Stratum work requests on <port> (default: %u or testnet: %u)"), BaseParams().StratumPort(), BaseParams().StratumPort()));
|
||||
strUsage += HelpMessageOpt("-stratumallowip=<ip>", _("Allow Stratum work requests from specified source. Valid for <ip> 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" or Arrakis Chain
|
||||
// "ac" prefix is inherited from the Komodo asset-chain lineage ("asset chain"/"affects consensus")
|
||||
strUsage += HelpMessageGroup(_("DragonX Chain options:"));
|
||||
strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, either 'equihash' or 'randomx'. default is Equihash (200,9)"));
|
||||
strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60"));
|
||||
@@ -789,7 +793,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
|
||||
}
|
||||
|
||||
/** Sanity checks
|
||||
* Ensure that Hush is running in a usable environment with all
|
||||
* Ensure that DragonX is running in a usable environment with all
|
||||
* necessary library support.
|
||||
*/
|
||||
bool InitSanityCheck(void)
|
||||
@@ -910,7 +914,7 @@ static void ZC_LoadParams(const CChainParams& chainparams)
|
||||
|
||||
if (!found) {
|
||||
// The traditional place Zcash params are stored, should not hit this case in normal circumstances,
|
||||
// as Hush packages sapling params now
|
||||
// as DragonX packages sapling params now
|
||||
sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
|
||||
sapling_output = ZC_GetParamsDir() / "sapling-output.params";
|
||||
if (files_exist(sapling_spend, sapling_output)) {
|
||||
@@ -987,6 +991,10 @@ bool AppInitServers(boost::thread_group& threadGroup)
|
||||
RPCServer::OnPreCommand(&OnRPCPreCommand);
|
||||
if (!InitHTTPServer())
|
||||
return false;
|
||||
// WARNING: the stratum server (stratum.cpp) is Equihash-era code: it assumes a 1347-byte
|
||||
// Equihash solution and calls CheckEquihashSolution. It has NOT been updated for DragonX's
|
||||
// 32-byte RandomX solution and must not be relied on for mining without a full revalidation.
|
||||
// It stays off by default (DEFAULT_STRATUM_ENABLE=false); only -stratum turns it on.
|
||||
if (GetBoolArg("-stratum", DEFAULT_STRATUM_ENABLE) && !InitStratumServer())
|
||||
return false;
|
||||
if (!StartRPC())
|
||||
@@ -1000,7 +1008,7 @@ bool AppInitServers(boost::thread_group& threadGroup)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Initialize Hush.
|
||||
/** Initialize DragonX.
|
||||
* @pre Parameters should be parsed and config file should be read.
|
||||
*/
|
||||
extern int32_t HUSH_REWIND;
|
||||
@@ -1203,7 +1211,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
|
||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
LogPrintf("Hush version %s (%s)\n", FormatFullVersion());
|
||||
LogPrintf("DragonX version %s (%s)\n", FormatFullVersion());
|
||||
|
||||
|
||||
#ifdef DEBUG_LOCKORDER
|
||||
@@ -1254,7 +1262,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
|
||||
}
|
||||
|
||||
// Read asmap file by default for HUSH3 and all Hush Arrakis Chains
|
||||
// Read asmap file by default on DragonX
|
||||
if (GetArg("-asmap",1)) {
|
||||
fs::path asmap_path = fs::path(GetArg("-asmap", ""));
|
||||
|
||||
@@ -1300,8 +1308,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
if(fs::exists(asmap_path)) {
|
||||
LogPrint("net", "%s: found asmap file at %s\n", __func__, asmap_path.c_str() );
|
||||
} else {
|
||||
// Shit is fucked up, die an honorable death
|
||||
InitError(strprintf(_("Could not find any asmap file! Please report this bug to Hush Developers")));
|
||||
// No asmap file found in any known location; abort startup.
|
||||
InitError(strprintf(_("Could not find any asmap file! Please report this bug to DragonX Developers")));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1637,7 +1645,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
// Sanity check
|
||||
if (!InitSanityCheck())
|
||||
return InitError(_("Initialization sanity check failed. Please check for insanity. Hush is shutting down!"));
|
||||
return InitError(_("Initialization sanity check failed. Please check for insanity. DragonX is shutting down!"));
|
||||
|
||||
std::string strDataDir = GetDataDir().string();
|
||||
#ifdef ENABLE_WALLET
|
||||
@@ -1645,7 +1653,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
|
||||
return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
|
||||
#endif
|
||||
// Make sure only a single Hush process is using the data directory.
|
||||
// Make sure only a single DragonX process is using the data directory.
|
||||
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
|
||||
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
|
||||
if (file) fclose(file);
|
||||
@@ -1668,7 +1676,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
|
||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
LogPrintf("Hush version %s\n", FormatFullVersion());
|
||||
LogPrintf("DragonX version %s\n", FormatFullVersion());
|
||||
|
||||
if (fPrintToDebugLog)
|
||||
OpenDebugLog();
|
||||
@@ -2066,7 +2074,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
|
||||
try {
|
||||
pnotarizations = new NotarizationDB(100*1024*1024, false, fReindex);
|
||||
pnotarizations = new NotarizationDB(NOTARIZATION_DB_CACHE_BYTES, false, fReindex);
|
||||
} catch (const std::exception& e) {
|
||||
// The notarizations (dPoW) DB is non-essential and node-regenerable. It has been seen to
|
||||
// snapshot/flush torn (0-byte log -> leveldb "Database I/O error" on reopen), which
|
||||
@@ -2082,7 +2090,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
boost::filesystem::remove_all(ndir.string() + ".corrupt");
|
||||
boost::filesystem::rename(ndir, ndir.string() + ".corrupt");
|
||||
}
|
||||
pnotarizations = new NotarizationDB(100*1024*1024, false, true);
|
||||
pnotarizations = new NotarizationDB(NOTARIZATION_DB_CACHE_BYTES, false, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -2256,10 +2264,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
InitWarning(msg);
|
||||
}
|
||||
else if (nLoadWalletRet == DB_TOO_NEW)
|
||||
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Hush") << "\n";
|
||||
strErrors << _("Error loading wallet.dat: Wallet requires newer version of DragonX") << "\n";
|
||||
else if (nLoadWalletRet == DB_NEED_REWRITE)
|
||||
{
|
||||
strErrors << _("Wallet needed to be rewritten: restart Hush to complete") << "\n";
|
||||
strErrors << _("Wallet needed to be rewritten: restart DragonX to complete") << "\n";
|
||||
LogPrintf("%s", strErrors.str());
|
||||
return InitError(strErrors.str());
|
||||
}
|
||||
@@ -2664,10 +2672,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
#ifdef ENABLE_MINING
|
||||
#ifndef ENABLE_WALLET
|
||||
if (GetBoolArg("-minetolocalwallet", false)) {
|
||||
return InitError(_("Hush was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Hush with wallet support."));
|
||||
return InitError(_("DragonX was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild DragonX with wallet support."));
|
||||
}
|
||||
if (GetArg("-mineraddress", "").empty() && GetBoolArg("-gen", false)) {
|
||||
return InitError(_("Hush was not built with wallet support. Set -mineraddress, or rebuild Hush with wallet support."));
|
||||
return InitError(_("DragonX was not built with wallet support. Set -mineraddress, or rebuild DragonX with wallet support."));
|
||||
}
|
||||
#endif // !ENABLE_WALLET
|
||||
|
||||
|
||||
14
src/net.cpp
14
src/net.cpp
@@ -56,7 +56,7 @@ extern uint8_t ASSETCHAINS_CLEARNET;
|
||||
// Run asmap health check every 24hr by default
|
||||
#define ASMAP_HEALTHCHECK_INTERVAL 24*60*60
|
||||
|
||||
// This is every 2 blocks, on avg, on HUSH3
|
||||
// Interval (seconds) between zindex stat dumps when -zindex is enabled.
|
||||
#define DUMP_ZINDEX_INTERVAL 150
|
||||
|
||||
#define CHECK_PLZ_STOP_INTERVAL 120
|
||||
@@ -79,7 +79,9 @@ extern uint8_t ASSETCHAINS_CLEARNET;
|
||||
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
|
||||
#define FEELER_SLEEP_WINDOW 1
|
||||
|
||||
#define USE_TLS "encrypted as fuck"
|
||||
// Marker macro that enables the TLS p2p transport. Only its definedness is
|
||||
// ever tested (via defined()/#ifdef); the string value itself is never used.
|
||||
#define USE_TLS "enabled"
|
||||
|
||||
#if defined(USE_TLS) && !defined(TLS1_3_VERSION)
|
||||
// minimum secure protocol is 1.3
|
||||
@@ -815,7 +817,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
|
||||
nPingUsecWait = GetTimeMicros() - nPingUsecStart;
|
||||
}
|
||||
|
||||
// Raw ping time is in microseconds, but show it to user as whole seconds (Hush users should be well used to small numbers with many decimal places by now :)
|
||||
// Raw ping time is in microseconds; convert to seconds for display to the user.
|
||||
stats.dPingTime = (((double)nPingUsecTime) / 1e6);
|
||||
stats.dMinPing = (((double)nMinPingUsecTime) / 1e6);
|
||||
stats.dPingWait = (((double)nPingUsecWait) / 1e6);
|
||||
@@ -2514,7 +2516,9 @@ void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
|
||||
return;
|
||||
}
|
||||
|
||||
// We always round down, except when we have only 1 connection
|
||||
// Relay to half of our peers, rounding down, but never fewer than 1.
|
||||
// Equivalent to max(1, vNodes.size()/2): the ternary picks 1 only when the
|
||||
// integer division vNodes.size()/2 is 0 (i.e. exactly 1 connection).
|
||||
auto newSize = (vNodes.size() / 2) == 0 ? 1 : (vNodes.size() / 2);
|
||||
|
||||
std::shuffle( vRelayNodes.begin(), vRelayNodes.end(), std::mt19937(GetRand(std::numeric_limits<uint32_t>::max())) );
|
||||
@@ -2773,7 +2777,7 @@ bool CNode::GetTlsValidate()
|
||||
{
|
||||
if (tlsValidate == eTlsOption::FALLBACK_UNSET)
|
||||
{
|
||||
// This is useful for private Hush Arrakis Chains, that want to exist
|
||||
// This is useful for private DragonX-based chains that want to exist
|
||||
// on a closed VPN with an internal CA or trusted cert system, or
|
||||
// various other use cases
|
||||
if ( GetBoolArg("-tlsvalidate", false)) {
|
||||
|
||||
@@ -44,9 +44,12 @@
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/signals2/signal.hpp>
|
||||
// Enable WolfSSL Support for Hush
|
||||
// Enable WolfSSL support for DragonX
|
||||
#include <wolfssl/options.h>
|
||||
// TODO: these are not set correctly by wolfssl for some reason. Ja bless.
|
||||
// Force-enable wolfSSL's constant-time (timing-resistant) ECC and TFM code paths.
|
||||
// These are feature-enable macros that wolfSSL checks with #ifdef, so the numeric
|
||||
// value is immaterial to behavior; the value 420 is arbitrary and must simply be
|
||||
// non-empty. Redefined here because wolfssl/options.h does not reliably set them.
|
||||
#undef ECC_TIMING_RESISTANT
|
||||
#undef TFM_TIMING_RESISTANT
|
||||
#define ECC_TIMING_RESISTANT 420
|
||||
|
||||
15
src/pow.cpp
15
src/pow.cpp
@@ -414,7 +414,10 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
||||
|
||||
// Changing this requires changing many other things and
|
||||
// might change consensus. Have fun -- Duke
|
||||
// NOTE: Ony HUSH3 mainnet should use this function, all HAC's should use params.AveragigWindowTimespan()
|
||||
// NOTE: This hardcoded AWT is legacy from the original HUSH3 mainnet. On DragonX the
|
||||
// CalculateNextWorkRequired strncmp(SMART_CHAIN_SYMBOL,"HUSH3",...) check is never true
|
||||
// (SMART_CHAIN_SYMBOL is "DRAGONX"), so this function is dead here and the params-derived
|
||||
// AveragingWindowTimespan() is used instead. Kept as-is to avoid a consensus change.
|
||||
int64_t AveragingWindowTimespan() {
|
||||
// used in const methods, beware!
|
||||
// This is the correct AWT for 75s blocktime, before block 340k
|
||||
@@ -432,8 +435,11 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
||||
int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime;
|
||||
LogPrint("pow", " nActualTimespan = %d before dampening\n", nActualTimespan);
|
||||
|
||||
// Legacy branch: the original HUSH3 mainnet used the hardcoded AveragingWindowTimespan()
|
||||
// above; every other chain uses the params-derived value. On DragonX the symbol is
|
||||
// "DRAGONX", so this comparison is always false and the params value is used. The check is
|
||||
// kept (rather than removed) because it is part of consensus difficulty calculation.
|
||||
bool ishush3 = strncmp(SMART_CHAIN_SYMBOL, "HUSH3",5) == 0 ? true : false;
|
||||
// If this is HUSH3, use AWT function defined above, else use the one in params
|
||||
int64_t AWT = ishush3 ? AveragingWindowTimespan() : params.AveragingWindowTimespan();
|
||||
|
||||
nActualTimespan = AWT + (nActualTimespan - AWT)/4;
|
||||
@@ -481,8 +487,9 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
||||
return bnNew.GetCompact();
|
||||
}
|
||||
|
||||
// HUSH does not use these functions but Hush Arrakis Chains can opt-in to using more bleeding edge DAA's
|
||||
// ASIC chains do not need these protections as much -- Duke Leto
|
||||
// These LWMA difficulty functions are inherited from the Hush lineage and are only used when
|
||||
// ASSETCHAINS_ALGO is neither Equihash nor RandomX (see the dispatch in GetNextWorkRequired).
|
||||
// DragonX uses RandomX, so this LWMA path is not on DragonX's active difficulty codepath.
|
||||
unsigned int lwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
return lwmaCalculateNextWorkRequired(pindexLast, params);
|
||||
|
||||
@@ -672,7 +672,7 @@ std::string GetWorkUnit(StratumClient& client)
|
||||
} */
|
||||
|
||||
/* if (!Params().MineBlocksOnDemand() && g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) {
|
||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Hush is not connected!");
|
||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DragonX is not connected!");
|
||||
} */
|
||||
|
||||
bool fvNodesEmpty;
|
||||
@@ -683,21 +683,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__);
|
||||
const std::string msg = strprintf("%s: Unable to get work unit, DragonX is not connected!", __func__);
|
||||
LogPrint("stratum", "%s\n", msg);
|
||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Hush is not connected!");
|
||||
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DragonX is not connected!");
|
||||
}
|
||||
|
||||
if (IsInitialBlockDownload()) {
|
||||
const std::string msg = strprintf("%s: Unable to get work unit, Hush is still downloading blocks!", __func__);
|
||||
const std::string msg = strprintf("%s: Unable to get work unit, DragonX is still downloading blocks!", __func__);
|
||||
LogPrint("stratum", "%s\n", msg);
|
||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Hush is downloading blocks...");
|
||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DragonX is downloading blocks...");
|
||||
}
|
||||
|
||||
if (!client.m_authorized && client.m_aux_addr.empty()) {
|
||||
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.");
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Stratum client not authorized. Use mining.authorize first, with a DragonX R.. address as the username or 'x' to mine to the default address.");
|
||||
}
|
||||
|
||||
static CBlockIndex* tip = NULL; // pindexPrev
|
||||
@@ -924,6 +924,15 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork
|
||||
const std::vector<unsigned char>& extranonce1, const std::vector<unsigned char>& extranonce2,
|
||||
boost::optional<uint32_t> nVersion, uint32_t nTime, const std::vector<unsigned char>& sol)
|
||||
{
|
||||
// ============================ WARNING (Equihash-era code) ============================
|
||||
// This entire submit path is hardcoded for the legacy Equihash proof-of-work:
|
||||
// it expects a 1347-byte Equihash solution and calls CheckEquihashSolution() below.
|
||||
// DragonX uses RandomX PoW (32-byte solution), NOT Equihash. This stratum path has
|
||||
// NOT been updated for RandomX and must not be relied on without full revalidation.
|
||||
// The 1347-byte length checks, the "sol.begin()+3" solution offset, and the equihash
|
||||
// target/difficulty math are all Equihash-era and are intentionally left unchanged.
|
||||
// ====================================================================================
|
||||
//
|
||||
// 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
|
||||
@@ -934,7 +943,9 @@ bool SubmitBlock(StratumClient& client, const uint256& job_id, const StratumWork
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, msg);
|
||||
}
|
||||
|
||||
// TODO: change hardcoded constants on actual determine of solution size, depends on equihash algo type: 200.9, etc.
|
||||
// WARNING (Equihash-era): 1347 is the Equihash-200,9 solution length. DragonX is RandomX
|
||||
// (32-byte solution), so this length check does not match the live PoW. Left unchanged
|
||||
// because this whole path is Equihash-era; do not repurpose without revalidating the miner protocol.
|
||||
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);
|
||||
@@ -1196,7 +1207,7 @@ UniValue stratum_mining_authorize(StratumClient& client, const UniValue& params)
|
||||
// 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
|
||||
// require any changes on each miner, just restart dragonxd 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());
|
||||
@@ -1204,9 +1215,9 @@ UniValue stratum_mining_authorize(StratumClient& client, const UniValue& params)
|
||||
}
|
||||
|
||||
if (!addr.IsValid()) {
|
||||
const std::string msg = strprintf("%s: Invalid Hush address=%s", __func__, addr.ToString());
|
||||
const std::string msg = strprintf("%s: Invalid DragonX address=%s", __func__, addr.ToString());
|
||||
LogPrint("stratum", "%s\n", msg);
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid Hush address: %s", username));
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid DragonX address: %s", username));
|
||||
}
|
||||
|
||||
client.m_addr = addr;
|
||||
@@ -1250,6 +1261,14 @@ UniValue stratum_mining_configure(StratumClient& client, const UniValue& params)
|
||||
|
||||
UniValue stratum_mining_submit(StratumClient& client, const UniValue& params)
|
||||
{
|
||||
// ============================ WARNING (Equihash-era code) ============================
|
||||
// This share-submission handler is hardcoded for legacy Equihash: it parses and requires
|
||||
// a 1347-byte Equihash solution and hands it to SubmitBlock() (which calls
|
||||
// CheckEquihashSolution). DragonX uses RandomX PoW (32-byte solution), NOT Equihash.
|
||||
// This path has NOT been updated for RandomX and must not be relied on without full
|
||||
// revalidation of the miner-facing stratum protocol.
|
||||
// ====================================================================================
|
||||
//
|
||||
// {"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).
|
||||
@@ -1762,7 +1781,7 @@ void SendKeepAlivePackets()
|
||||
|
||||
}
|
||||
|
||||
/** Configure the Hush stratum server */
|
||||
/** Configure the DragonX stratum server */
|
||||
bool InitStratumServer()
|
||||
{
|
||||
LOCK(cs_stratum);
|
||||
|
||||
@@ -285,8 +285,9 @@ bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockF
|
||||
std::pair<char, uint256> key = make_pair(DB_BLOCK_INDEX, it->GetBlockHash());
|
||||
try {
|
||||
CDiskBlockIndex dbindex {it, [this, &key]() {
|
||||
// It can happen that the index entry is written, then the Equihash solution is cleared from memory,
|
||||
// It can happen that the index entry is written, then the solution is cleared from memory,
|
||||
// then the index entry is rewritten. In that case we must read the solution from the old entry.
|
||||
// (GetSolution() returns DragonX's RandomX solution.)
|
||||
CDiskBlockIndex dbindex_old;
|
||||
if (!Read(key, dbindex_old)) {
|
||||
LogPrintf("%s: Failed to read index entry", __func__);
|
||||
@@ -698,7 +699,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
pindexNew->nTime = diskindex.nTime;
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
// the Equihash solution will be loaded lazily from the dbindex entry
|
||||
// the solution (DragonX RandomX solution) will be loaded lazily from the dbindex entry
|
||||
// pindexNew->nSolution = diskindex.nSolution;
|
||||
pindexNew->nStatus = diskindex.nStatus;
|
||||
pindexNew->nCachedBranchId = diskindex.nCachedBranchId;
|
||||
|
||||
50
src/util.cpp
50
src/util.cpp
@@ -499,27 +499,35 @@ 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
|
||||
// DragonX stores its data under a per-chain subdirectory named after
|
||||
// SMART_CHAIN_SYMBOL (which is "DRAGONX"), so the default datadir resolves
|
||||
// to (Unix) ~/.hush/DRAGONX, (Mac) ~/Library/Application Support/Hush/DRAGONX,
|
||||
// or (Windows) %APPDATA%\Hush\DRAGONX.
|
||||
//
|
||||
// The "Hush" / "Komodo" parent-directory names below are retained from the
|
||||
// Hush/Komodo lineage: the ".hush"/"Hush" path is the current location, and
|
||||
// the ".komodo"/"Komodo" path is only probed as a backward-compatible
|
||||
// fallback for pre-existing legacy data directories. Do not change these
|
||||
// string literals -- they determine where node data is read from and written.
|
||||
|
||||
// NEW NAMES:
|
||||
// Current (per-symbol subdirectory lives under these parents):
|
||||
// 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 :)
|
||||
// Legacy fallback (only used if such a directory already exists):
|
||||
// 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
|
||||
|
||||
fs::path pathRet;
|
||||
#ifdef _WIN32
|
||||
// Windows
|
||||
pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol;
|
||||
// Always use .hush/HUSH3, if it exists (even if .komodo/HUSH3 exists)
|
||||
// Always use Hush\<symbol> (Hush\DRAGONX) if it exists, even if the legacy
|
||||
// Komodo\<symbol> directory also exists.
|
||||
if(fs::is_directory(pathRet)) {
|
||||
return pathRet;
|
||||
} else {
|
||||
@@ -528,7 +536,7 @@ boost::filesystem::path GetDefaultDataDir()
|
||||
// existing legacy directory, use that for backward compat
|
||||
return pathRet;
|
||||
} else {
|
||||
// For new clones, use Hush/ACNAME
|
||||
// For new nodes, use Hush\<symbol>
|
||||
pathRet = GetSpecialFolderPath(CSIDL_APPDATA) / "Hush" / symbol;
|
||||
return pathRet;
|
||||
}
|
||||
@@ -551,7 +559,7 @@ boost::filesystem::path GetDefaultDataDir()
|
||||
// create Library/Application Support/Hush if it doesn't exist
|
||||
TryCreateDirectory(tmppath);
|
||||
|
||||
// Always use Hush/HUSH3 if it exists
|
||||
// Always use Hush/<symbol> (Hush/DRAGONX) if it exists
|
||||
if(fs::is_directory(tmppath / symbol)) {
|
||||
return tmppath / symbol;
|
||||
} else {
|
||||
@@ -563,16 +571,16 @@ boost::filesystem::path GetDefaultDataDir()
|
||||
// Found legacy dir, use that
|
||||
return tmppath / symbol;
|
||||
} else {
|
||||
// For new clones, use Hush/ACNAME
|
||||
// For new nodes, use Hush/<symbol>
|
||||
tmppath = pathRet / "Hush" / symbol;
|
||||
}
|
||||
return tmppath;
|
||||
}
|
||||
#else
|
||||
// Unix
|
||||
// New directory :)
|
||||
// Unix: current default datadir is ~/.hush/<symbol> (i.e. ~/.hush/DRAGONX)
|
||||
fs::path tmppath = pathRet / ".hush" / symbol;
|
||||
// Always use .hush/HUSH3, if it exists (even if .komodo/HUSH3 exists)
|
||||
// Always use ~/.hush/<symbol> (~/.hush/DRAGONX) if it exists, even if the
|
||||
// legacy ~/.komodo/<symbol> directory also exists.
|
||||
if(fs::is_directory(tmppath)) {
|
||||
return tmppath;
|
||||
} else {
|
||||
@@ -582,7 +590,7 @@ boost::filesystem::path GetDefaultDataDir()
|
||||
// existing legacy directory, use that for backward compat
|
||||
return tmppath;
|
||||
} else {
|
||||
// For new clones, use .hush/ACNAME
|
||||
// For new nodes, use ~/.hush/<symbol>
|
||||
tmppath = pathRet / ".hush" / symbol;
|
||||
}
|
||||
return tmppath;
|
||||
@@ -598,13 +606,17 @@ static CCriticalSection csPathCached;
|
||||
|
||||
static boost::filesystem::path ZC_GetBaseParamsDir()
|
||||
{
|
||||
// Copied from GetDefaultDataDir and adapted for zcash params.
|
||||
// Copied from GetDefaultDataDir and adapted for the zk-SNARK parameter files.
|
||||
// DragonX reuses the upstream Sapling parameter directory layout, so these
|
||||
// locations retain the historical "ZcashParams" / ".zcash-params" names. Do
|
||||
// not change these string literals -- they determine where the proving and
|
||||
// verifying keys are loaded from.
|
||||
namespace fs = boost::filesystem;
|
||||
// Windows < Vista: C:\Documents and Settings\Username\Application Data\ZcashParams
|
||||
// Windows >= Vista: C:\Users\Username\AppData\Roaming\ZcashParams
|
||||
// Mac: ~/Library/Application Support/ZcashParams
|
||||
// Unix: ~/.zcash-params
|
||||
// Debian packages: /usr/share/hush
|
||||
// System-wide install (Debian packages): /usr/share/hush
|
||||
fs::path pathRet;
|
||||
#ifdef _WIN32
|
||||
return GetSpecialFolderPath(CSIDL_APPDATA) / "ZcashParams";
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
CAmount fConsolidationTxFee = DEFAULT_CONSOLIDATION_FEE;
|
||||
bool fConsolidationMapUsed = false;
|
||||
|
||||
// Number of Sietch dummy ("zdust") shielded outputs added to every consolidation
|
||||
// transaction to obscure the real output and keep the anonymity set large. This is
|
||||
// a wallet privacy-tuning parameter (not a consensus rule); the sweep operation uses
|
||||
// the same value under the name ZOUTS.
|
||||
static const int MIN_ZOUTS = 7;
|
||||
|
||||
extern string randomSietchZaddr();
|
||||
|
||||
AsyncRPCOperation_saplingconsolidation::AsyncRPCOperation_saplingconsolidation(int targetHeight) : targetHeight_(targetHeight) {}
|
||||
@@ -238,10 +244,10 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() {
|
||||
builder.AddSaplingOutput(extsk.expsk.ovk, addr, actualAmountToSend);
|
||||
LogPrint("zrpcunsafe", "%s: Added consolidation output %s with amount=%li\n", opid, addr.GetHash().ToString().c_str(), actualAmountToSend);
|
||||
|
||||
// Add sietch zouts
|
||||
int MIN_ZOUTS = 7;
|
||||
// Add sietch zouts: MIN_ZOUTS dummy zero-value shielded outputs to
|
||||
// randomly-generated z-addresses, so the consolidation tx does not
|
||||
// shrink the anonymity set.
|
||||
for(size_t i = 0; i < MIN_ZOUTS; i++) {
|
||||
// In Privacy Zdust We Trust -- Duke
|
||||
string zdust = randomSietchZaddr();
|
||||
auto zaddr = DecodePaymentAddress(zdust);
|
||||
if (IsValidPaymentAddress(zaddr)) {
|
||||
|
||||
@@ -215,9 +215,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
bool isPureTaddrOnlyTx = (isfromtaddr_ && z_outputs_.size() == 0);
|
||||
CAmount minersFee = fee_;
|
||||
|
||||
// TODO: fix this garbage ZEC prisoner mindset bullshit
|
||||
// When spending coinbase utxos, you can only specify a single zaddr as the change must go somewhere
|
||||
// and if there are multiple zaddrs, we don't know where to send it.
|
||||
// Coinbase-change routing constraint:
|
||||
// When spending coinbase UTXOs, only a single zaddr recipient may be specified, because the
|
||||
// change must be routed somewhere and with multiple zaddr recipients there is no unambiguous
|
||||
// destination for it. See the isSingleZaddrOutput / isMultipleZaddrOutput handling below.
|
||||
if (isfromtaddr_) {
|
||||
if (isSingleZaddrOutput) {
|
||||
bool b = find_utxos(true);
|
||||
@@ -354,8 +355,8 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
|
||||
|
||||
/**
|
||||
* SCENARIO #0 (All HUSH and Hush Arrakis Chains)
|
||||
* Sprout not involved, so we just use the TransactionBuilder and we're done.
|
||||
* SCENARIO #0 (DragonX and all Sapling-only chains)
|
||||
* Sprout is not involved, so we just use the TransactionBuilder and we're done.
|
||||
* We added the transparent inputs to the builder earlier.
|
||||
*/
|
||||
if (isUsingBuilder_) {
|
||||
@@ -506,7 +507,8 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
return true;
|
||||
}
|
||||
// END SCENARIO #0
|
||||
// No other scenarios, because Hush developers are elite.
|
||||
// No other scenarios: DragonX is Sapling-only (Sprout removed), so the builder path above
|
||||
// handles every supported case. Reaching here means the builder was not used, which is unexpected.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -668,7 +670,8 @@ void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() {
|
||||
rawTx.vout.push_back(out);
|
||||
}
|
||||
if ( !hush_hardfork_active((uint32_t)chainActive.LastTip()->nTime) )
|
||||
rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777
|
||||
// Pre-hardfork: set nLockTime slightly in the past so the tx is immediately spendable.
|
||||
rawTx.nLockTime = (uint32_t)time(NULL) - 60;
|
||||
else
|
||||
rawTx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast();
|
||||
|
||||
@@ -698,7 +701,8 @@ void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CBitcoinAddress *
|
||||
CMutableTransaction rawTx(tx_);
|
||||
rawTx.vout.push_back(out);
|
||||
if ( !hush_hardfork_active((uint32_t)chainActive.LastTip()->nTime) )
|
||||
rawTx.nLockTime = (uint32_t)time(NULL) - 60; // jl777
|
||||
// Pre-hardfork: set nLockTime slightly in the past so the tx is immediately spendable.
|
||||
rawTx.nLockTime = (uint32_t)time(NULL) - 60;
|
||||
else
|
||||
rawTx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast();
|
||||
tx_ = CTransaction(rawTx);
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/foreach.hpp>
|
||||
// TODO: these are not set correctly by wolfssl for some reason. Ja bless.
|
||||
// Enable wolfSSL timing-resistant ECC and TFM (fastmath) code paths, which
|
||||
// harden against timing side-channels. wolfSSL gates these purely with #ifdef,
|
||||
// so the defined value is immaterial (any value enables the feature); we do not
|
||||
// rely on 420 meaning anything.
|
||||
#undef ECC_TIMING_RESISTANT
|
||||
#undef TFM_TIMING_RESISTANT
|
||||
#define ECC_TIMING_RESISTANT 420
|
||||
@@ -306,7 +309,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||
}
|
||||
if (keyPass && keyFail)
|
||||
{
|
||||
LogPrintf("Oh shit! The wallet is probably corrupted: Some keys decrypt but not all.\n");
|
||||
LogPrintf("The wallet is probably corrupted: some keys decrypt but not all.\n");
|
||||
assert(false);
|
||||
}
|
||||
if (keyFail || !keyPass)
|
||||
|
||||
@@ -169,7 +169,8 @@ private:
|
||||
|
||||
CKeyingMaterial vMasterKey;
|
||||
|
||||
//! if fUseCrypto is true, mapKeys, mapSproutSpendingKeys, and mapSaplingSpendingKeys must be empty
|
||||
//! if fUseCrypto is true, mapKeys and mapSaplingSpendingKeys must be empty
|
||||
//! (Sprout was removed; the former mapSproutSpendingKeys no longer exists)
|
||||
//! if fUseCrypto is false, vMasterKey must be empty
|
||||
bool fUseCrypto;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ UniValue convertpassphrase(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
"1. \"agamapassphrase\" (string, required) Agama passphrase\n"
|
||||
"\nResult:\n"
|
||||
"\"agamapassphrase\": \"agamapassphrase\", (string) Agama passphrase you entered\n"
|
||||
"\"address\": \"hushaddress\", (string) Address corresponding to your passphrase\n"
|
||||
"\"address\": \"dragonxaddress\", (string) Address corresponding to your passphrase\n"
|
||||
"\"pubkey\": \"publickeyhex\", (string) The hex value of the raw public key\n"
|
||||
"\"privkey\": \"privatekeyhex\", (string) The hex value of the raw private key\n"
|
||||
"\"wif\": \"wif\" (string) The private key in WIF format to use with 'importprivkey'\n"
|
||||
@@ -255,10 +255,10 @@ UniValue importprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
if (fHelp || params.size() < 1 || params.size() > 5)
|
||||
throw runtime_error(
|
||||
"importprivkey \"hushprivkey\" ( \"label\" rescan height secret_key)\n"
|
||||
"importprivkey \"dragonxprivkey\" ( \"label\" rescan height secret_key)\n"
|
||||
"\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hushprivkey\" (string, required) The private key (see dumpprivkey)\n"
|
||||
"1. \"dragonxprivkey\" (string, required) The private key (see dumpprivkey)\n"
|
||||
"2. \"label\" (string, optional, default=\"\") An optional label\n"
|
||||
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
|
||||
"4. height (integer, optional, default=0) start at block height?\n"
|
||||
@@ -378,7 +378,7 @@ UniValue importaddress(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
|
||||
script = CScript(data.begin(), data.end());
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Hush address or script");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DragonX address or script");
|
||||
}
|
||||
|
||||
string strLabel = "";
|
||||
@@ -504,7 +504,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||
if (vstr.size() < 2)
|
||||
continue;
|
||||
|
||||
// Let's see if the address is a valid Hush spending key
|
||||
// Let's see if the address is a valid DragonX spending key
|
||||
if (fImportZKeys) {
|
||||
auto spendingkey = DecodeSpendingKey(vstr[0]);
|
||||
int64_t nTime = DecodeDumpTime(vstr[1]);
|
||||
@@ -524,7 +524,7 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||
continue;
|
||||
} else {
|
||||
LogPrintf("%s: Importing detected an error: invalid spending key. Trying as a transparent key...\n",__func__);
|
||||
// Not a valid spending key, so carry on and see if it's a Hush transparent address
|
||||
// Not a valid spending key, so carry on and see if it's a DragonX transparent address
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +659,7 @@ UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
"z_exportwallet \"filename\"\n"
|
||||
"\nExports all wallet keys, for taddr and zaddr, in a human-readable format. Overwriting an existing file is not permitted.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"filename\" (string, required) The filename, saved in folder set by hushd -exportdir option\n"
|
||||
"1. \"filename\" (string, required) The filename, saved in folder set by dragonxd -exportdir option\n"
|
||||
"\nResult:\n"
|
||||
"\"path\" (string) The full path of the destination file\n"
|
||||
"\nExamples:\n"
|
||||
@@ -680,7 +680,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
"dumpwallet \"filename\"\n"
|
||||
"\nDumps taddr wallet keys in a human-readable format. Overwriting an existing file is not permitted.\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"filename\" (string, required) The filename, saved in folder set by hushd -exportdir option\n"
|
||||
"1. \"filename\" (string, required) The filename, saved in folder set by dragonxd -exportdir option\n"
|
||||
"\nResult:\n"
|
||||
"\"path\" (string) The full path of the destination file\n"
|
||||
"\nExamples:\n"
|
||||
@@ -736,7 +736,7 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
|
||||
std::sort(vKeyBirth.begin(), vKeyBirth.end());
|
||||
|
||||
// produce output
|
||||
file << strprintf("# Wallet dump created by Hush %s (%s)\n", CLIENT_BUILD);
|
||||
file << strprintf("# Wallet dump created by DragonX %s (%s)\n", CLIENT_BUILD);
|
||||
file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
|
||||
file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
|
||||
file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
|
||||
|
||||
@@ -364,7 +364,7 @@ UniValue setaccount(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Hush address!");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DragonX address!");
|
||||
}
|
||||
|
||||
string strAccount;
|
||||
@@ -411,7 +411,7 @@ UniValue getaccount(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Hush address!");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DragonX address!");
|
||||
}
|
||||
|
||||
std::string strAccount;
|
||||
@@ -571,7 +571,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Hush address!");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DragonX address!");
|
||||
}
|
||||
|
||||
// Amount
|
||||
@@ -705,7 +705,8 @@ UniValue kvupdate(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "HUSH3" : SMART_CHAIN_SYMBOL)));
|
||||
// The SMART_CHAIN_SYMBOL[0]==0 fallback is dead on DragonX (symbol is always "DRAGONX"); kept for defensiveness.
|
||||
ret.push_back(Pair("coin",(char *)(SMART_CHAIN_SYMBOL[0] == 0 ? "DRAGONX" : SMART_CHAIN_SYMBOL)));
|
||||
height = chainActive.LastTip()->GetHeight();
|
||||
if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 )
|
||||
ret.push_back(Pair("owner",refpubkey.GetHex()));
|
||||
@@ -895,7 +896,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp, const CPubKey&
|
||||
// Bitcoin address
|
||||
CTxDestination dest = DecodeDestination(params[0].get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Hush address!");
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DragonX address!");
|
||||
}
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
if (!IsMine(*pwalletMain, scriptPubKey)) {
|
||||
@@ -1452,7 +1453,7 @@ UniValue sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
CScript tmpspk;
|
||||
tmpspk << ParseHex(name_) << OP_CHECKSIG;
|
||||
if ( !ExtractDestination(tmpspk, dest, true) )
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Hush address or pubkey: ") + name_);
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid DragonX address or pubkey: ") + name_);
|
||||
}
|
||||
|
||||
CScript scriptPubKey = GetScriptForDestination(dest);
|
||||
@@ -2546,7 +2547,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
// slack space in .dat files; that is bad if the old data is
|
||||
// unencrypted private keys. So:
|
||||
StartShutdown();
|
||||
return "wallet encrypted; Hush server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
|
||||
return "wallet encrypted; DragonX server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
|
||||
}
|
||||
|
||||
UniValue lockunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
@@ -2854,7 +2855,7 @@ UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
" \"txid\" : \"txid\", (string) the transaction id \n"
|
||||
" \"vout\" : n, (numeric) the vout value\n"
|
||||
" \"generated\" : true|false (boolean) true if txout is a coinbase transaction output\n"
|
||||
" \"address\" : \"address\", (string) the Hush address\n"
|
||||
" \"address\" : \"address\", (string) the DragonX address\n"
|
||||
" \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
|
||||
" \"scriptPubKey\" : \"key\", (string) the script key\n"
|
||||
" \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n"
|
||||
@@ -2888,7 +2889,7 @@ UniValue listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
const UniValue& input = inputs[idx];
|
||||
CTxDestination dest = DecodeDestination(input.get_str());
|
||||
if (!IsValidDestination(dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Hush address: ") + input.get_str());
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid DragonX address: ") + input.get_str());
|
||||
}
|
||||
if (!destinations.insert(dest).second) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
|
||||
@@ -3423,7 +3424,7 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
|
||||
"This function is slow if no filters are given, use z_listreceivedbyaddress if you do not need filters."
|
||||
"\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hushaddress:\" (string, required) \n"
|
||||
"1. \"dragonxaddress:\" (string, required) \n"
|
||||
"\n"
|
||||
"2. \"Minimum Confimations:\" (numeric, optional, default=0) \n"
|
||||
"\n"
|
||||
@@ -3460,13 +3461,13 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&
|
||||
" \"walletconflicts\": [conflicts], An array of wallet conflicts\n"
|
||||
" \"recieved\": { A list of receives from the transaction\n"
|
||||
" \"transparentReceived\": [{ An Array of txos received for transparent addresses\n"
|
||||
" \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n"
|
||||
" \"address\": \"dragonxaddress\", (string) DragonX transparent address (t-address)\n"
|
||||
" \"scriptPubKey\": \"script\", (string) Script for the transparent address (t-address)\n"
|
||||
" \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n"
|
||||
" \"vout\": : n, (numeric) the vout value\n"
|
||||
" }],\n"
|
||||
" \"saplingReceived\": [{ An Array of utxos/notes received for sapling addresses\n"
|
||||
" \"address\": \"hushaddress\", (string) Shielded address (z-address)\n"
|
||||
" \"address\": \"dragonxaddress\", (string) Shielded address (z-address)\n"
|
||||
" \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n"
|
||||
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
|
||||
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
|
||||
@@ -3599,12 +3600,12 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&)
|
||||
if (fHelp || params.size() > 5 || params.size() == 3)
|
||||
throw runtime_error(
|
||||
"z_listsentbyaddress\n"
|
||||
"\nReturns decrypted Hush outputs sent to a single address.\n"
|
||||
"\nReturns decrypted DragonX outputs sent to a single address.\n"
|
||||
"\n"
|
||||
"This function only returns information on addresses sent from wallet addresses with full spending keys."
|
||||
"\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"hushaddress:\" (string, required) \n"
|
||||
"1. \"dragonxaddress:\" (string, required) \n"
|
||||
"\n"
|
||||
"2. \"Minimum Confimations:\" (numeric, optional, default=0) \n"
|
||||
"\n"
|
||||
@@ -3642,13 +3643,13 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&)
|
||||
" \"sends\": { A list of outputs of where funds were sent to in the transaction,\n"
|
||||
" only available if the transaction has valid sends (inputs) belonging to the wallet\n"
|
||||
" \"transparentSends\": [{ An Array of spends (outputs) for transparent addresses of the receipient\n"
|
||||
" \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n"
|
||||
" \"scriptPubKey\": \"script\", (string) Script for the Hush transparent address (t-address)\n"
|
||||
" \"address\": \"dragonxaddress\", (string) DragonX transparent address (t-address)\n"
|
||||
" \"scriptPubKey\": \"script\", (string) Script for the DragonX transparent address (t-address)\n"
|
||||
" \"amount\": x.xxxx, (numeric) Value of output being sent " + CURRENCY_UNIT + ", negative for sends\n"
|
||||
" \"vout\": : n, (numeric) the vout value\n"
|
||||
" }],\n"
|
||||
" \"saplingSends\": [{ An Array of spends (outputs) for sapling addresses\n"
|
||||
" \"address\": \"hushaddress\", (string) Hush sapling address (z-address) of the receipient\n"
|
||||
" \"address\": \"dragonxaddress\", (string) DragonX sapling address (z-address) of the receipient\n"
|
||||
" \"amount\": x.xxxx, (numeric) Value of output being sent" + CURRENCY_UNIT + ", negative for sends\n"
|
||||
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
|
||||
" \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n"
|
||||
@@ -4277,7 +4278,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
string address = o.get_str();
|
||||
auto zaddr = DecodePaymentAddress(address);
|
||||
if (!IsValidPaymentAddress(zaddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid Hush zaddr: ") + address);
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid DragonX zaddr: ") + address);
|
||||
}
|
||||
auto hasSpendingKey = boost::apply_visitor(HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr);
|
||||
if (!fIncludeWatchonly && !hasSpendingKey) {
|
||||
@@ -4820,7 +4821,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
// getbalance and "getbalance * 1 true" should return the same number
|
||||
// but they don't because wtx.GetAmounts() does not handle tx where there are no outputs
|
||||
// pwalletMain->GetBalance() does not accept min depth parameter
|
||||
// so we use our own method to get balance of utxos, lulzwtfbbq
|
||||
// so we use our own method to get balance of utxos
|
||||
CAmount nBalance = getBalanceTaddr("", nMinDepth, !fIncludeWatchonly);
|
||||
CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth, !fIncludeWatchonly);
|
||||
CAmount nTotalBalance = nBalance + nPrivateBalance;
|
||||
@@ -4856,7 +4857,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
" \"rk\" : \"rk\", (string) The rk\n"
|
||||
" \"zkproof\" : \"zkproof\", (string) Hexadecimal string representation of raw zksnark proof\n"
|
||||
" \"outputPrev\" : n, (numeric) the index of the output within the vShieldedOutput\n"
|
||||
" \"address\" : \"zcashaddress\", (string) The Hush shielded address involved in the transaction\n"
|
||||
" \"address\" : \"dragonxaddress\", (string) The DragonX shielded address involved in the transaction\n"
|
||||
" \"value\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n"
|
||||
" \"valueZat\" : xxxx (numeric) The amount in puposhis\n"
|
||||
" }\n"
|
||||
@@ -4866,7 +4867,7 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
" {\n"
|
||||
" \"type\" : \"sapling\", (string) The type of address\n"
|
||||
" \"output\" : n, (numeric) the index of the output within the vShieldedOutput\n"
|
||||
" \"address\" : \"hushaddress\", (string) The Hush address involved in the transaction\n"
|
||||
" \"address\" : \"dragonxaddress\", (string) The DragonX address involved in the transaction\n"
|
||||
" \"outgoing\" : true|false (boolean) True if the output is not for an address in the wallet\n"
|
||||
" \"value\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n"
|
||||
" \"valueZat\" : xxxx (numeric) The amount in puposhis\n"
|
||||
@@ -5143,7 +5144,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// Hilarious that Komodo commented this out, opening themselves up to metadata attackz, lulz
|
||||
// Guard against building shielded transactions before the chain is fully synced;
|
||||
// sending while behind the tip can leak metadata usable for linkability analysis.
|
||||
THROW_IF_SYNCING(HUSH_INSYNC);
|
||||
|
||||
// Check that the from address is valid.
|
||||
@@ -5388,6 +5390,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
// SIETCH: Sprinkle our cave with some magic privacy zdust
|
||||
// End goal is to have this be as large as possible without slowing xtns down too much
|
||||
// A value of 7 will provide much stronger linkability privacy versus pre-Sietch operations
|
||||
// DEFAULT_MIN_ZOUTS (7): default number of dummy z-outputs padded onto each z_sendmany.
|
||||
// MAX_ZOUTS (50): upper bound for the operator-tunable -sietch-min-zouts arg.
|
||||
// The effective floor is clamped to [3, MAX_ZOUTS] below.
|
||||
unsigned int DEFAULT_MIN_ZOUTS=7;
|
||||
unsigned int MAX_ZOUTS=50;
|
||||
unsigned int MIN_ZOUTS=GetArg("-sietch-min-zouts", DEFAULT_MIN_ZOUTS);
|
||||
@@ -5457,9 +5462,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
txsize += GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
|
||||
if (fromTaddr) {
|
||||
txsize += CTXIN_SPEND_DUST_SIZE;
|
||||
//TODO: On HUSH since block 340k there can no longer be taddr change,
|
||||
// (except for notary addresses)
|
||||
// so we can likely make a better estimation of max txsize
|
||||
// DragonX is ac_private=1 (fully shielded from genesis); transparent outputs are
|
||||
// banned, so in practice there is no taddr change and this estimate is conservative.
|
||||
txsize += CTXOUT_REGULAR_SIZE; // There will probably be taddr change
|
||||
}
|
||||
txsize += CTXOUT_REGULAR_SIZE * taddrRecipients.size();
|
||||
@@ -5594,7 +5598,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// Hilarious that Komodo commented this out, opening themselves up to metadata attackz, lulz
|
||||
// Guard against building shielded transactions before the chain is fully synced;
|
||||
// sending while behind the tip can leak metadata usable for linkability analysis.
|
||||
THROW_IF_SYNCING(HUSH_INSYNC);
|
||||
|
||||
// Validate the from address
|
||||
@@ -5840,7 +5845,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// Hilarious that Komodo commented this out, opening themselves up to metadata attackz, lulz
|
||||
// Guard against building shielded transactions before the chain is fully synced;
|
||||
// sending while behind the tip can leak metadata usable for linkability analysis.
|
||||
THROW_IF_SYNCING(HUSH_INSYNC);
|
||||
|
||||
bool useAnyUTXO = false;
|
||||
|
||||
@@ -578,7 +578,7 @@ void CWallet::ChainTip(const CBlockIndex *pindex,
|
||||
}
|
||||
|
||||
void CWallet::RunSaplingSweep(int blockHeight) {
|
||||
// Sapling is always active since height=1 of HUSH+HACs
|
||||
// Sapling is always active since height=1 on DragonX
|
||||
// if (!NetworkUpgradeActive(blockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||
// return;
|
||||
// }
|
||||
@@ -669,7 +669,7 @@ void CWallet::RunSaplingSweep(int blockHeight) {
|
||||
}
|
||||
|
||||
void CWallet::RunSaplingConsolidation(int blockHeight) {
|
||||
// Sapling is always active on HUSH+HACs
|
||||
// Sapling is always active on DragonX (activated at height=1)
|
||||
//if (!NetworkUpgradeActive(blockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||
// return;
|
||||
//}
|
||||
@@ -2380,7 +2380,7 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
|
||||
|
||||
case TX_SCRIPTHASH:
|
||||
scriptID = CScriptID(uint160(vSolutions[0]));
|
||||
//TODO: remove CLTV stuff not relevant to Hush
|
||||
//TODO: evaluate whether this CLTV timelock handling is needed on DragonX
|
||||
if (this->GetCScript(scriptID, subscript))
|
||||
{
|
||||
// if this is a CLTV, handle it differently
|
||||
@@ -4580,7 +4580,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
|
||||
std::numeric_limits<unsigned int>::max()-1));
|
||||
|
||||
// All Hush Arrakis Chains always have overwinter NU and so this option was never used
|
||||
// DragonX always has the Overwinter NU active and so this option was never used
|
||||
// Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
|
||||
// const size_t limit = 0; // (size_t)GetArg("-mempooltxinputlimit", 0);
|
||||
//{
|
||||
@@ -5727,7 +5727,7 @@ SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingE
|
||||
if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) {
|
||||
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = nTime;
|
||||
} else {
|
||||
// TODO: set a better time for HUSH+HACs
|
||||
// TODO: set a better time for DragonX
|
||||
// 154051200 seconds from epoch is Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates
|
||||
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user