From 65abc2081496fed54e01b6f3b43db2df6d52a665 Mon Sep 17 00:00:00 2001 From: alexhz Date: Tue, 26 Mar 2013 18:30:10 +0000 Subject: [PATCH] Fix PoS difficulty at 0.25 after blocks v3 supermajority threshold + misc fixes --- src/bitcoinrpc.cpp | 4 +++- src/init.cpp | 2 +- src/kernel.cpp | 1 + src/main.cpp | 42 ++++++++++++++++++++++++------------------ src/main.h | 17 ++++++++++++++++- src/version.h | 4 ++-- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 6dfb19c..f149dd2 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -222,7 +222,9 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPri else txinfo.push_back(tx.GetHash().GetHex()); } - result.push_back(Pair("tx", txinfo)); + + result.push_back(Pair("tx", txinfo)); + result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end()))); return result; } diff --git a/src/init.cpp b/src/init.cpp index 47be408..96ba319 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -371,7 +371,7 @@ bool AppInit2(int argc, char* argv[]) printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) - strErrors << _("Error loading blkindex.dat") << "\n"; + strErrors << _("Error loading blkindex.dat. Remove blk*.dat from your data directory and try again.") << "\n"; // as LoadBlockIndex can take several minutes, it's possible the user // requested to kill bitcoin-qt during the last operation. If so, exit. diff --git a/src/kernel.cpp b/src/kernel.cpp index 5970dcf..719d780 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -18,6 +18,7 @@ static std::map mapStakeModifierCheckpoints = boost::assign::map_list_of ( 0, 0x0e00670bu ) ( 6000, 0xb7cbc5d3u ) + ( 12661, 0x5d84115du ) ; // Get the last stake modifier and its generation time from a given block diff --git a/src/main.cpp b/src/main.cpp index 3c8a4a6..a101105 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ map mapBlockIndex; set > setStakeSeen; uint256 hashGenesisBlock = hashGenesisBlockOfficial; static CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); +static CBigNum bnProofOfStakeLimit(~uint256(0) >> 30); static CBigNum bnInitialHashTarget(~uint256(0) >> 20); unsigned int nStakeMinAge = STAKE_MIN_AGE; int nCoinbaseMaturity = COINBASE_MATURITY_PPC; @@ -916,8 +917,10 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { + CBigNum bnTargetLimit = (fProofOfStake && CBlockIndex::IsSuperMajority(3, pindexLast, 950, 1000)) ? bnProofOfStakeLimit : bnProofOfWorkLimit; + if (pindexLast == NULL) - return bnProofOfWorkLimit.GetCompact(); // genesis block + return bnTargetLimit.GetCompact(); // genesis block const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); if (pindexPrev->pprev == NULL) @@ -937,8 +940,8 @@ unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fP bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); - if (bnNew > bnProofOfWorkLimit) - bnNew = bnProofOfWorkLimit; + if (bnNew > bnTargetLimit) + bnNew = bnTargetLimit; return bnNew.GetCompact(); } @@ -1361,25 +1364,19 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool // already refuses previously-known transaction id's entirely. - // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. - // On testnet it is enabled as of februari 20, 2012, 0:00 UTC. - if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000)) + BOOST_FOREACH(CTransaction& tx, vtx) { - BOOST_FOREACH(CTransaction& tx, vtx) + CTxIndex txindexOld; + if (txdb.ReadTxIndex(tx.GetHash(), txindexOld)) { - CTxIndex txindexOld; - if (txdb.ReadTxIndex(tx.GetHash(), txindexOld)) - { - BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) - if (pos.IsNull()) - return false; - } + BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) + if (pos.IsNull()) + return false; } } - // BIP16 didn't become active until Apr 1 2012 (Feb 15 on testnet) - int64 nBIP16SwitchTime = fTestNet ? 1329264000 : 1333238400; - bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); + // BIP16 always active + bool fStrictPayToScriptHash = true; //// issue here: it doesn't know the version unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size()); @@ -1962,6 +1959,15 @@ bool CBlock::AcceptBlock() if (!Checkpoints::CheckSync(hash, pindexPrev)) return error("AcceptBlock() : rejected by synchronized checkpoint"); + // Reject block.nVersion < 3 blocks when 95% (75% on testnet) of the network has upgraded: + if (nVersion < 3) + { + if ((!fTestNet && CBlockIndex::IsSuperMajority(3, pindexPrev, 950, 1000)) || (fTestNet && CBlockIndex::IsSuperMajority(3, pindexPrev, 75, 100))) + { + return error("CheckBlock() : rejected nVersion < 3 block"); + } + } + if(nHeight > 0) { CScript expect = CScript() << nHeight; @@ -2496,7 +2502,7 @@ string GetWarnings(string strFor) // ppcoin: should not enter safe mode for longer invalid chain // ppcoin: if sync-checkpoint is too old do not enter safe mode - if (Checkpoints::IsSyncCheckpointTooOld(60 * 60 * 24 * 10) && !fTestNet) + if (Checkpoints::IsSyncCheckpointTooOld(60 * 60 * 24 * 10) && !fTestNet && !IsInitialBlockDownload()) { nPriority = 100; strStatusBar = "WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers."; diff --git a/src/main.h b/src/main.h index e3f454f..e4c596f 100644 --- a/src/main.h +++ b/src/main.h @@ -928,7 +928,7 @@ public: void SetNull() { - nVersion = 2; + nVersion = 3; hashPrevBlock = 0; hashMerkleRoot = 0; nTime = 0; @@ -1365,6 +1365,18 @@ public: return (nFlags & BLOCK_PROOF_OF_STAKE); } + static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) + { + unsigned int nFound = 0; + for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + return (nFound >= nRequired); + } + void SetProofOfStake() { nFlags |= BLOCK_PROOF_OF_STAKE; @@ -1422,11 +1434,13 @@ class CDiskBlockIndex : public CBlockIndex public: uint256 hashPrev; uint256 hashNext; + int nProtocolVersion; CDiskBlockIndex() { hashPrev = 0; hashNext = 0; + nProtocolVersion = PROTOCOL_VERSION; } explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) @@ -1448,6 +1462,7 @@ public: READWRITE(nMoneySupply); READWRITE(nFlags); READWRITE(nStakeModifier); + READWRITE(nProtocolVersion); if (IsProofOfStake()) { READWRITE(prevoutStake); diff --git a/src/version.h b/src/version.h index 7aa3405..a2b8dd2 100644 --- a/src/version.h +++ b/src/version.h @@ -30,14 +30,14 @@ extern const std::string CLIENT_DATE; // ppcoin version - intended for display purpose ONLY #define PPCOIN_VERSION_MAJOR 0 #define PPCOIN_VERSION_MINOR 3 -#define PPCOIN_VERSION_REVISION 2 +#define PPCOIN_VERSION_REVISION 3 #define PPCOIN_VERSION_BUILD 0 // // network protocol versioning // -static const int PROTOCOL_VERSION = 60003; +static const int PROTOCOL_VERSION = 60004; // earlier versions not supported as of Feb 2012, and are disconnected // NOTE: as of bitcoin v0.6 message serialization (vSend, vRecv) still -- 1.7.1