diff --git a/src/Makefile.am b/src/Makefile.am index 9a071b0031..1451953f3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -146,6 +146,9 @@ BITCOIN_CORE_H = \ dbwrapper.h \ limitedmap.h \ logging.h \ + masternodes/masternodes.h \ + masternodes/mn_checks.h \ + masternodes/mn_txdb.h \ memusage.h \ merkleblock.h \ miner.h \ @@ -276,6 +279,10 @@ libbitcoin_server_a_SOURCES = \ interfaces/node.cpp \ init.cpp \ dbwrapper.cpp \ + masternodes/masternodes.cpp \ + masternodes/mn_checks.cpp \ + masternodes/mn_txdb.cpp \ + masternodes/mn_rpc.cpp \ miner.cpp \ net.cpp \ net_processing.cpp \ diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index e421b377a0..e369a4614d 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -49,6 +49,7 @@ nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES) bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bench_bench_bitcoin_LDADD = \ + $(LIBBITCOIN_MN) \ $(LIBBITCOIN_SERVER) \ $(LIBBITCOIN_WALLET) \ $(LIBBITCOIN_SERVER) \ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9b8f17a23d..b98b0c6c09 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include #include @@ -17,7 +19,43 @@ #include #include -static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) + +std::vector CChainParams::CreateGenesisMasternodes() const +{ +// CChainParamsDummy dummy(*this); + + + std::vector mnTxs; + for (auto const & addrs : vMasternodes) + { + CMutableTransaction txNew; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(2); + txNew.vin[0].scriptSig = CScript(); // << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + + CTxDestination operatorDest = DecodeDestination(addrs.operatorAddress, *this); + assert(operatorDest.which() == 1 || operatorDest.which() == 4); + CTxDestination ownerDest = DecodeDestination(addrs.ownerAddress, *this); + assert(ownerDest.which() == 1 || ownerDest.which() == 4); + + CKeyID operatorAuthKey = operatorDest.which() == 1 ? CKeyID(*boost::get(&operatorDest)) : CKeyID(*boost::get(&operatorDest)) ; + CDataStream metadata(MnTxMarker, SER_NETWORK, PROTOCOL_VERSION); + metadata << static_cast(MasternodesTxType::CreateMasternode) + << static_cast(operatorDest.which()) << operatorAuthKey; + + CScript scriptMeta; + scriptMeta << OP_RETURN << ToByteVector(metadata); + + txNew.vout[0] = CTxOut(consensus.mn.creationFee, scriptMeta); + txNew.vout[1] = CTxOut(consensus.mn.collateralAmount, GetScriptForDestination(ownerDest)); + + mnTxs.push_back(MakeTransactionRef(std::move(txNew))); + } + return mnTxs; +} + +static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward, std::vector const & extraTxs) { CMutableTransaction txNew; txNew.nVersion = 1; @@ -35,6 +73,12 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi genesis.stakeModifier = uint256S("0"); genesis.mintedBlocks = 0; genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); + + for (auto tx : extraTxs) + { + genesis.vtx.push_back(tx); + } + genesis.hashPrevBlock.SetNull(); genesis.hashMerkleRoot = BlockMerkleRoot(genesis); return genesis; @@ -51,11 +95,11 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) * vMerkleTree: 4a5e1e */ -static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward, std::vector const & extraTxs) { 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, nBits, nVersion, genesisReward); + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nBits, nVersion, genesisReward, extraTxs); } /** @@ -96,6 +140,13 @@ class CMainParams : public CChainParams { // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x0000000000000000000f1c54590ee18d15ec70e68c8cd4cfbadb1b4f11697eee"); //563378 + // Masternodes' params + consensus.mn.activationDelay = 1500; + consensus.mn.collateralUnlockDelay = 300; + consensus.mn.creationFee = 1 * COIN; + consensus.mn.collateralAmount = 100 * COIN; + consensus.mn.historyFrame = 300; + /** * 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 @@ -110,8 +161,15 @@ class CMainParams : public CChainParams { m_assumed_blockchain_size = 240; m_assumed_chain_state_size = 3; - genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); + 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 = "df"; + + genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN, CreateGenesisMasternodes()); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); assert(genesis.hashMerkleRoot == uint256S("0x800c7581a09c96d98bdad848db8fc027e8869d28d890ca21f6c25124baf53afe")); @@ -130,14 +188,6 @@ class CMainParams : public CChainParams { // 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 = "df"; - vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); fDefaultConsistencyChecks = false; @@ -209,6 +259,13 @@ class CTestNetParams : public CChainParams { // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x0000000000000037a8cd3e06cd5edbfe9dd1dbcc5dacab279376ef7cfc2b4c75"); //1354312 + // Masternodes' params + consensus.mn.activationDelay = 10; + consensus.mn.collateralUnlockDelay = 10; + consensus.mn.creationFee = 1 * COIN; + consensus.mn.collateralAmount = 10 * COIN; + consensus.mn.historyFrame = 300; + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -218,7 +275,15 @@ class CTestNetParams : public CChainParams { m_assumed_blockchain_size = 30; m_assumed_chain_state_size = 2; - genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); + 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 = "tf"; + + genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN, CreateGenesisMasternodes()); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); @@ -232,14 +297,6 @@ class CTestNetParams : public CChainParams { // 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 = "tf"; - vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); fDefaultConsistencyChecks = false; @@ -299,6 +356,13 @@ class CRegTestParams : public CChainParams { // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x00"); + // Masternodes' params + consensus.mn.activationDelay = 10; + consensus.mn.collateralUnlockDelay = 10; + consensus.mn.creationFee = 1 * COIN; + consensus.mn.collateralAmount = 10 * COIN; + consensus.mn.historyFrame = 300; + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; @@ -310,11 +374,24 @@ class CRegTestParams : public CChainParams { UpdateActivationParametersFromArgs(args); - genesis = CreateGenesisBlock(1569396815, 0x1e0fffff, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); + base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); + base58Prefixes[SECRET_KEY] = std::vector(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - assert(consensus.hashGenesisBlock == uint256S("0xc0f410a59e9aa22afd67ee4671d41c2e3135c0efc589446e4b393cc534d178ac")); - assert(genesis.hashMerkleRoot == uint256S("0x800c7581a09c96d98bdad848db8fc027e8869d28d890ca21f6c25124baf53afe")); + bech32_hrp = "bcrt"; + + // owner base58, operator base58 + vMasternodes.push_back({"mwsZw8nF7pKxWH8eoKL9tPxTpaFkz7QeLU", "mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy"}); + vMasternodes.push_back({"msER9bmJjyEemRpQoS8YYVL21VyZZrSgQ7", "mps7BdmwEF2vQ9DREDyNPibqsuSRZ8LuwQ"}); + vMasternodes.push_back({"bcrt1qyrfrpadwgw7p5eh3e9h3jmu4kwlz4prx73cqny", "bcrt1qmfvw3dp3u6fdvqkdc0y3lr0e596le9cf22vtsv"}); + vMasternodes.push_back({"bcrt1qyeuu9rvq8a67j86pzvh5897afdmdjpyankp4mu", "bcrt1qurwyhta75n2g75u2u5nds9p6w9v62y8wr40d2r"}); + + genesis = CreateGenesisBlock(1296688602, 0x207fffff, 1, 50 * COIN, CreateGenesisMasternodes()); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x000006772a3244d0a5a4911a5cb1d7e910e175f4e4b77c755018459122fa7a89")); + assert(genesis.hashMerkleRoot == uint256S("0x2faeba8cd467cb0df14c48d30b57736f1ed3275790401d127a03d55037df7b5c")); vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. @@ -325,7 +402,7 @@ class CRegTestParams : public CChainParams { checkpointData = { { - {0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")}, + {0, uint256S("0x000006772a3244d0a5a4911a5cb1d7e910e175f4e4b77c755018459122fa7a89")}, } }; @@ -334,14 +411,6 @@ class CRegTestParams : public CChainParams { 0, 0 }; - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,239); - base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; - base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - - bech32_hrp = "bcrt"; } /** diff --git a/src/chainparams.h b/src/chainparams.h index 90e94c6102..9c6743b420 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -104,6 +104,14 @@ class CChainParams bool m_is_test_chain; CCheckpointData checkpointData; ChainTxData chainTxData; + + struct MasternodeKeys + { + std::string ownerAddress; + std::string operatorAddress; + }; + std::vector vMasternodes; + std::vector CreateGenesisMasternodes() const; }; /** diff --git a/src/consensus/params.h b/src/consensus/params.h index b969d557ef..a9dee5ccb6 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_CONSENSUS_PARAMS_H #define BITCOIN_CONSENSUS_PARAMS_H +#include #include #include #include @@ -91,6 +92,15 @@ struct Params { uint256 nMinimumChainWork; uint256 defaultAssumeValid; + + struct MnParams { + CAmount creationFee; + CAmount collateralAmount; + int activationDelay; + int collateralUnlockDelay; + int historyFrame; + }; + MnParams mn; }; } // namespace Consensus diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 4b93cae848..3537f791e7 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include