634 lines
28 KiB
C++
634 lines
28 KiB
C++
// Copyright (c) 2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
|
// Copyright (c) 2026 The Vexta Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include "arith_uint256.h"
|
|
#include <chainparams.h>
|
|
|
|
#include <chainparamsseeds.h>
|
|
#include <consensus/merkle.h>
|
|
#include <deploymentinfo.h>
|
|
#include <hash.h> // for signet block challenge hash
|
|
#include <util/system.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <boost/algorithm/string/classification.hpp>
|
|
#include <boost/algorithm/string/split.hpp>
|
|
|
|
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
|
|
{
|
|
CMutableTransaction txNew;
|
|
txNew.nVersion = 1;
|
|
txNew.vin.resize(1);
|
|
txNew.vout.resize(1);
|
|
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
|
|
txNew.vout[0].nValue = genesisReward;
|
|
txNew.vout[0].scriptPubKey = CScript() << 0x0 << OP_CHECKSIG;
|
|
|
|
CBlock genesis;
|
|
genesis.nTime = nTime;
|
|
genesis.nBits = nBits;
|
|
genesis.nNonce = nNonce;
|
|
genesis.nVersion = nVersion;
|
|
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
|
|
genesis.hashPrevBlock.SetNull();
|
|
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
|
|
return genesis;
|
|
}
|
|
|
|
/**
|
|
* Build the genesis block. Note that the output of its generation
|
|
* transaction cannot be spent since it did not originally exist in the
|
|
* database.
|
|
*
|
|
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
|
|
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
|
|
* CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
|
|
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
|
|
* vMerkleTree: 4a5e1e
|
|
*/
|
|
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
|
|
{
|
|
const char* pszTimestamp = "Vexta Genesis Block 29/Jun/2026 - VTX network begins";
|
|
const CScript genesisOutputScript = CScript() << 0x0 << OP_CHECKSIG;
|
|
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
|
|
}
|
|
|
|
/**
|
|
* Main network on which people trade goods and services.
|
|
*/
|
|
class CMainParams : public CChainParams {
|
|
public:
|
|
CMainParams() {
|
|
strNetworkID = CBaseChainParams::MAIN;
|
|
consensus.signet_blocks = false;
|
|
consensus.signet_challenge.clear();
|
|
consensus.BIP16Exception = uint256S("0x0");
|
|
|
|
// BIP34, BIP65 and BIP66, CSV and Segwit were activated simultaneously
|
|
// DEPLOYMENT_NVERSIONBIPS, DEPLOYMENT_CSV, DEPLOYMENT_SEGWIT
|
|
consensus.BIP34Hash = uint256S("0xadd8ca420f557f62377ec2be6e6f47b96cf2e68160d58aeb7b73433de834cca0");
|
|
consensus.BIP34Height = consensus.BIP65Height = consensus.BIP66Height = 1; // Vexta: active from block 1
|
|
consensus.CSVHeight = consensus.SegwitHeight = 1; // Vexta: active from block 1
|
|
|
|
|
|
consensus.powLimit = ArithToUint256(~arith_uint256(0) >> 20);
|
|
consensus.nPowTargetSpacing = 10 * 60;
|
|
consensus.nSubsidyHalvingInterval = 210000; // ~4 years at 10 minute blocks
|
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
|
consensus.fEasyPow = false;
|
|
consensus.fPowNoRetargeting = false;
|
|
consensus.fRbfEnabled = false;
|
|
|
|
// Vexta consensus parameters
|
|
consensus.nRuleChangeActivationThreshold = 28224; // 28224 - 70% of 40320 blocks
|
|
consensus.nMinerConfirmationWindow = 40320; // 1 week of blocks
|
|
|
|
// Suppress unknown activation warnings before the configured warning height
|
|
consensus.MinBIP9WarningHeight = 1; // Vexta: deployments are active from launch
|
|
|
|
// Vexta protocol activation heights
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 27;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
|
|
|
// Deployment of Taproot (BIPs 340-342)
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
|
|
|
// The best chain should have at least this much work.
|
|
consensus.nMinimumChainWork = uint256{};
|
|
|
|
// By default assume that the signatures in ancestors of this block are valid.
|
|
consensus.defaultAssumeValid = uint256{};
|
|
|
|
/**
|
|
* The message start string is designed to be unlikely to occur in normal data.
|
|
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
|
|
* a large 32-bit integer with any alignment.
|
|
*/
|
|
pchMessageStart[0] = 0x56; // V
|
|
pchMessageStart[1] = 0x54; // T
|
|
pchMessageStart[2] = 0x58; // X
|
|
pchMessageStart[3] = 0x31; // 1
|
|
nDefaultPort = 19333;
|
|
nPruneAfterHeight = 100000;
|
|
m_assumed_blockchain_size = 0;
|
|
m_assumed_chain_state_size = 0;
|
|
|
|
genesis = CreateGenesisBlock(1782770400, 1605828, 0x1e0ffff0, BLOCK_VERSION_SHA256D, 50 * COIN);
|
|
consensus.hashGenesisBlock = genesis.GetHash();
|
|
assert(consensus.hashGenesisBlock == uint256S("0x0000027626959d894ae1c8a6f9050cdcbdf58eb0037ab06345cb5502955370f1"));
|
|
assert(genesis.hashMerkleRoot == uint256S("0x3c1f602428f06c9baf0961930a5f711a2b5fd6157a9922365e7f1eca1970ff16"));
|
|
|
|
// Public Vexta mainnet seed nodes.
|
|
vSeeds.emplace_back("87.106.99.23"); // UK seed
|
|
vSeeds.emplace_back("74.208.53.160"); // US seed
|
|
|
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,70);
|
|
base58Prefixes[SCRIPT_ADDRESS_OLD] = std::vector<unsigned char>(1,85);
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,85);
|
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,198);
|
|
base58Prefixes[SECRET_KEY_OLD] = std::vector<unsigned char>(1,199);
|
|
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
|
|
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
|
|
|
|
bech32_hrp = "vtx";
|
|
|
|
vFixedSeeds.clear(); // Vexta: no hardcoded seeds yet
|
|
|
|
fDefaultConsistencyChecks = false;
|
|
fRequireStandard = true;
|
|
m_is_test_chain = false;
|
|
m_is_mockable_chain = false;
|
|
|
|
checkpointData = {
|
|
{
|
|
{0, consensus.hashGenesisBlock},
|
|
}
|
|
};
|
|
|
|
chainTxData = ChainTxData{
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
// Vexta difficulty parameters.
|
|
//
|
|
// Vexta uses a single SHA256D proof-of-work algorithm with a moving
|
|
// averaging window for difficulty adjustment.
|
|
|
|
|
|
consensus.difficultyAveragingWindow = 10; // 10 blocks
|
|
consensus.difficultyTargetTimespan = consensus.difficultyAveragingWindow * consensus.nPowTargetSpacing;
|
|
|
|
|
|
consensus.difficultyMinActualTimespan = consensus.difficultyTargetTimespan * 92 / 100;
|
|
consensus.difficultyMaxActualTimespan = consensus.difficultyTargetTimespan * 116 / 100;
|
|
|
|
|
|
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Testnet (v3): public test network which is reset from time to time.
|
|
*/
|
|
class CTestNetParams : public CChainParams {
|
|
public:
|
|
CTestNetParams() {
|
|
strNetworkID = "test";
|
|
consensus.powLimit = ArithToUint256(~arith_uint256(0) >> 20);
|
|
consensus.nPowTargetSpacing = 10 * 60;
|
|
consensus.nSubsidyHalvingInterval = 210000; // ~4 years at 10 minute blocks
|
|
|
|
consensus.BIP16Exception = uint256();
|
|
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
|
|
consensus.BIP34Hash = uint256();
|
|
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in functional tests)
|
|
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in functional tests)
|
|
consensus.CSVHeight = 1; // CSV activated on regtest (Used in rpc activation tests)
|
|
consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden
|
|
|
|
consensus.MinBIP9WarningHeight = 0;
|
|
|
|
// Vexta difficulty parameters.
|
|
//
|
|
// Vexta uses a single SHA256D proof-of-work algorithm with a moving
|
|
// averaging window for difficulty adjustment.
|
|
|
|
|
|
consensus.difficultyAveragingWindow = 10; // 10 blocks
|
|
consensus.difficultyTargetTimespan = consensus.difficultyAveragingWindow * consensus.nPowTargetSpacing;
|
|
|
|
|
|
consensus.difficultyMinActualTimespan = consensus.difficultyTargetTimespan * 92 / 100;
|
|
consensus.difficultyMaxActualTimespan = consensus.difficultyTargetTimespan * 116 / 100;
|
|
|
|
|
|
|
|
// Vexta protocol activation heights
|
|
|
|
consensus.fPowAllowMinDifficultyBlocks = true;
|
|
consensus.fEasyPow = false;
|
|
consensus.fPowNoRetargeting = true;
|
|
consensus.nRuleChangeActivationThreshold = 4032; // 4032 - 70% of 5760
|
|
consensus.nMinerConfirmationWindow = 5760; // 1 day of blocks on testnet
|
|
consensus.fRbfEnabled = false;
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 27;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1619222400; // April 24th, 2021
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1628640000; // August 11th, 2021
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
|
|
|
// Deployment of Taproot (BIPs 340-342)
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1718921304; // 20th June 2024 Testnet
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1750457304; // 20th June 2025 Testnet
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
|
|
|
|
|
// The best chain should have at least this much work.
|
|
consensus.nMinimumChainWork = uint256{};
|
|
|
|
// By default assume that the signatures in ancestors of this block are valid.
|
|
consensus.defaultAssumeValid = uint256{};
|
|
|
|
pchMessageStart[0] = 0x56; // V
|
|
pchMessageStart[1] = 0x54; // T
|
|
pchMessageStart[2] = 0x58; // X
|
|
pchMessageStart[3] = 0x54; // T
|
|
nDefaultPort = 12026;
|
|
nPruneAfterHeight = 1000;
|
|
m_assumed_blockchain_size = 0;
|
|
m_assumed_chain_state_size = 0;
|
|
|
|
genesis = CreateGenesisBlock("Vexta Testnet Genesis Block 09/Jul/2026 - VTX test network begins", CScript() << 0x0 << OP_CHECKSIG, 1783555200, 2228323, 0x1e0ffff0, 1, 50 * COIN);
|
|
consensus.hashGenesisBlock = genesis.GetHash();
|
|
assert(consensus.hashGenesisBlock == uint256S("0x00000dc74b41d5ebb73e55098e160534f34ec418becf4a3aa5bb218e6055cca5"));
|
|
assert(genesis.hashMerkleRoot == uint256S("0x0fba2f6943df4ab9ffd13b5cf1233a825e364d2228a4683a72866b47d6a767c7"));
|
|
|
|
vFixedSeeds.clear();
|
|
vSeeds.clear();
|
|
|
|
// DNS seeds will be added after public Vexta testnet seed nodes are deployed.
|
|
|
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,126);
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,140);
|
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,254);
|
|
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
|
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
|
|
|
bech32_hrp = "vtxt";
|
|
|
|
vFixedSeeds.clear(); // Vexta: no hardcoded testnet seeds yet
|
|
|
|
fDefaultConsistencyChecks = false;
|
|
fRequireStandard = false;
|
|
m_is_test_chain = true;
|
|
m_is_mockable_chain = false;
|
|
|
|
checkpointData = {
|
|
{
|
|
{0, consensus.hashGenesisBlock},
|
|
}
|
|
};
|
|
|
|
m_assumeutxo_data = MapAssumeutxo{};
|
|
|
|
chainTxData = ChainTxData{
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Signet: test network with an additional consensus parameter (see BIP325).
|
|
*/
|
|
class SigNetParams : public CChainParams {
|
|
public:
|
|
explicit SigNetParams(const ArgsManager& args) {
|
|
std::vector<uint8_t> bin;
|
|
vSeeds.clear();
|
|
|
|
if (!args.IsArgSet("-signetchallenge")) {
|
|
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
|
|
// DNS seeds will be added after first public Vexta signet seed nodes are online.
|
|
|
|
consensus.nMinimumChainWork = uint256{};
|
|
consensus.defaultAssumeValid = uint256{};
|
|
m_assumed_blockchain_size = 0;
|
|
m_assumed_chain_state_size = 0;
|
|
chainTxData = ChainTxData{
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
} else {
|
|
const auto signet_challenge = args.GetArgs("-signetchallenge");
|
|
if (signet_challenge.size() != 1) {
|
|
throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__));
|
|
}
|
|
bin = ParseHex(signet_challenge[0]);
|
|
|
|
consensus.nMinimumChainWork = uint256{};
|
|
consensus.defaultAssumeValid = uint256{};
|
|
m_assumed_blockchain_size = 0;
|
|
m_assumed_chain_state_size = 0;
|
|
chainTxData = ChainTxData{
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
LogPrintf("Signet with challenge %s\n", signet_challenge[0]);
|
|
}
|
|
|
|
if (args.IsArgSet("-signetseednode")) {
|
|
vSeeds = args.GetArgs("-signetseednode");
|
|
}
|
|
|
|
strNetworkID = CBaseChainParams::SIGNET;
|
|
consensus.signet_blocks = true;
|
|
consensus.signet_challenge.assign(bin.begin(), bin.end());
|
|
consensus.BIP16Exception = uint256{};
|
|
consensus.BIP34Height = 1;
|
|
consensus.BIP34Hash = uint256{};
|
|
consensus.BIP65Height = 1;
|
|
consensus.BIP66Height = 1;
|
|
consensus.CSVHeight = 1;
|
|
consensus.SegwitHeight = 1;
|
|
consensus.nPowTargetSpacing = 10 * 60;
|
|
consensus.nSubsidyHalvingInterval = 210000; // ~4 years at 10 minute blocks
|
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
|
consensus.fEasyPow = false;
|
|
consensus.fPowNoRetargeting = false;
|
|
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
|
|
consensus.nMinerConfirmationWindow = 2016; // legacy Bitcoin confirmation window
|
|
consensus.fRbfEnabled = false;
|
|
|
|
consensus.MinBIP9WarningHeight = 0;
|
|
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 27;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
|
|
|
// Activation of Taproot (BIPs 340-342)
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
|
|
|
// message start is defined as the first 4 bytes of the sha256d of the block script
|
|
CHashWriter h(SER_DISK, 0);
|
|
h << consensus.signet_challenge;
|
|
uint256 hash = h.GetHash();
|
|
memcpy(pchMessageStart, hash.begin(), 4);
|
|
|
|
nDefaultPort = 38443;
|
|
nPruneAfterHeight = 1000;
|
|
|
|
genesis = CreateGenesisBlock("Vexta Signet Genesis Block 09/Jul/2026 - VTX signet network begins", CScript() << 0x0 << OP_CHECKSIG, 1783555202, 4047966, 0x1e0377ae, 1, 50 * COIN);
|
|
consensus.hashGenesisBlock = genesis.GetHash();
|
|
|
|
assert(consensus.hashGenesisBlock == uint256S("0x00000297613fa90675b13ac95d0590e95f787b15410ee3e568d7bc9df796c3c4"));
|
|
assert(genesis.hashMerkleRoot == uint256S("0xd4764aaa54047c0408946a09f43c28b167988604619d055854bc89d51bcb736e"));
|
|
|
|
vFixedSeeds.clear();
|
|
|
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,126);
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,140);
|
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,254);
|
|
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
|
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
|
|
|
bech32_hrp = "vtxt";
|
|
|
|
fDefaultConsistencyChecks = false;
|
|
fRequireStandard = true;
|
|
m_is_test_chain = true;
|
|
m_is_mockable_chain = false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Regression test: intended for private networks only. Has minimal difficulty to ensure that
|
|
* blocks can be found instantly.
|
|
*/
|
|
class CRegTestParams : public CChainParams {
|
|
public:
|
|
explicit CRegTestParams(const ArgsManager& args) {
|
|
strNetworkID = CBaseChainParams::REGTEST;
|
|
consensus.signet_blocks = false;
|
|
consensus.signet_challenge.clear();
|
|
consensus.BIP16Exception = uint256();
|
|
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
|
|
consensus.BIP34Hash = uint256();
|
|
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in functional tests)
|
|
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in functional tests)
|
|
consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
|
|
consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden
|
|
consensus.MinBIP9WarningHeight = 0;
|
|
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
consensus.fPowAllowMinDifficultyBlocks = true;
|
|
consensus.fEasyPow = false; // allow easy blocks on regtest (can be set with -easypow)
|
|
consensus.nPowTargetSpacing = 10 * 60;
|
|
consensus.nSubsidyHalvingInterval = 210000; // ~4 years at 10 minute blocks
|
|
|
|
consensus.difficultyAveragingWindow = 10; // 10 blocks
|
|
consensus.difficultyTargetTimespan = consensus.difficultyAveragingWindow * consensus.nPowTargetSpacing;
|
|
|
|
|
|
consensus.difficultyMinActualTimespan = consensus.difficultyTargetTimespan * 92 / 100;
|
|
consensus.difficultyMaxActualTimespan = consensus.difficultyTargetTimespan * 116 / 100;
|
|
|
|
|
|
consensus.BIP65Height = 1351;
|
|
consensus.BIP66Height = 1251;
|
|
|
|
// Vexta protocol activation heights
|
|
consensus.nRuleChangeActivationThreshold = 168; // 70% of 240
|
|
consensus.nMinerConfirmationWindow = 240; // 1 hour in RegTest
|
|
consensus.fRbfEnabled = false;
|
|
|
|
consensus.fPowNoRetargeting = true;
|
|
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 27;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
|
|
|
// Activation of Taproot (BIPs 340-342)
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
|
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
|
|
|
consensus.nMinimumChainWork = uint256{};
|
|
consensus.defaultAssumeValid = uint256{};
|
|
|
|
|
|
pchMessageStart[0] = 0x56; // V
|
|
pchMessageStart[1] = 0x54; // T
|
|
pchMessageStart[2] = 0x58; // X
|
|
pchMessageStart[3] = 0x52; // R
|
|
nDefaultPort = 18444;
|
|
nPruneAfterHeight = args.GetBoolArg("-fastprune", false) ? 100 : 1000;
|
|
m_assumed_blockchain_size = 0;
|
|
m_assumed_chain_state_size = 0;
|
|
|
|
bech32_hrp = "vtxrt";
|
|
|
|
UpdateActivationParametersFromArgs(args);
|
|
|
|
genesis = CreateGenesisBlock("Vexta Regtest Genesis Block 09/Jul/2026 - VTX regression test network begins", CScript() << 0x0 << OP_CHECKSIG, 1783555201, 5, 0x207fffff, 1, 50 * COIN);
|
|
consensus.hashGenesisBlock = genesis.GetHash();
|
|
|
|
assert(consensus.hashGenesisBlock == uint256S("0x3b5c0230bafd65f3dabcda2a30f33cdef0c3cda635e7440bda6909bb581462b7"));
|
|
assert(genesis.hashMerkleRoot == uint256S("0x1d7df76c2482ecb39a9347895f012dd0d03696f064feb4b484d5bdb4f33cd924"));
|
|
|
|
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
|
|
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
|
|
|
|
fDefaultConsistencyChecks = true;
|
|
fRequireStandard = true;
|
|
m_is_test_chain = true;
|
|
m_is_mockable_chain = true;
|
|
|
|
checkpointData = {
|
|
{
|
|
{0, consensus.hashGenesisBlock},
|
|
}
|
|
};
|
|
|
|
m_assumeutxo_data = MapAssumeutxo{};
|
|
|
|
chainTxData = ChainTxData{
|
|
0,
|
|
0,
|
|
0
|
|
};
|
|
|
|
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,126);
|
|
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,140);
|
|
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,254);
|
|
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
|
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
|
}
|
|
/**
|
|
* Allows modifying the Version Bits regtest parameters.
|
|
*/
|
|
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height)
|
|
{
|
|
consensus.vDeployments[d].nStartTime = nStartTime;
|
|
consensus.vDeployments[d].nTimeout = nTimeout;
|
|
consensus.vDeployments[d].min_activation_height = min_activation_height;
|
|
}
|
|
void UpdateActivationParametersFromArgs(const ArgsManager& args);
|
|
};
|
|
|
|
static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& consensus)
|
|
{
|
|
for (const std::string& arg : args.GetArgs("-testactivationheight")) {
|
|
const auto found{arg.find('@')};
|
|
if (found == std::string::npos) {
|
|
throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg));
|
|
}
|
|
const auto name{arg.substr(0, found)};
|
|
const auto value{arg.substr(found + 1)};
|
|
int32_t height;
|
|
if (!ParseInt32(value, &height) || height < 0 || height >= std::numeric_limits<int>::max()) {
|
|
throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg));
|
|
}
|
|
if (name == "segwit") {
|
|
consensus.SegwitHeight = int{height};
|
|
} else if (name == "bip34") {
|
|
consensus.BIP34Height = int{height};
|
|
} else if (name == "dersig") {
|
|
consensus.BIP66Height = int{height};
|
|
} else if (name == "cltv") {
|
|
consensus.BIP65Height = int{height};
|
|
} else if (name == "csv") {
|
|
consensus.CSVHeight = int{height};
|
|
} else {
|
|
throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg));
|
|
}
|
|
}
|
|
}
|
|
|
|
// This method was added to enable easy mining on regtest networks only.
|
|
// it will be easy to mine blocks in regtest network.
|
|
// This method can only be applied to RegTest networks by design and is called from
|
|
// `CRegTestParams::UpdateActivationParametersFromArgs`
|
|
static void MaybeEnableEasyMining(const ArgsManager& args, Consensus::Params& consensus)
|
|
{
|
|
if (!args.IsArgSet("-easypow")) return;
|
|
|
|
consensus.fEasyPow = true;
|
|
consensus.fPowAllowMinDifficultyBlocks = true;
|
|
|
|
|
|
// Delay new difficulty retargeting algorithm.
|
|
// This will also delay have fixed subsidy as follows:
|
|
// else nSubsidy = 8000 * COIN;
|
|
|
|
// Delay softforks
|
|
consensus.BIP34Height = 1000000;
|
|
consensus.CSVHeight = 1000000;
|
|
}
|
|
|
|
void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
|
|
{
|
|
MaybeEnableEasyMining(args, consensus);
|
|
MaybeUpdateHeights(args, consensus);
|
|
|
|
if (!args.IsArgSet("-vbparams")) return;
|
|
|
|
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
|
|
std::vector<std::string> vDeploymentParams;
|
|
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
|
|
if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
|
|
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
|
|
}
|
|
int64_t nStartTime, nTimeout;
|
|
int min_activation_height = 0;
|
|
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
|
|
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
|
|
}
|
|
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
|
|
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
|
|
}
|
|
if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) {
|
|
throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
|
|
}
|
|
bool found = false;
|
|
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
|
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
|
|
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height);
|
|
found = true;
|
|
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, min_activation_height);
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0]));
|
|
}
|
|
}
|
|
}
|
|
|
|
static std::unique_ptr<const CChainParams> globalChainParams;
|
|
|
|
const CChainParams &Params() {
|
|
assert(globalChainParams);
|
|
return *globalChainParams;
|
|
}
|
|
|
|
std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const std::string& chain)
|
|
{
|
|
if (chain == CBaseChainParams::MAIN) {
|
|
return std::unique_ptr<CChainParams>(new CMainParams());
|
|
} else if (chain == CBaseChainParams::TESTNET) {
|
|
return std::unique_ptr<CChainParams>(new CTestNetParams());
|
|
} else if (chain == CBaseChainParams::SIGNET) {
|
|
return std::unique_ptr<CChainParams>(new SigNetParams(args));
|
|
} else if (chain == CBaseChainParams::REGTEST) {
|
|
return std::unique_ptr<CChainParams>(new CRegTestParams(args));
|
|
}
|
|
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
|
|
}
|
|
|
|
void SelectParams(const std::string& network)
|
|
{
|
|
SelectBaseParams(network);
|
|
globalChainParams = CreateChainParams(gArgs, network);
|
|
}
|