diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -41,8 +41,8 @@ // ParseParameters(argc, argv); - // Check for -testnet or -regtest parameter (Params() calls are only valid - // after this clause) + // Check for -testnet / -regtest / -chain_nol parameter + // (Params() calls are only valid after this clause) try { SelectParams(ChainNameFromCommandLine()); } catch (const std::exception &e) { diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -26,6 +26,42 @@ std::end(ANTI_REPLAY_COMMITMENT)); } +/** + * Import BU's genesis block creation method as a quick way to get to + * a working nolnet definition. + */ +static CBlock BUCreateGenesisBlock(CScript prefix, const std::string &comment, + const CScript &genesisOutputScript, + uint32_t nTime, uint32_t nNonce, + uint32_t nBits, int32_t nVersion, + const CAmount &genesisReward) { + const unsigned char *pComment = (const unsigned char *)comment.c_str(); + std::vector vComment(pComment, pComment + comment.length()); + + CMutableTransaction txNew; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = prefix << vComment; + txNew.vout[0].nValue = genesisReward; + txNew.vout[0].scriptPubKey = genesisOutputScript; + + 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; +} + +/** + * Original genesis block creation method used for networks other than + * nolnet. + */ +// FIXME: Refactor code to use single genesis block creation method. static CBlock CreateGenesisBlock(const char *pszTimestamp, const CScript &genesisOutputScript, uint32_t nTime, uint32_t nNonce, @@ -367,6 +403,114 @@ static CTestNetParams testNetParams; /** + * Nolnet (rebooted June 2017) + */ +class CNolNetParams : public CChainParams { +public: + CNolNetParams() { + strNetworkID = "nol"; + + std::vector rawScript( + ParseHex("76a914a123a6fdc265e1bbcf1123458891bd7af1a1b5d988ac")); + CScript outputScript(rawScript.begin(), rawScript.end()); + genesis = BUCreateGenesisBlock( + CScript() << 0, "Big blocks FTW (for the world)", outputScript, + 1496544271, 2301659837, 0x1d00ffff, 1, 50 * COIN); + consensus.hashGenesisBlock = genesis.GetHash(); + consensus.nSubsidyHalvingInterval = 210000; + consensus.BIP34Height = 0; + consensus.BIP34Hash = consensus.hashGenesisBlock; + // TODO: BU does not have BIP65Height / BIP66Height + // Setting to 0, but need to verify this is right. + consensus.BIP65Height = 0; + consensus.BIP66Height = 0; + consensus.hfStartTime = HF_START_TIME; + consensus.antiReplayOpReturnSunsetHeight = 530000; + consensus.antiReplayOpReturnCommitment = GetAntiReplayCommitment(); + consensus.powLimit = uint256S( + "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + // two weeks + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; + consensus.nPowTargetSpacing = 10 * 60; + consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowNoRetargeting = false; + // 95% for nolnet as per BU rebooted definition + // FIXME: clarify with BU whether they want to adjust this to + // the usual 75% for testnets, or keep as is. All clients with + // nolnet definitions would need to adjust if it is decided to + // lower the threshold. + consensus.nRuleChangeActivationThreshold = 1916; + // nPowTargetTimespan / nPowTargetSpacing + consensus.nMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; + // January 1, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = + 1199145601; + // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = + 1230767999; + + // Deployment of BIP68, BIP112, and BIP113. + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = + 999999999999ULL; + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + + pchMessageStart[0] = 0xfb; + pchMessageStart[1] = 0xce; + pchMessageStart[2] = 0xc4; + pchMessageStart[3] = 0xe9; + nDefaultPort = 9333; + nPruneAfterHeight = 100000; + + assert(consensus.hashGenesisBlock == + uint256S("0000000057e31bd2066c939a63b7b8623bd0f10d8c001304bdfc1a" + "7902ae6d35")); + assert( + genesis.hashMerkleRoot == + uint256S("0x23e723c7e7b53d6ac8bfee6685f281a17d5be453c3ed6a43d6adbb" + "90f6b3c798")); + + vFixedSeeds.clear(); + vSeeds.clear(); + // nodes with support for servicebits filtering should be at the top + vSeeds.push_back(CDNSSeedData("bitcoinunlimited.info", + "nolnet-seed.bitcoinunlimited.info", + true)); + + // P2PKH addresses begin with B + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1, 25); + // P2SH addresses begin with U + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1, 68); + // WIF format begins with 2B or 2C + base58Prefixes[SECRET_KEY] = std::vector(1, 35); + base58Prefixes[EXT_PUBLIC_KEY] = + boost::assign::list_of(0x42)(0x69)(0x67)(0x20) + .convert_to_container>(); + base58Prefixes[EXT_SECRET_KEY] = + boost::assign::list_of(0x42)(0x6c)(0x6b)(0x73) + .convert_to_container>(); + + vFixedSeeds = std::vector(); + + fMiningRequiresPeers = true; + fDefaultConsistencyChecks = false; + fRequireStandard = false; + fMineBlocksOnDemand = false; + + checkpointData = (CCheckpointData){ + boost::assign::map_list_of( + 0, uint256S("00000000000000000000000000000000000000000000000000" + "00000000000000")), + }; + } +}; +static CNolNetParams nolNetParams; + +/** * Regression test */ class CRegTestParams : public CChainParams { @@ -476,6 +620,8 @@ return mainParams; else if (chain == CBaseChainParams::TESTNET) return testNetParams; + else if (chain == CBaseChainParams::NOLNET) + return nolNetParams; else if (chain == CBaseChainParams::REGTEST) return regTestParams; else diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -18,6 +18,7 @@ /** BIP70 chain name strings (main, test or regtest) */ static const std::string MAIN; static const std::string TESTNET; + static const std::string NOLNET; static const std::string REGTEST; const std::string &DataDir() const { return strDataDir; } @@ -48,7 +49,8 @@ void SelectBaseParams(const std::string &chain); /** - * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name. + * Looks for -regtest/-testnet/-chain_nol and returns the appropriate BIP70 + * chain name. * @return CBaseChainParams::MAX_NETWORK_TYPES if an invalid combination is * given. CBaseChainParams::MAIN by default. */ diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -12,11 +12,13 @@ const std::string CBaseChainParams::MAIN = "main"; const std::string CBaseChainParams::TESTNET = "test"; +const std::string CBaseChainParams::NOLNET = "nolnet"; const std::string CBaseChainParams::REGTEST = "regtest"; void AppendParamsHelpMessages(std::string &strUsage, bool debugHelp) { strUsage += HelpMessageGroup(_("Chain selection options:")); strUsage += HelpMessageOpt("-testnet", _("Use the test chain")); + strUsage += HelpMessageOpt("-chain_nol", _("Use the nolnet test chain")); if (debugHelp) { strUsage += HelpMessageOpt( "-regtest", "Enter regression test mode, which uses a special " @@ -47,6 +49,18 @@ }; static CBaseTestNetParams testNetParams; +/** + * Nolnet + */ +class CBaseNolNetParams : public CBaseChainParams { +public: + CBaseNolNetParams() { + nRPCPort = 9332; + strDataDir = "nol"; + } +}; +static CBaseNolNetParams nolNetParams; + /* * Regression test */ @@ -71,6 +85,8 @@ return mainParams; else if (chain == CBaseChainParams::TESTNET) return testNetParams; + else if (chain == CBaseChainParams::NOLNET) + return nolNetParams; else if (chain == CBaseChainParams::REGTEST) return regTestParams; else @@ -85,12 +101,14 @@ std::string ChainNameFromCommandLine() { bool fRegTest = GetBoolArg("-regtest", false); bool fTestNet = GetBoolArg("-testnet", false); + bool fNolNet = GetBoolArg("-chain_nol", false); - if (fTestNet && fRegTest) + if (fRegTest && (fTestNet || fNolNet)) throw std::runtime_error( - "Invalid combination of -regtest and -testnet."); + "Invalid combination of -regtest and other testnet."); if (fRegTest) return CBaseChainParams::REGTEST; if (fTestNet) return CBaseChainParams::TESTNET; + if (fNolNet) return CBaseChainParams::NOLNET; return CBaseChainParams::MAIN; } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -625,8 +625,8 @@ // network-specific settings. // - Needs to be done before createOptionsModel. - // Check for -testnet or -regtest parameter (Params() calls are only valid - // after this clause) + // Check for -testnet / -regtest / -chain_nol parameter + // (Params() calls are only valid after this clause) try { SelectParams(ChainNameFromCommandLine()); } catch (std::exception &e) { diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -52,5 +52,6 @@ #define QAPP_ORG_DOMAIN "bitcoin.org" #define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt" #define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet" +#define QAPP_APP_NAME_NOLNET "Bitcoin-Qt-nolnet" #endif // BITCOIN_QT_GUICONSTANTS_H diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -17,6 +17,8 @@ } network_styles[] = {{"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""}, {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")}, + {"nol", QAPP_APP_NAME_NOLNET, 70, 30, + QT_TRANSLATE_NOOP("SplashScreen", "[nolimit]")}, {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"}}; static const unsigned network_styles_count = sizeof(network_styles) / sizeof(*network_styles); diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -618,7 +618,8 @@ return false; } - // Rather not work on nonstandard transactions (unless -testnet/-regtest) + // Rather not work on nonstandard transactions + // (unless -testnet/-regtest/-chain_nol) std::string reason; if (fRequireStandard && !IsStandardTx(tx, reason)) { return state.DoS(0, false, REJECT_NONSTANDARD, reason);