Commit 7915eec7 authored by Ashot's avatar Ashot

Merged mn_pos branch

parents 0af414de 5184c558
Pipeline #866 passed with stage
in 90 minutes and 25 seconds
......@@ -142,6 +142,10 @@ BITCOIN_CORE_H = \
masternode-sync.h \
masternodeman.h \
masternodeconfig.h \
mn-pos/kernel.h \
mn-pos/stakepointer.h \
mn-pos/stakeminer.h \
mn-pos/stakevalidation.h \
nodeconfig.h \
systemnode.h \
systemnode-payments.h \
......@@ -201,6 +205,10 @@ libbitcoin_server_a_SOURCES = \
main.cpp \
merkleblock.cpp \
miner.cpp \
mn-pos/kernel.cpp \
mn-pos/stakeminer.cpp \
mn-pos/stakepointer.cpp \
mn-pos/stakevalidation.cpp \
net.cpp \
noui.cpp \
pow.cpp \
......@@ -239,6 +247,7 @@ libbitcoin_wallet_a_SOURCES = \
masternode-payments.cpp \
masternode-sync.cpp \
masternodeconfig.cpp \
mn-pos/stakeminer.cpp \
nodeconfig.cpp \
masternodeman.cpp \
systemnode-sync.cpp \
......
......@@ -69,6 +69,7 @@ BITCOIN_TESTS =\
test/sighash_tests.cpp \
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/staking_tests.cpp \
test/test_crown.cpp \
test/timedata_tests.cpp \
test/transaction_tests.cpp \
......
......@@ -31,7 +31,19 @@ void CActiveMasternode::ManageStatus()
pmn = mnodeman.Find(pubKeyMasternode);
if(pmn != NULL) {
pmn->Check();
if(pmn->IsEnabled() && pmn->protocolVersion == PROTOCOL_VERSION) EnableHotColdMasterNode(pmn->vin, pmn->addr);
if (pmn->IsEnabled() && pmn->protocolVersion == PROTOCOL_VERSION) {
EnableHotColdMasterNode(pmn->vin, pmn->addr);
if (!pmn->vchSignover.empty()) {
if (pmn->pubkey.Verify(pubKeyMasternode.GetHash(), pmn->vchSignover)) {
LogPrintf("%s: Verified pubkey2 signover for staking\n", __func__);
activeMasternode.vchSigSignover = pmn->vchSignover;
} else {
LogPrintf("%s: Failed to verify pubkey on signover!\n", __func__);
}
} else {
LogPrintf("%s: NOT SIGNOVER!\n", __func__);
}
}
}
}
......@@ -111,7 +123,8 @@ void CActiveMasternode::ManageStatus()
}
CMasternodeBroadcast mnb;
if(!CMasternodeBroadcast::Create(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb)) {
bool fSignOver = true;
if(!CMasternodeBroadcast::Create(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, fSignOver, errorMessage, mnb)) {
notCapableReason = "Error on CreateBroadcast: " + errorMessage;
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
return;
......
......@@ -34,6 +34,9 @@ public:
// Keys for the main Masternode
CPubKey pubKeyMasternode;
// Signature signing over staking priviledge
std::vector<unsigned char> vchSigSignover;
// Initialized while registering Masternode
CTxIn vin;
CService service;
......
......@@ -29,11 +29,23 @@ void CActiveSystemnode::ManageStatus()
if(status == ACTIVE_SYSTEMNODE_SYNC_IN_PROCESS) status = ACTIVE_SYSTEMNODE_INITIAL;
if(status == ACTIVE_SYSTEMNODE_INITIAL) {
CSystemnode *pmn;
pmn = snodeman.Find(pubKeySystemnode);
if(pmn != NULL) {
pmn->Check();
if(pmn->IsEnabled() && pmn->protocolVersion == PROTOCOL_VERSION) EnableHotColdSystemNode(pmn->vin, pmn->addr);
CSystemnode *psn;
psn = snodeman.Find(pubKeySystemnode);
if(psn != NULL) {
psn->Check();
if(psn->IsEnabled() && psn->protocolVersion == PROTOCOL_VERSION) {
EnableHotColdSystemNode(psn->vin, psn->addr);
if (!psn->vchSignover.empty()) {
if (psn->pubkey.Verify(pubKeySystemnode.GetHash(), psn->vchSignover)) {
LogPrintf("%s: Verified pubkey2 signover for staking\n", __func__);
activeSystemnode.vchSigSignover = psn->vchSignover;
} else {
LogPrintf("%s: Failed to verify pubkey on signover!\n", __func__);
}
} else {
LogPrintf("%s: NOT SIGNOVER!\n", __func__);
}
}
}
}
......@@ -113,7 +125,8 @@ void CActiveSystemnode::ManageStatus()
}
CSystemnodeBroadcast mnb;
if(!CSystemnodeBroadcast::Create(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keySystemnode, pubKeySystemnode, errorMessage, mnb)) {
bool fSignOver = true;
if(!CSystemnodeBroadcast::Create(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keySystemnode, pubKeySystemnode, fSignOver, errorMessage, mnb)) {
notCapableReason = "Error on CreateBroadcast: " + errorMessage;
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
return;
......
......@@ -39,7 +39,10 @@ public:
// Keys for the main Systemnode
CPubKey pubKeySystemnode;
// Initialized while registering Systemnode
// Signature signing over staking priviledge
std::vector<unsigned char> vchSigSignover;
// Initialized while registering Systemnode
CTxIn vin;
CService service;
......
......@@ -138,6 +138,8 @@ public:
unsigned int nTime;
unsigned int nBits;
unsigned int nNonce;
bool fProofOfStake;
std::pair<uint256, unsigned int> stakeSource;
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
uint32_t nSequenceId;
......@@ -162,6 +164,9 @@ public:
nTime = 0;
nBits = 0;
nNonce = 0;
fProofOfStake = false;
stakeSource.first = uint256();
stakeSource.second = 0;
}
CBlockIndex()
......@@ -169,7 +174,7 @@ public:
SetNull();
}
CBlockIndex(const CBlockHeader& block)
CBlockIndex(const CBlock& block)
{
SetNull();
......@@ -178,6 +183,11 @@ public:
nTime = block.nTime;
nBits = block.nBits;
nNonce = block.nNonce;
fProofOfStake = block.IsProofOfStake();
if (fProofOfStake) {
stakeSource.first = block.stakePointer.txid;
stakeSource.second = block.stakePointer.nPos;
}
}
CDiskBlockPos GetBlockPos() const {
......@@ -271,6 +281,7 @@ public:
//! Efficiently find an ancestor of this block.
CBlockIndex* GetAncestor(int height);
const CBlockIndex* GetAncestor(int height) const;
bool IsProofOfStake() const;
};
/** Used to marshal pointers into hashes for db storage. */
......@@ -311,6 +322,10 @@ public:
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
READWRITE(fProofOfStake);
if (fProofOfStake) {
READWRITE(stakeSource);
}
}
uint256 GetBlockHash() const
......
......@@ -155,14 +155,17 @@ static const Checkpoints::CCheckpointData data = {
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
( 0, uint256S("0x0000000085370d5e122f64f4ab19c68614ff3df78c8d13cb814fd7e69a1dc6da"))
( 0, uint256S("0x00008f72785c0713a31a5457c4169a17088338540410b548f302c92bc17c1bc1"))
( 9820, uint256S("0x000007e98d19383421f4ff13528e364edb19cda8c302df0290b2aef16936d9b2"))
( 9950, uint256S("0x000006ef1474fad5c76c503cd6896f6a09339a2c6fb66c7727566380567b1c7b"))
( 10007, uint256S("0x485e03be7d12c2802e0e49f0410011da36d0070746c48fb9bf347eff550943fa"))
;
static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet,
1412760826, // * UNIX timestamp of last checkpoint block
0, // * total number of transactions between genesis and last checkpoint
1543018925, // * UNIX timestamp of last checkpoint block
10205, // * total number of transactions between genesis and last checkpoint
// (the tx=... number in the SetBestChain debug.log lines)
0 // * estimated number of transactions per day after checkpoint
2000 // * estimated number of transactions per day after checkpoint
};
static Checkpoints::MapCheckpoints mapCheckpointsDevnet =
......@@ -213,7 +216,14 @@ public:
nMinerThreads = 0;
nTargetTimespan = 14 * 24 * 60 * 60; // Crown: 2 weeks
nTargetSpacing = 1 * 60; // Crown: 1 minutes
nMaxTipAge = 6 * 60 * 60;
nMaxTipAge = 6 * 60 * 60;
nAuxpowChainId = 20;
nPoSChainId = 22;
nStakePointerValidityPeriod = 1440; //Stake pointers are valid to stake with for the next 1 day worth of blocks
nMaxReorgDepth = 100;
nKernelModifierOffset = 100; //Number blocks before the stake pointer is the kernel modifier from
nChainStallDuration = 60*60; //Spacing between blocks that will consider the chain as "stalled"
/**
* Build the genesis block. Note that the output of the genesis coinbase cannot
......@@ -334,54 +344,60 @@ public:
nTargetTimespan = 2 * 24 * 60 * 60; // 2 days
nTargetSpacing = 1.5 * 60; // 1.5 minutes
nMaxTipAge = 0x7fffffff;
nBlockPoSStart = 10000;
//! Modify the testnet genesis block so the timestamp is valid for a later start.
genesis.nTime = 1412760826;
genesis.nNonce = 1612467894;
/*if (true && genesis.GetHash() != hashGenesisBlock)
{
printf("Searching for genesis block...\n");
uint256 hashTarget = uint256().SetCompact(genesis.nBits);
uint256 thash;
while (true)
{
thash = genesis.GetHash();
if (thash <= hashTarget)
break;
if ((genesis.nNonce & 0xFFF) == 0)
{
printf("nonce %08X: hash = %s (target = %s)\n", genesis.nNonce, thash.ToString().c_str(), hashTarget.ToString().c_str());
}
++genesis.nNonce;
if (genesis.nNonce == 0)
{
printf("NONCE WRAPPED, incrementing time\n");
++genesis.nTime;
}
}
printf("genesis.nTime = %u \n", genesis.nTime);
printf("genesis.nNonce = %u \n", genesis.nNonce);
printf("genesis.nVersion = %u \n", genesis.nVersion);
//printf("genesis.GetHash = %s\n", genesis.GetHash().ToString().c_str()); //first this, then comment this line out and uncomment the one under.
printf("genesis.hashMerkleRoot = %s \n", genesis.hashMerkleRoot.ToString().c_str()); //improvised. worked for me, to find merkle root/
}*/
genesis.nTime = 1536962431;
genesis.nNonce = 1112529522;
arith_uint256 nCompact = 0;
nCompact = ~nCompact;
nCompact >>= 16;
bnProofOfWorkLimit = nCompact;
genesis.nBits = nCompact.GetCompact();
// if (true && genesis.GetHash() != hashGenesisBlock)
// {
// printf("Searching for genesis block...\n");
// arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
// arith_uint256 thash;
// while (true)
// {
// thash = UintToArith256(genesis.GetHash());
// if (thash <= hashTarget)
// break;
// if ((genesis.nNonce & 0xFFF) == 0)
// {
// printf("nonce %08X: hash = %s (target = %s)\n", genesis.nNonce, thash.ToString().c_str(), hashTarget.ToString().c_str());
// }
// ++genesis.nNonce;
// if (genesis.nNonce == 0)
// {
// printf("NONCE WRAPPED, incrementing time\n");
// ++genesis.nTime;
// }
// }
// printf("genesis.nTime = %u \n", genesis.nTime);
// printf("genesis.nNonce = %u \n", genesis.nNonce);
// printf("genesis.nVersion = %u \n", genesis.nVersion);
// printf("genesis.GetHash = %s\n", genesis.GetHash().ToString().c_str()); //first this, then comment this line out and uncomment the one under.
// printf("genesis.hashMerkleRoot = %s \n", genesis.hashMerkleRoot.ToString().c_str()); //improvised. worked for me, to find merkle root/
// }
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256S("0x0000000085370d5e122f64f4ab19c68614ff3df78c8d13cb814fd7e69a1dc6da"));
assert(hashGenesisBlock == uint256S("0x00008f72785c0713a31a5457c4169a17088338540410b548f302c92bc17c1bc1"));
assert(genesis.hashMerkleRoot == uint256S("0x80ad356118a9ab8db192db66ef77146cc36d958f959251feace550e4ca3d1446"));
vFixedSeeds.clear();
vSeeds.clear();
vSeeds.push_back(CDNSSeedData("fra-testnet-crwdns", "fra-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("blr-testnet-crwdns", "blr-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("sgp-testnet-crwdns", "sgp-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("lon-testnet-crwdns", "lon-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("nyc-testnet-crwdns", "nyc-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("tor-testnet-crwdns", "tor-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("sfo-testnet-crwdns", "sfo-testnet-crwdns.crowndns.info"));
vSeeds.push_back(CDNSSeedData("ams-testnet-crwdns", "ams-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("fra-testnet-crwdns", "fra-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("blr-testnet-crwdns", "blr-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("sgp-testnet-crwdns", "sgp-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("lon-testnet-crwdns", "lon-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("nyc-testnet-crwdns", "nyc-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("tor-testnet-crwdns", "tor-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("sfo-testnet-crwdns", "sfo-testnet-crwdns.crowndns.info"));
// vSeeds.push_back(CDNSSeedData("ams-testnet-crwdns", "ams-testnet-crwdns.crowndns.info"));
// Testnet crown addresses start with 'tCRW'
base58Prefixes[PUBKEY_ADDRESS] = list_of(0x01)(0x7A)(0xCD)(0x67).convert_to_container<std::vector<unsigned char> >();
......@@ -416,6 +432,8 @@ public:
strDevfundAddress = "mr59c3aniaN3qHXej5L8UBsssRZbiUUMnz";
strLegacySignerDummyAddress = "mr59c3aniaN3qHXej5L8UBsssRZbiUUMnz";
nStartMasternodePayments = 1420837558; //Fri, 09 Jan 2015 21:05:58 GMT
nStakePointerValidityPeriod = 3000;
}
const Checkpoints::CCheckpointData& Checkpoints() const
{
......@@ -598,6 +616,7 @@ public:
fDefaultConsistencyChecks = true;
fAllowMinDifficultyBlocks = false;
fMineBlocksOnDemand = true;
nBlockPoSStart = 9999999;
}
const Checkpoints::CCheckpointData& Checkpoints() const
......
......@@ -102,7 +102,13 @@ public:
int64_t StartMasternodePayments() const { return nStartMasternodePayments; }
CBaseChainParams::Network NetworkID() const { return networkID; }
/* Return the auxpow chain ID. */
inline int32_t AuxpowChainId () const { return 20; }
inline int32_t AuxpowChainId () const { return nAuxpowChainId; }
int32_t PoSChainId () const { return nPoSChainId; }
int PoSStartHeight() const { return nBlockPoSStart; }
int ValidStakePointerDuration() const { return nStakePointerValidityPeriod; }
int MaxReorganizationDepth() const { return nMaxReorgDepth; }
int KernelModifierOffset() const { return nKernelModifierOffset; }
int ChainStallDuration() const { return nChainStallDuration; }
/* Return start height of auxpow and the retarget interval change. */
virtual int AuxpowStartHeight() const = 0;
/* Return whether or not to enforce strict chain ID checks. */
......@@ -148,6 +154,13 @@ protected:
std::string strLegacySignerDummyAddress;
std::string strDevfundAddress;
int64_t nStartMasternodePayments;
int32_t nAuxpowChainId;
int32_t nPoSChainId;
int nBlockPoSStart;
int nStakePointerValidityPeriod;
int nMaxReorgDepth;
int nKernelModifierOffset;
int nChainStallDuration;
};
/**
......
......@@ -57,7 +57,7 @@
* version code unspentness vout[4] vout[16] height
*
* - version = 1
* - code = 9 (coinbase, neither vout[0] or vout[1] are unspent,
* - code = 9 (coinbase/coinstake, neither vout[0] or vout[1] are unspent,
* 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow)
* - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
* - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
......@@ -73,8 +73,8 @@
class CCoins
{
public:
//! whether transaction is a coinbase
bool fCoinBase;
//! whether transaction is a coinbase/coinstake
bool fBlockReward;
//! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
std::vector<CTxOut> vout;
......@@ -87,7 +87,7 @@ public:
int nVersion;
void FromTx(const CTransaction &tx, int nHeightIn) {
fCoinBase = tx.IsCoinBase();
fBlockReward = tx.IsCoinBase() || tx.IsCoinStake();
vout = tx.vout;
nHeight = nHeightIn;
nVersion = tx.nVersion;
......@@ -100,14 +100,14 @@ public:
}
void Clear() {
fCoinBase = false;
fBlockReward = false;
std::vector<CTxOut>().swap(vout);
nHeight = 0;
nVersion = 0;
}
//! empty constructor
CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { }
CCoins() : fBlockReward(false), vout(0), nHeight(0), nVersion(0) { }
//!remove spent outputs at the end of vout
void Cleanup() {
......@@ -126,7 +126,7 @@ public:
}
void swap(CCoins &to) {
std::swap(to.fCoinBase, fCoinBase);
std::swap(to.fBlockReward, fBlockReward);
to.vout.swap(vout);
std::swap(to.nHeight, nHeight);
std::swap(to.nVersion, nVersion);
......@@ -137,7 +137,7 @@ public:
// Empty CCoins objects are always equal.
if (a.IsPruned() && b.IsPruned())
return true;
return a.fCoinBase == b.fCoinBase &&
return a.fBlockReward == b.fBlockReward &&
a.nHeight == b.nHeight &&
a.nVersion == b.nVersion &&
a.vout == b.vout;
......@@ -148,8 +148,8 @@ public:
void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const;
bool IsCoinBase() const {
return fCoinBase;
bool IsBlockReward() const {
return fBlockReward;
}
unsigned int GetSerializeSize(int nType, int nVersion) const {
......@@ -159,7 +159,7 @@ public:
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
bool fSecond = vout.size() > 1 && !vout[1].IsNull();
assert(fFirst || fSecond || nMaskCode);
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fBlockReward ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
// version
nSize += ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion);
// size of header code
......@@ -182,7 +182,7 @@ public:
bool fFirst = vout.size() > 0 && !vout[0].IsNull();
bool fSecond = vout.size() > 1 && !vout[1].IsNull();
assert(fFirst || fSecond || nMaskCode);
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fBlockReward ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
// version
::Serialize(s, VARINT(this->nVersion), nType, nVersion);
// header code
......@@ -211,7 +211,7 @@ public:
::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
// header code
::Unserialize(s, VARINT(nCode), nType, nVersion);
fCoinBase = nCode & 1;
fBlockReward = nCode & 1;
std::vector<bool> vAvail(2, false);
vAvail[0] = (nCode & 2) != 0;
vAvail[1] = (nCode & 4) != 0;
......
......@@ -310,6 +310,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
strUsage += " -maxreorg=<n> " + strprintf(_("Set the Maximum reorg depth (default: %u)"), Params(CBaseChainParams::MAIN).MaxReorganizationDepth()) + "\n";
strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
#ifndef WIN32
......@@ -1305,11 +1306,14 @@ bool AppInit2(boost::thread_group& threadGroup)
}
uiInterface.InitMessage(_("Verifying blocks..."));
fVerifying = true;
if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected");
fVerifying = false;
break;
}
fVerifying = false;
} catch(std::exception &e) {
if (fDebug) LogPrintf("%s\n", e.what());
strLoadError = _("Error opening block database");
......
This diff is collapsed.
......@@ -116,6 +116,12 @@ struct BlockHasher
size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
};
typedef std::pair<uint256, unsigned int> SPIdentifier;
struct SPHasher
{
size_t operator()(const SPIdentifier& spID) const { return spID.first.GetHash(uint256S(std::to_string(spID.second))); }
};
extern CScript COINBASE_FLAGS;
extern CCriticalSection cs_main;
extern CTxMemPool mempool;
......@@ -129,6 +135,7 @@ extern CWaitableCriticalSection csBestBlock;
extern CConditionVariable cvBlockChange;
extern bool fImporting;
extern bool fReindex;
extern bool fVerifying;
extern int nScriptCheckThreads;
extern bool fTxIndex;
extern bool fIsBareMultisigStd;
......@@ -136,12 +143,14 @@ extern bool fCheckBlockIndex;
extern size_t nCoinCacheUsage;
extern CFeeRate minRelayTxFee;
extern bool fAlerts;
extern bool fLargeWorkForkFound;
extern bool fLargeWorkInvalidChainFound;
extern std::map<uint256, int64_t> mapRejectedBlocks;
typedef uint256 PointerHash;
extern std::map<PointerHash, uint256> mapUsedStakePointers; //pointer hash matched to blockhash that it is in
/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;
......@@ -230,7 +239,7 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL);
int64_t GetBlockValue(int nHeight, const CAmount &nFees);
/** Create a new block index entry for a given block hash */
CBlockIndex * InsertBlockIndex(uint256 hash);
CBlockIndex * InsertBlockIndex(uint256 hash, bool fProofOfStake);
/** Abort with a message */
bool AbortNode(const std::string &msg, const std::string &userMessage="");
/** Get statistics from node state */
......@@ -431,7 +440,7 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
/** Store block on disk. If dbp is provided, the file is known to already reside on disk */
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL);
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
bool AcceptBlockHeader(const CBlockHeader& block, bool fProofOfStake, CValidationState& state, CBlockIndex **ppindex= NULL);
......
......@@ -171,7 +171,7 @@ public:
LOCK(cs);
return
mapSeenMasternodeBudgetProposals.count(hash) ||
//mapSeenMasternodeBudgetProposals.count(hash) ||
mapSeenMasternodeBudgetVotes.count(hash) ||
mapSeenBudgetDrafts.count(hash) ||
mapSeenBudgetDraftVotes.count(hash);
......@@ -574,53 +574,55 @@ public:
// Proposals are cast then sent to peers with this object, which leaves the votes out
class CBudgetProposalBroadcast : public CBudgetProposal
{
public:
CBudgetProposalBroadcast() : CBudgetProposal(){}
CBudgetProposalBroadcast(const CBudgetProposal& other) : CBudgetProposal(other){}
CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other) : CBudgetProposal(other){}
CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
public:
CBudgetProposalBroadcast() : CBudgetProposal(){}
CBudgetProposalBroadcast(const CBudgetProposal& other) : CBudgetProposal(other){}
CBudgetProposalBroadcast(const CBudgetProposalBroadcast& other) : CBudgetProposal(other){}
CBudgetProposalBroadcast(std::string strProposalNameIn, std::string strURLIn, int nPaymentCount, CScript addressIn, CAmount nAmountIn, int nBlockStartIn, uint256 nFeeTXHashIn);
void swap(CBudgetProposalBroadcast& first, CBudgetProposalBroadcast& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.strProposalName, second.strProposalName);
swap(first.nBlockStart, second.nBlockStart);
swap(first.strURL, second.strURL);
swap(first.nBlockEnd, second.nBlockEnd);
swap(first.nAmount, second.nAmount);
swap(first.address, second.address);
swap(first.nTime, second.nTime);
swap(first.nFeeTXHash, second.nFeeTXHash);
first.mapVotes.swap(second.mapVotes);
}
void swap(CBudgetProposalBroadcast& first, CBudgetProposalBroadcast& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.strProposalName, second.strProposalName);
swap(first.nBlockStart, second.nBlockStart);
swap(first.strURL, second.strURL);
swap(first.nBlockEnd, second.nBlockEnd);
swap(first.nAmount, second.nAmount);
swap(first.address, second.address);
swap(first.nTime, second.nTime);
swap(first.nFeeTXHash, second.nFeeTXHash);
first.mapVotes.swap(second.mapVotes);
}
CBudgetProposalBroadcast& operator=(CBudgetProposalBroadcast from)
{
swap(*this, from);
return *this;
}
CBudgetProposalBroadcast& operator=(CBudgetProposalBroadcast from)
{
swap(*this, from);
return *this;
}
void Relay();
void Relay();
ADD_SERIALIZE_METHODS;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
//for syncing with other clients
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
//for syncing with other clients
READWRITE(LIMITED_STRING(strProposalName, 20));
READWRITE(LIMITED_STRING(strURL, 64));
READWRITE(nTime);
READWRITE(nBlockStart);
READWRITE(nBlockEnd);
READWRITE(nAmount);
READWRITE(*(CScriptBase*)(&address));
READWRITE(nFeeTXHash);
}
READWRITE(LIMITED_STRING(strProposalName, 20));
READWRITE(LIMITED_STRING(strURL, 64));
READWRITE(nTime);
READWRITE(nBlockStart);
READWRITE(nBlockEnd);
READWRITE(nAmount);
READWRITE(*(CScriptBase*)(&address));
READWRITE(nFeeTXHash);
}
};
#endif
......@@ -12,6 +12,7 @@
#include "sync.h"
#include "spork.h"
#include "addrman.h"
#include "utilmoneystr.h"
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
......@@ -26,6 +27,8 @@ bool IsBlockValueValid(const CBlock& block, int64_t nExpectedValue){
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
bool fProofOfStake = block.IsProofOfStake();
int nHeight = 0;
if(pindexPrev->GetBlockHash() == block.hashPrevBlock)
{
......@@ -40,32 +43,36 @@ bool IsBlockValueValid(const CBlock& block, int64_t nExpectedValue){
LogPrintf("IsBlockValueValid() : WARNING: Couldn't find previous block");
}
CAmount nBlockCreation = block.vtx[0].GetValueOut();
if (fProofOfStake)
nBlockCreation += block.vtx[1].GetValueOut();
if(!masternodeSync.IsSynced()) { //there is no budget data to use to check anything
//super blocks will always be on these blocks, max 100 per budgeting
if(nHeight % GetBudgetPaymentCycleBlocks() < 100){
return true;
} else {
if(block.vtx[0].GetValueOut() > nExpectedValue) return false;
if (nBlockCreation > nExpectedValue) return false;
}
} else { // we're synced and have data so check the budget schedule
//are these blocks even enabled
if(!IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)){
return block.vtx[0].GetValueOut() <= nExpectedValue;
if (!IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS)) {
return nBlockCreation <= nExpectedValue;
}
if(budget.IsBudgetPaymentBlock(nHeight)){
//the value of the block is evaluated in CheckBlock
return true;
} else {
if(block.vtx[0].GetValueOut() > nExpectedValue) return false;
if (nBlockCreation > nExpectedValue) return false;
}
}
return true;
}
bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight)
bool IsBlockPayeeValid(const CAmount& nAmountCreated, const