From bd88898ce037f6ee0e7bb945d9da4b221f931e8f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 12 Apr 2020 05:55:08 -0400 Subject: [PATCH 1/7] Implement z2z transition period for mempool --- src/main.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 17b89a76b..aa8ba176e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1741,6 +1741,25 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel) { AssertLockHeld(cs_main); + uint32_t z2zTransitionWindow = 10; + uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow; + uint32_t z2zTransitionEnd = 340000; + bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + uint32_t nHeight = chainActive.Height(); + + // This only applies to HUSH3, other chains can start off z2z via ac_private=1 + if(ishush3) { + if((nHeight >= z2zTransitionStart) || (nHeight <= z2zTransitionEnd)) { + // During the z2z transition window, only coinbase tx's as part of blocks are allowed + // Theory: We want an empty mempool at our fork block height, and the only way to assure that + // is to have an empty mempool for a few previous blocks, to take care of potential re-orgs + // and edge cases. This empty mempool assures there will be no transactions involving taddrs + // stuck in the mempool, when the z2z rule takes effect. + // Thanks to jl777 for helping design this + fprintf(stderr,"%s: rejecting all tx's during z2z transition window at height=%d\n", __func__,nHeight); + return false; + } + } if (pfMissingInputs) *pfMissingInputs = false; uint32_t tiptime; From 3d9e662266a28f6d634185d239b6b23ec362b629 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Apr 2020 07:53:01 -0400 Subject: [PATCH 2/7] Switch to -ac_private=1 at our z2z fork height --- src/main.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index aa8ba176e..7575a4e0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3368,6 +3368,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return(false); //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight()); AssertLockHeld(cs_main); + + bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + if(!ASSETCHAINS_PRIVATE && ishush3) { + unsigned int z2zForkHeight = 340000; + unsigned int nHeight = pindex->GetHeight(); + if(nHeight >= z2zForkHeight) { + // At startup, HUSH3 doesn't know a block height yet and so we must wait until + // connecting a block + fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,nHeight); + ASSETCHAINS_PRIVATE = 1; + } + } + bool fExpensiveChecks = true; if (fCheckpointsEnabled) { CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); From e51556083793c3c5272f31b3e64cf6cfecddae27 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Apr 2020 22:27:24 -0400 Subject: [PATCH 3/7] Improve and remove mention of sprout in this error message --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7575a4e0a..20c6cffe6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1591,11 +1591,11 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio if ( counter++ < 10 ) fprintf(stderr,"found taddr in private chain: z_z.%d z_t.%d t_z.%d vinsize.%d\n",z_z,z_t,t_z,(int32_t)tx.vin.size()); if ( z_t == 0 || z_z != 0 || t_z != 0 || tx.vin.size() != 0 ) - return state.DoS(100, error("CheckTransaction(): this is a private chain, only sprout -> taddr allowed until deadline"),REJECT_INVALID, "bad-txns-acprivacy-chain"); + return state.DoS(100, error("CheckTransaction(): this is a private chain, sending to taddrs not allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain"); } if ( ASSETCHAINS_TXPOW != 0 ) { - // genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + // BTC genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b uint256 txid = tx.GetHash(); if ( ((ASSETCHAINS_TXPOW & 2) != 0 && iscoinbase != 0) || ((ASSETCHAINS_TXPOW & 1) != 0 && iscoinbase == 0) ) { From 77cc82428bab83079bdd3a0751645b2a8a25cc27 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 00:59:47 -0400 Subject: [PATCH 4/7] Hush Smart Chains --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index ac15db192..b9bc096a7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -581,7 +581,7 @@ 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(_("Komodo Asset Chain options:")); + 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")); strUsage += HelpMessageOpt("-ac_cc", _("Cryptoconditions, default 0")); From a2013ecc39219151067578661b3dbf13b4e1fe7f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 02:07:19 -0400 Subject: [PATCH 5/7] Fix incorrect error message --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 20c6cffe6..cfe851f7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6121,7 +6121,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); + throw runtime_error("InsertBlockIndex(): new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str()); From 41a4c84633945f868061abd0b17741ecceaa1935 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 02:39:18 -0400 Subject: [PATCH 6/7] Refactor z2z and additionally set ac_private=1 when loading block index from disk This should avoid the edge case when a node starts up after the z2z block height but has not yet seen a new block and so does not yet know it is an -ac_private=1 chain, as currently that is set in ConnectBlock. --- src/main.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cfe851f7f..472a8bb90 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,6 +114,8 @@ bool fAlerts = DEFAULT_ALERTS; /* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; +bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; +unsigned int z2zForkHeight = 340000; unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1742,14 +1744,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { AssertLockHeld(cs_main); uint32_t z2zTransitionWindow = 10; - uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow; - uint32_t z2zTransitionEnd = 340000; - bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; - uint32_t nHeight = chainActive.Height(); + uint32_t z2zTransitionStart = z2zForkHeight - z2zTransitionWindow; + uint32_t nHeight = chainActive.Height(); // This only applies to HUSH3, other chains can start off z2z via ac_private=1 if(ishush3) { - if((nHeight >= z2zTransitionStart) || (nHeight <= z2zTransitionEnd)) { + if((nHeight >= z2zTransitionStart) || (nHeight <= z2zForkHeight)) { // During the z2z transition window, only coinbase tx's as part of blocks are allowed // Theory: We want an empty mempool at our fork block height, and the only way to assure that // is to have an empty mempool for a few previous blocks, to take care of potential re-orgs @@ -3371,7 +3371,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; if(!ASSETCHAINS_PRIVATE && ishush3) { - unsigned int z2zForkHeight = 340000; unsigned int nHeight = pindex->GetHeight(); if(nHeight >= z2zForkHeight) { // At startup, HUSH3 doesn't know a block height yet and so we must wait until @@ -6338,6 +6337,13 @@ bool static LoadBlockIndexDB() chainActive.SetTip(it->second); + // Try to detect if we are z2z based on height of blocks on disk + // This helps to set it correctly on startup before a new block is connected + if(ishush3 && chainActive.Height() >= z2zForkHeight) { + LogPrintf("%s: enabled ac_private=1 at height=%d\n", __func__, chainActive.Height()); + ASSETCHAINS_PRIVATE = 1; + } + // Set hashFinalSproutRoot for the end of best chain it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT); From 1009c7933de1d284e83afc139a599b0efd1785cf Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Apr 2020 22:10:25 -0400 Subject: [PATCH 7/7] CLI arg -z2zforkheight and avoid a compiler warning --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 472a8bb90..e1beb5c5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; -unsigned int z2zForkHeight = 340000; +unsigned int z2zForkHeight = GetArg("-z2zforkheight",340000); unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1329,7 +1329,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde )) { librustzcash_sapling_verification_ctx_free(ctx); - fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%d\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); + fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%li\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"), REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); }