diff --git a/src/Makefile.am b/src/Makefile.am index 8fc7f61d4b7..9a071b0031d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -167,7 +167,8 @@ BITCOIN_CORE_H = \ policy/policy.h \ policy/rbf.h \ policy/settings.h \ - pow.h \ + pos.h \ + pos_kernel.h \ protocol.h \ psbt.h \ random.h \ @@ -286,7 +287,8 @@ libbitcoin_server_a_SOURCES = \ policy/fees.cpp \ policy/rbf.cpp \ policy/settings.cpp \ - pow.cpp \ + pos.cpp \ + pos_kernel.cpp \ rest.cpp \ rpc/blockchain.cpp \ rpc/mining.cpp \ diff --git a/src/amount.h b/src/amount.h index 47968e80b17..c00475b6fd6 100644 --- a/src/amount.h +++ b/src/amount.h @@ -16,7 +16,7 @@ static const CAmount COIN = 100000000; /** No amount larger than this (in satoshi) is valid. * * Note that this constant is *not* the total money supply, which in Bitcoin - * currently happens to be less than 21,000,000 BTC for various reasons, but + * currently happens to be less than 21,000,000 DFI for various reasons, but * rather a sanity check. As this sanity check is used by consensus-critical * validation code, the exact value of the MAX_MONEY constant is consensus * critical; in unusual circumstances like a(nother) overflow bug that allowed diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp index 2440341287f..d5d45e42a54 100644 --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -28,8 +28,8 @@ static void DuplicateInputs(benchmark::State& state) LOCK(cs_main); CBlockIndex* pindexPrev = ::ChainActive().Tip(); assert(pindexPrev != nullptr); - block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); - block.nNonce = 0; + block.nBits = pos::GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus().pos); + // block.nNonce = 0; auto nHeight = pindexPrev->nHeight + 1; // Make a coinbase TX diff --git a/src/chain.cpp b/src/chain.cpp index 5520d8149a1..40772206606 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -144,7 +144,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr r = from.nChainWork - to.nChainWork; sign = -1; } - r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); + r = r * arith_uint256(params.pos.nTargetSpacing) / GetBlockProof(tip); if (r.bits() > 63) { return sign * std::numeric_limits::max(); } diff --git a/src/chain.h b/src/chain.h index 1b67ebbe41b..bef75e6b864 100644 --- a/src/chain.h +++ b/src/chain.h @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #include +#include /** * Maximum amount of time that a block timestamp is allowed to exceed the @@ -180,7 +182,13 @@ class CBlockIndex uint256 hashMerkleRoot; uint32_t nTime; uint32_t nBits; - uint32_t nNonce; + + // proof-of-stake specific fields + uint64_t height; + uint64_t mintedBlocks; + uint256 stakeModifier; // hash modifier for proof-of-stake + std::vector sig; + CKeyID minter; // memory only //! (memory only) Sequential id assigned to distinguish order in which blocks are received. int32_t nSequenceId; @@ -208,7 +216,10 @@ class CBlockIndex hashMerkleRoot = uint256(); nTime = 0; nBits = 0; - nNonce = 0; + stakeModifier = uint256{}; + height = 0; + mintedBlocks = 0; + sig = {}; } CBlockIndex() @@ -224,7 +235,10 @@ class CBlockIndex hashMerkleRoot = block.hashMerkleRoot; nTime = block.nTime; nBits = block.nBits; - nNonce = block.nNonce; + height = block.height; + mintedBlocks = block.mintedBlocks; + stakeModifier = block.stakeModifier; + sig = block.sig; } FlatFilePos GetBlockPos() const { @@ -254,7 +268,10 @@ class CBlockIndex block.hashMerkleRoot = hashMerkleRoot; block.nTime = nTime; block.nBits = nBits; - block.nNonce = nNonce; + block.stakeModifier = stakeModifier; + block.height = height; + block.mintedBlocks = mintedBlocks; + block.sig = sig; return block; } @@ -300,8 +317,9 @@ class CBlockIndex std::string ToString() const { - return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", + return strprintf("CBlockIndex(pprev=%p, nHeight=%d, stakeModifier=(%s), merkle=%s, hashBlock=%s)", pprev, nHeight, + stakeModifier.ToString(), hashMerkleRoot.ToString(), GetBlockHash().ToString()); } @@ -382,7 +400,10 @@ class CDiskBlockIndex : public CBlockIndex READWRITE(hashMerkleRoot); READWRITE(nTime); READWRITE(nBits); - READWRITE(nNonce); + READWRITE(stakeModifier); + READWRITE(height); + READWRITE(mintedBlocks); + READWRITE(sig); } uint256 GetBlockHash() const @@ -393,7 +414,11 @@ class CDiskBlockIndex : public CBlockIndex block.hashMerkleRoot = hashMerkleRoot; block.nTime = nTime; block.nBits = nBits; - block.nNonce = nNonce; + block.stakeModifier = stakeModifier; + block.height = height; + block.mintedBlocks = mintedBlocks; + block.sig = sig; + return block.GetHash(); } diff --git a/src/chainparams.cpp b/src/chainparams.cpp index ad766471dc1..9b8f17a23d6 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -17,21 +17,23 @@ #include #include -static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, 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((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 0 << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); 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.nTime = nTime; + genesis.nBits = nBits; + genesis.nVersion = nVersion; + genesis.height = 0; + genesis.stakeModifier = uint256S("0"); + genesis.mintedBlocks = 0; genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = BlockMerkleRoot(genesis); @@ -43,17 +45,17 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi * 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) + * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, 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) +static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) { const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; - return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nBits, nVersion, genesisReward); } /** @@ -65,25 +67,31 @@ class CMainParams : public CChainParams { strNetworkID = "main"; consensus.nSubsidyHalvingInterval = 210000; consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22"); - consensus.BIP34Height = 227931; - consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); - consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 - consensus.CSVHeight = 419328; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5 - consensus.SegwitHeight = 481824; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893 - consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = false; - consensus.fPowNoRetargeting = false; + consensus.BIP34Height = 0; + consensus.BIP34Hash = uint256(); + consensus.BIP65Height = 0; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 + consensus.BIP66Height = 0; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 + + consensus.pos.diffLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.pos.nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.pos.nTargetSpacing = 10 * 60; // 10 minutes + consensus.pos.fAllowMinDifficultyBlocks = false; // only for regtest + consensus.pos.fNoRetargeting = false; // only for regtest + + consensus.pos.coinstakeMaturity = 100; + + consensus.pos.allowMintingWithoutPeers = false; // don't mint if no peers connected + + consensus.CSVHeight = 1; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5 + consensus.SegwitHeight = 0; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893 consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 - consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing + consensus.nMinerConfirmationWindow = 2016; // nTargetTimespan / nTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000051dc8b82f450202ecb3d471"); + consensus.nMinimumChainWork = uint256S("0x00"); // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x0000000000000000000f1c54590ee18d15ec70e68c8cd4cfbadb1b4f11697eee"); //563378 @@ -97,37 +105,38 @@ class CMainParams : public CChainParams { pchMessageStart[1] = 0xbe; pchMessageStart[2] = 0xb4; pchMessageStart[3] = 0xd9; - nDefaultPort = 8333; + nDefaultPort = 8323; nPruneAfterHeight = 100000; m_assumed_blockchain_size = 240; m_assumed_chain_state_size = 3; - genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); + consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); + assert(genesis.hashMerkleRoot == uint256S("0x800c7581a09c96d98bdad848db8fc027e8869d28d890ca21f6c25124baf53afe")); // Note that of those which support the service bits prefix, most only support a subset of // possible options. // This is fine at runtime as we'll fall back to using them as a oneshot if they don't support the // service bits we want, but we should get them updated to support all service bits wanted by any // release ASAP to avoid it where possible. - vSeeds.emplace_back("seed.bitcoin.sipa.be"); // Pieter Wuille, only supports x1, x5, x9, and xd - vSeeds.emplace_back("dnsseed.bluematt.me"); // Matt Corallo, only supports x9 - vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org"); // Luke Dashjr - vSeeds.emplace_back("seed.bitcoinstats.com"); // Christian Decker, supports x1 - xf - vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch"); // Jonas Schnelli, only supports x1, x5, x9, and xd - vSeeds.emplace_back("seed.btc.petertodd.org"); // Peter Todd, only supports x1, x5, x9, and xd - vSeeds.emplace_back("seed.bitcoin.sprovoost.nl"); // Sjors Provoost - vSeeds.emplace_back("dnsseed.emzy.de"); // Stephan Oeste - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); - base58Prefixes[SECRET_KEY] = std::vector(1,128); +// vSeeds.emplace_back("seed.bitcoin.sipa.be"); // Pieter Wuille, only supports x1, x5, x9, and xd +// vSeeds.emplace_back("dnsseed.bluematt.me"); // Matt Corallo, only supports x9 +// vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org"); // Luke Dashjr +// vSeeds.emplace_back("seed.bitcoinstats.com"); // Christian Decker, supports x1 - xf +// vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch"); // Jonas Schnelli, only supports x1, x5, x9, and xd +// vSeeds.emplace_back("seed.btc.petertodd.org"); // Peter Todd, only supports x1, x5, x9, and xd +// vSeeds.emplace_back("seed.bitcoin.sprovoost.nl"); // Sjors Provoost +// vSeeds.emplace_back("dnsseed.emzy.de"); // Stephan Oeste + + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,18); // '8' (0('1') for bitcoin) + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,90); // 'd' (5('3') for bitcoin) + base58Prefixes[SECRET_KEY] = std::vector(1,128); // (128 ('5', 'K' or 'L') for bitcoin) base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; - bech32_hrp = "bc"; + bech32_hrp = "df"; vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); @@ -137,27 +146,27 @@ class CMainParams : public CChainParams { checkpointData = { { - { 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, - { 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, - { 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, - {105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, - {134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, - {168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, - {193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, - {210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, - {216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, - {225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, - {250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, - {279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, - {295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")}, +// { 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, +// { 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, +// { 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, +// {105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, +// {134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, +// {168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, +// {193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, +// {210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, +// {216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, +// {225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, +// {250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, +// {279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, +// {295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")}, } }; chainTxData = ChainTxData{ // Data from rpc: getchaintxstats 4096 0000000000000000000f1c54590ee18d15ec70e68c8cd4cfbadb1b4f11697eee - /* nTime */ 1550374134, - /* nTxCount */ 383732546, - /* dTxRate */ 3.685496590998308 + /* nTime */ 1569396815, + /* nTxCount */ 0, + /* dTxRate */ 0 }; } }; @@ -171,25 +180,31 @@ class CTestNetParams : public CChainParams { strNetworkID = "test"; consensus.nSubsidyHalvingInterval = 210000; consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105"); - consensus.BIP34Height = 21111; - consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); - consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 - consensus.CSVHeight = 770112; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb - consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca - consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; - consensus.fPowNoRetargeting = false; + consensus.BIP34Height = 0; + consensus.BIP34Hash = uint256(); + consensus.BIP65Height = 0; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 + consensus.BIP66Height = 0; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 + + consensus.pos.diffLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.pos.nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.pos.nTargetSpacing = 10 * 60; // 10 minutes + consensus.pos.fAllowMinDifficultyBlocks = false; // only for regtest + consensus.pos.fNoRetargeting = false; // only for regtest + + consensus.pos.coinstakeMaturity = 100; + + consensus.pos.allowMintingWithoutPeers = true; + + consensus.CSVHeight = 1; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb + consensus.SegwitHeight = 0; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains - consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing + consensus.nMinerConfirmationWindow = 2016; // nTargetTimespan / nTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 // The best chain should have at least this much work. - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000007dbe94253893cbd463"); + consensus.nMinimumChainWork = uint256S("0x00"); // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75"); //1354312 @@ -198,31 +213,32 @@ class CTestNetParams : public CChainParams { pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; pchMessageStart[3] = 0x07; - nDefaultPort = 18333; + nDefaultPort = 18323; nPruneAfterHeight = 1000; m_assumed_blockchain_size = 30; m_assumed_chain_state_size = 2; - genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + + assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); + assert(genesis.hashMerkleRoot == uint256S("0x800c7581a09c96d98bdad848db8fc027e8869d28d890ca21f6c25124baf53afe")); vFixedSeeds.clear(); vSeeds.clear(); // nodes with support for servicebits filtering should be at the top - vSeeds.emplace_back("testnet-seed.bitcoin.jonasschnelli.ch"); - vSeeds.emplace_back("seed.tbtc.petertodd.org"); - vSeeds.emplace_back("seed.testnet.bitcoin.sprovoost.nl"); - vSeeds.emplace_back("testnet-seed.bluematt.me"); // Just a static list of stable node(s), only supports x9 - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,239); +// vSeeds.emplace_back("testnet-seed.bitcoin.jonasschnelli.ch"); +// vSeeds.emplace_back("seed.tbtc.petertodd.org"); +// vSeeds.emplace_back("seed.testnet.bitcoin.sprovoost.nl"); +// vSeeds.emplace_back("testnet-seed.bluematt.me"); // Just a static list of stable node(s), only supports x9 + + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,15); // '7' (111 ('m' or 'n') for bitcoin) + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,128); // 't' (196 ('2') for bitcoin) + base58Prefixes[SECRET_KEY] = std::vector(1,239); // (239 ('9' or 'c') for bitcoin) base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - bech32_hrp = "tb"; + bech32_hrp = "tf"; vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); @@ -233,15 +249,15 @@ class CTestNetParams : public CChainParams { checkpointData = { { - {546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, +// {546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, } }; chainTxData = ChainTxData{ // Data from rpc: getchaintxstats 4096 0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75 - /* nTime */ 1531929919, - /* nTxCount */ 19438708, - /* dTxRate */ 0.626 + /* nTime */ 1569396815, + /* nTxCount */ 0, + /* dTxRate */ 0 }; } }; @@ -255,17 +271,22 @@ class CRegTestParams : public CChainParams { strNetworkID = "regtest"; consensus.nSubsidyHalvingInterval = 150; consensus.BIP16Exception = uint256(); - consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests) + consensus.BIP34Height = 0; // 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.BIP65Height = 0; // BIP65 activated on regtest (Used in functional tests) + consensus.BIP66Height = 0; // BIP66 activated on regtest (Used in functional tests) + consensus.pos.diffLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.pos.nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.pos.nTargetSpacing = 10 * 60; // 10 minutes + consensus.pos.fAllowMinDifficultyBlocks = false; // only for regtest + consensus.pos.fNoRetargeting = false; // only for regtest + + consensus.pos.coinstakeMaturity = 100; + + consensus.pos.allowMintingWithoutPeers = true; // don't mint if no peers connected + + consensus.CSVHeight = 1; // CSV activated on regtest (Used in rpc activation tests) consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden - consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; - consensus.fPowNoRetargeting = true; consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; @@ -282,17 +303,18 @@ class CRegTestParams : public CChainParams { pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nDefaultPort = 18444; + nDefaultPort = 18424; nPruneAfterHeight = 1000; m_assumed_blockchain_size = 0; m_assumed_chain_state_size = 0; UpdateActivationParametersFromArgs(args); - genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + + assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); + assert(genesis.hashMerkleRoot == uint256S("0x800c7581a09c96d98bdad848db8fc027e8869d28d890ca21f6c25124baf53afe")); vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. diff --git a/src/chainparams.h b/src/chainparams.h index 8f1d27e03cd..90e94c6102f 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -74,7 +74,7 @@ class CChainParams /** Minimum free space (in GB) needed for data directory when pruned; Does not include prune target*/ uint64_t AssumedChainStateSize() const { return m_assumed_chain_state_size; } /** Whether it is possible to mine blocks on demand (no retargeting) */ - bool MineBlocksOnDemand() const { return consensus.fPowNoRetargeting; } + bool MineBlocksOnDemand() const { return consensus.pos.fNoRetargeting; } /** Return the BIP70 network string (main, test or regtest) */ std::string NetworkIDString() const { return strNetworkID; } /** Return the list of hostnames to look up for DNS seeds */ diff --git a/src/consensus/params.h b/src/consensus/params.h index 8263b0fef4a..b969d557efa 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace Consensus { @@ -62,21 +63,32 @@ struct Params { * Note that segwit v0 script rules are enforced on all blocks except the * BIP 16 exception blocks. */ int SegwitHeight; + + /** Proof of stake parameters */ + struct PoS { + uint256 diffLimit; + int64_t nTargetTimespan; + int64_t nTargetSpacing; + bool fAllowMinDifficultyBlocks; + bool fNoRetargeting; + + int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; } + + arith_uint256 interestAtoms = arith_uint256{10000000000000000ull}; + bool allowMintingWithoutPeers; + int coinstakeMaturity = 500; + }; + PoS pos; + /** * Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period, - * (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. + * (nTargetTimespan / nTargetSpacing) which is also used for BIP9 deployments. * Examples: 1916 for 95%, 1512 for testchains. */ uint32_t nRuleChangeActivationThreshold; uint32_t nMinerConfirmationWindow; BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]; - /** Proof of work parameters */ - uint256 powLimit; - bool fPowAllowMinDifficultyBlocks; - bool fPowNoRetargeting; - int64_t nPowTargetSpacing; - int64_t nPowTargetTimespan; - int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } + uint256 nMinimumChainWork; uint256 defaultAssumeValid; }; diff --git a/src/init.cpp b/src/init.cpp index 042335b8e74..23c47880282 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include @@ -1823,5 +1825,55 @@ bool AppInitMain(InitInterfaces& interfaces) g_banman->DumpBanlist(); }, DUMP_BANS_INTERVAL * 1000); + // ********************************************************* Step 14: start minter thread + pos::ThreadStaker::Args stakerParams{}; + { + CKey key; + std::vector> wallets = GetWallets(); + if (wallets.size() == 0) { + LogPrintf("Warning! wallets not found"); + return true; + } + std::shared_ptr defaultWallet = wallets[0]; + + CTxDestination destination; + + std::string minterAddress = gArgs.GetArg("-minterAddress", ""); + if (minterAddress != "") { + destination = DecodeDestination(minterAddress); + if (!IsValidDestination(destination)) { + LogPrintf("Error: coinstake destination is invalid"); + return false; + } + } else { + std::string strErr; + if(!defaultWallet->GetNewDestination(OutputType::LEGACY, "", destination, strErr)) { + LogPrintf("%s\n", strErr); + return false; + } + } + + CScript coinbaseScript = GetScriptForDestination(destination); + CKey minterKey; + if (!defaultWallet->GetKey(CKeyID(*boost::get(&destination)), minterKey)) { + LogPrintf("Error: private key not found"); + return false; + } + + stakerParams.coinbaseScript = coinbaseScript; + stakerParams.minterKey = minterKey; + } + + // Mint proof-of-stake blocks in background + threadGroup.create_thread([=]() { + TraceThread("CoinStaker", [=]() { + // Fill Staker Args + + // Run ThreadStaker + pos::ThreadStaker threadStaker{}; + threadStaker(stakerParams, chainparams); + }); + }); + return true; } diff --git a/src/logging.h b/src/logging.h index 75cd5353c0e..42e230853ac 100644 --- a/src/logging.h +++ b/src/logging.h @@ -54,6 +54,7 @@ namespace BCLog { COINDB = (1 << 18), QT = (1 << 19), LEVELDB = (1 << 20), + STAKING = (1 << 21), ALL = ~(uint32_t)0, }; diff --git a/src/miner.cpp b/src/miner.cpp index 015645c9c66..9579f7b7f7f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -13,9 +13,11 @@ #include #include #include +#include #include #include -#include +#include +#include #include #include