Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ycask fork on testnet at block 478989 #3978

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 36 additions & 9 deletions src/chainparams.cpp
Expand Up @@ -106,8 +106,8 @@ class CMainParams : public CChainParams {
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 347500;
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007;
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 419200;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170009;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight =
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nProtocolVersion = 170009;
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nActivationHeight =
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;

// The best chain should have at least this much work.
Expand Down Expand Up @@ -272,6 +272,7 @@ class CTestNetParams : public CChainParams {
consensus.nMajorityRejectBlockOutdated = 75;
consensus.nMajorityWindow = 400;
consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
//consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
consensus.nPowAveragingWindow = 17;
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow);
consensus.nPowMaxAdjustDown = 32; // 32% adjustment down
Expand All @@ -288,9 +289,8 @@ class CTestNetParams : public CChainParams {
consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 207500;
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007;
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 280000;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170008;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight =
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nProtocolVersion = 270008;
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nActivationHeight = 478989;

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000000000001d0c4d9cd");
Expand Down Expand Up @@ -321,7 +321,7 @@ class CTestNetParams : public CChainParams {
vSeeds.push_back(CDNSSeedData("z.cash", "dnsseed.testnet.z.cash")); // Zcash

// guarantees the first 2 characters, when base58 encoded, are "tm"
base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25};
base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25}; // s - {0x20,0x28}; tm = {0x1C,0x90};
// guarantees the first 2 characters, when base58 encoded, are "t2"
base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA};
// the first character, when base58 encoded, is "9" or "c" (as in Bitcoin)
Expand All @@ -330,7 +330,7 @@ class CTestNetParams : public CChainParams {
base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94};
// guarantees the first 2 characters, when base58 encoded, are "zt"
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6};
base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6}; // zt - {0x16,0xB6}; yt - {0x15,0xB6}
// guarantees the first 4 characters, when base58 encoded, are "ZiVt"
base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C};
// guarantees the first 2 characters, when base58 encoded, are "ST"
Expand Down Expand Up @@ -422,8 +422,8 @@ class CRegTestParams : public CChainParams {
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170006;
consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight =
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170008;
consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight =
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nProtocolVersion = 170008;
consensus.vUpgrades[Consensus::UPGRADE_YCASH].nActivationHeight =
Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;

// The best chain should have at least this much work.
Expand Down Expand Up @@ -569,3 +569,30 @@ void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivation
{
regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight);
}

// To help debugging, let developers change the equihash parameters for a network upgrade.
// TODO: Restrict this to regtest mode in the future.
void UpdateEquihashUpgradeParameters(Consensus::UpgradeIndex idx, unsigned int n, unsigned int k)
{
assert(idx > Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES);
EquihashUpgradeInfo[idx].N = n;
EquihashUpgradeInfo[idx].K = k;
}

// Return Equihash parameter N at a given block height.
unsigned int CChainParams::EquihashN(int nHeight) const {
unsigned int n = EquihashUpgradeInfo[CurrentEpoch(nHeight, GetConsensus())].N;
if (n == EquihashInfo::DEFAULT_PARAMS) {
n = nEquihashN;
}
return n;
}

// Return Equihash parameter K at a given block height.
unsigned int CChainParams::EquihashK(int nHeight) const {
unsigned int k = EquihashUpgradeInfo[CurrentEpoch(nHeight, GetConsensus())].K;
if (k == EquihashInfo::DEFAULT_PARAMS) {
k = nEquihashK;
}
return k;
}
11 changes: 9 additions & 2 deletions src/chainparams.h
Expand Up @@ -83,8 +83,10 @@ class CChainParams
/** Policy: Filter transactions that do not match well-defined patterns */
bool RequireStandard() const { return fRequireStandard; }
int64_t PruneAfterHeight() const { return nPruneAfterHeight; }
unsigned int EquihashN() const { return nEquihashN; }
unsigned int EquihashK() const { return nEquihashK; }

unsigned int EquihashN(int nHeight = 0) const;
unsigned int EquihashK(int nHeight = 0) const;

std::string CurrencyUnits() const { return strCurrencyUnits; }
uint32_t BIP44CoinType() const { return bip44CoinType; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
Expand Down Expand Up @@ -160,4 +162,9 @@ bool SelectParamsFromCommandLine();
*/
void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight);

/**
* Let developers modify the equihash upgrade parameters for testing purposes.
*/
void UpdateEquihashUpgradeParameters(Consensus::UpgradeIndex idx, unsigned int n, unsigned int k);

#endif // BITCOIN_CHAINPARAMS_H
2 changes: 1 addition & 1 deletion src/consensus/params.h
Expand Up @@ -26,7 +26,7 @@ enum UpgradeIndex {
UPGRADE_TESTDUMMY,
UPGRADE_OVERWINTER,
UPGRADE_SAPLING,
UPGRADE_BLOSSOM,
UPGRADE_YCASH,
// NOTE: Also add new upgrades to NetworkUpgradeInfo in upgrades.cpp
MAX_NETWORK_UPGRADES
};
Expand Down
42 changes: 39 additions & 3 deletions src/consensus/upgrades.cpp
Expand Up @@ -30,14 +30,50 @@ const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = {
/*.strInfo =*/ "See https://z.cash/upgrade/sapling.html for details.",
},
{
/*.nBranchId =*/ 0x2bb40e60,
/*.strName =*/ "Blossom",
/*.strInfo =*/ "See https://z.cash/upgrade/blossom.html for details.",
/*.nBranchId =*/ 0x4bb40e60,
/*.strName =*/ "YCash",
/*.strInfo =*/ "See YCash for details.",
}
};

const uint32_t SPROUT_BRANCH_ID = NetworkUpgradeInfo[Consensus::BASE_SPROUT].nBranchId;


/**
* General information associating epoch with equihash parameters.
* Ordered by Consensus::UpgradeIndex, to match NetworkUpgradeInfo.
* TODO: Maybe refactor and include in NetworkUpgradeInfo
* TODO: Make this const
*/
struct EquihashInfo EquihashUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = {
// BASE_SPROUT
{
/* N = */ EquihashInfo::DEFAULT_PARAMS,
/* K = */ EquihashInfo::DEFAULT_PARAMS,
},
// UPGRADE_TESTDUMMY
{
/* N = */ EquihashInfo::DEFAULT_PARAMS,
/* K = */ EquihashInfo::DEFAULT_PARAMS,
},
// UPGRADE_OVERWINTER
{
/* N = */ EquihashInfo::DEFAULT_PARAMS,
/* K = */ EquihashInfo::DEFAULT_PARAMS,
},
// UPGRADE SAPLING
{
/* N = */ EquihashInfo::DEFAULT_PARAMS,
/* K = */ EquihashInfo::DEFAULT_PARAMS,
},
// UPGRADE YCASH
{
// TODO (A): Finalize Equihash params
/* N = */ 96,
/* K = */ 5,
}
};

UpgradeState NetworkUpgradeState(
int nHeight,
const Consensus::Params& params,
Expand Down
13 changes: 13 additions & 0 deletions src/consensus/upgrades.h
Expand Up @@ -29,6 +29,19 @@ extern const struct NUInfo NetworkUpgradeInfo[];
// Consensus branch id to identify pre-overwinter (Sprout) consensus rules.
extern const uint32_t SPROUT_BRANCH_ID;


struct EquihashInfo {
unsigned int N;
unsigned int K;

// Use default value as set in chainparams and genesis block
static constexpr int DEFAULT_PARAMS = 0;
};

extern struct EquihashInfo EquihashUpgradeInfo[];



/**
* Checks the state of a given network upgrade based on block height.
* Caller must check that the height is >= 0 (and handle unknown heights).
Expand Down
13 changes: 13 additions & 0 deletions src/crypto/equihash.cpp
Expand Up @@ -814,3 +814,16 @@ template bool Equihash<48,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<48,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);


// Explicit instantiations for Equihash<144,5>
template int Equihash<144,5>::InitialiseState(eh_HashState& base_state);
#ifdef ENABLE_MINING
template bool Equihash<144,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
template bool Equihash<144,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
#endif
template bool Equihash<144,5>::IsValidSolution(const eh_HashState& base_state, std::vector<unsigned char> soln);
9 changes: 9 additions & 0 deletions src/crypto/equihash.h
Expand Up @@ -199,6 +199,7 @@ static Equihash<96,3> Eh96_3;
static Equihash<200,9> Eh200_9;
static Equihash<96,5> Eh96_5;
static Equihash<48,5> Eh48_5;
static Equihash<144,5> Eh144_5;

#define EhInitialiseState(n, k, base_state) \
if (n == 96 && k == 3) { \
Expand All @@ -209,6 +210,8 @@ static Equihash<48,5> Eh48_5;
Eh96_5.InitialiseState(base_state); \
} else if (n == 48 && k == 5) { \
Eh48_5.InitialiseState(base_state); \
} else if (n == 144 && k == 5) { \
Eh144_5.InitialiseState(base_state); \
} else { \
throw std::invalid_argument("Unsupported Equihash parameters"); \
}
Expand All @@ -226,6 +229,8 @@ inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& bas
return Eh96_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) {
return Eh48_5.BasicSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.BasicSolve(base_state, validBlock, cancelled);
} else {
throw std::invalid_argument("Unsupported Equihash parameters");
}
Expand All @@ -250,6 +255,8 @@ inline bool EhOptimisedSolve(unsigned int n, unsigned int k, const eh_HashState&
return Eh96_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 48 && k == 5) {
return Eh48_5.OptimisedSolve(base_state, validBlock, cancelled);
} else if (n == 144 && k == 5) {
return Eh144_5.OptimisedSolve(base_state, validBlock, cancelled);
} else {
throw std::invalid_argument("Unsupported Equihash parameters");
}
Expand All @@ -272,6 +279,8 @@ inline bool EhOptimisedSolveUncancellable(unsigned int n, unsigned int k, const
ret = Eh96_5.IsValidSolution(base_state, soln); \
} else if (n == 48 && k == 5) { \
ret = Eh48_5.IsValidSolution(base_state, soln); \
} else if (n == 144 && k == 5) { \
ret = Eh144_5.IsValidSolution(base_state, soln); \
} else { \
throw std::invalid_argument("Unsupported Equihash parameters"); \
}
Expand Down
41 changes: 41 additions & 0 deletions src/init.cpp
Expand Up @@ -454,6 +454,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
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)");
strUsage += HelpMessageOpt("-eqparams=hexBranchId:N:K", "Use given equihash parameters for specified network upgrade");
}
string debugCategories = "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)"; // Don't translate these
Expand Down Expand Up @@ -1138,6 +1139,46 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}


if (!mapMultiArgs["-eqparams"].empty()) {
// Allow overriding equihash upgrade parameters for testing
if (Params().NetworkIDString() != "regtest") {
return InitError("Network upgrade parameters may only be overridden on regtest.");
}
const vector<string>& deployments = mapMultiArgs["-eqparams"];
for (auto i : deployments) {
std::vector<std::string> vDeploymentParams;
boost::split(vDeploymentParams, i, boost::is_any_of(":"));
if (vDeploymentParams.size() != 3) {
return InitError("Equihash upgrade parameters malformed, expecting hexBranchId:N:K");
}
int n, k;
// TODO: Restrict to support n,k parameters and cast to unsigned int
if (!ParseInt32(vDeploymentParams[1], &n)) {
return InitError(strprintf("Invalid N (%s)", vDeploymentParams[1]));
}
if (!ParseInt32(vDeploymentParams[2], &k)) {
return InitError(strprintf("Invalid K (%s)", vDeploymentParams[2]));
}
bool found = false;
// Exclude Sprout from upgrades
for (auto i = Consensus::BASE_SPROUT + 1; i < Consensus::MAX_NETWORK_UPGRADES; ++i)
{
if (vDeploymentParams[0].compare(HexInt(NetworkUpgradeInfo[i].nBranchId)) == 0) {
UpdateEquihashUpgradeParameters(Consensus::UpgradeIndex(i), n, k);
found = true;
LogPrintf("Setting equihash upgrade activation parameters for %s to n=%d, k=%d\n", vDeploymentParams[0], n, k);
break;
}
}
if (!found) {
return InitError(strprintf("Invalid equihash upgrade (%s)", vDeploymentParams[0]));
}
}
}



// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log

// Initialize libsodium
Expand Down
16 changes: 16 additions & 0 deletions src/main.cpp
Expand Up @@ -3753,6 +3753,22 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta

int nHeight = pindexPrev->nHeight+1;

// If the equihash solution is set, check the size is correct for given parameters.
size_t nSolSize = block.nSolution.size();
if (nSolSize > 0) {
int n = chainParams.EquihashN(nHeight);
int k = chainParams.EquihashK(nHeight);
size_t expectedSize = (pow(2, k) * ((n/(k+1))+1)) / 8;
if (nSolSize != expectedSize){
return state.DoS(
100,
error("%s: incorrect equihash solution size %d, expected size %d for parameters (%d, %d)",
__func__, nSolSize, expectedSize, n, k),
REJECT_INVALID,
"bad-equihash-solution-size");
}
}

// Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.DoS(100, error("%s: incorrect proof of work", __func__),
Expand Down
19 changes: 14 additions & 5 deletions src/miner.cpp
Expand Up @@ -533,12 +533,9 @@ void static BitcoinMiner(const CChainParams& chainparams)
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);

unsigned int n = chainparams.EquihashN();
unsigned int k = chainparams.EquihashK();

std::string solver = GetArg("-equihashsolver", "default");
assert(solver == "tromp" || solver == "default");
LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);


std::mutex m_cs;
bool cancelSolver = false;
Expand Down Expand Up @@ -577,7 +574,19 @@ void static BitcoinMiner(const CChainParams& chainparams)
// Create new block
//
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrev = chainActive.Tip();

// Get the height of current tip
int nHeight = chainActive.Height();
if (nHeight == -1) {
LogPrintf("Error in ZcashMiner: chainActive.Height() returned -1\n");
return;
}
CBlockIndex* pindexPrev = chainActive[nHeight];

// Get equihash parameters for the next block to be mined.
unsigned int n = chainparams.EquihashN(nHeight + 1);
unsigned int k = chainparams.EquihashK(nHeight + 1);
LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);

unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript));
if (!pblocktemplate.get())
Expand Down