From: alex Date: Mon, 29 Jul 2013 22:12:14 +0000 (+0400) Subject: Use uint256 instead of CBigNum for ChainTrust X-Git-Tag: v0.4.4-nvc~19 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=3fca9acedf650c25da89ed500fe52c13505d65e6 Use uint256 instead of CBigNum for ChainTrust --- diff --git a/src/bignum.h b/src/bignum.h index c214275..9d93b00 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -235,7 +235,7 @@ public: BN_mpi2bn(pch, p - pch, this); } - uint256 getuint256() + uint256 getuint256() const { unsigned int nSize = BN_bn2mpi(this, NULL); if (nSize < 4) diff --git a/src/db.cpp b/src/db.cpp index e6f66ca..13a59fd 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -649,7 +649,7 @@ bool CTxDB::LoadBlockIndex() if (fRequestShutdown) return true; - // Calculate bnChainTrust + // Calculate nChainTrust vector > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) @@ -661,7 +661,7 @@ bool CTxDB::LoadBlockIndex() BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; - pindex->bnChainTrust = (pindex->pprev ? pindex->pprev->bnChainTrust : 0) + pindex->GetBlockTrust(); + pindex->nChainTrust = (pindex->pprev ? pindex->pprev->nChainTrust : 0) + pindex->GetBlockTrust(); // ppcoin: calculate stake modifier checksum pindex->nStakeModifierChecksum = GetStakeModifierChecksum(pindex); if (!CheckStakeModifierCheckpoints(pindex->nHeight, pindex->nStakeModifierChecksum)) @@ -679,9 +679,9 @@ bool CTxDB::LoadBlockIndex() return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; - bnBestChainTrust = pindexBest->bnChainTrust; + nBestChainTrust = pindexBest->nChainTrust; printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", - hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); // ppcoin: load hashSyncCheckpoint @@ -690,7 +690,9 @@ bool CTxDB::LoadBlockIndex() printf("LoadBlockIndex(): synchronized checkpoint %s\n", Checkpoints::hashSyncCheckpoint.ToString().c_str()); // Load bnBestInvalidTrust, OK if it doesn't exist + CBigNum bnBestInvalidTrust; ReadBestInvalidTrust(bnBestInvalidTrust); + nBestInvalidTrust = bnBestInvalidTrust.getuint256(); // Verify blocks in the best chain int nCheckLevel = GetArg("-checklevel", 1); diff --git a/src/main.cpp b/src/main.cpp index af4e190..19d67a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,7 +37,7 @@ CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty CBigNum bnProofOfStakeLimit(~uint256(0) >> 27); // proof of stake target limit since 20 June 2013, equal to 0.03125 proof of stake difficulty CBigNum bnProofOfStakeHardLimit(~uint256(0) >> 30); // disabled temporarily, will be used in the future to fix minimal proof of stake difficulty at 0.25 -CBigNum bnPoWBase = CBigNum(uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000")); // difficulty-1 target +uint256 nPoWBase = uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000"); // difficulty-1 target CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16); @@ -49,8 +49,10 @@ unsigned int nModifierInterval = 6 * 60 * 60; // time to elapse before new modif int nCoinbaseMaturity = 500; CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; -CBigNum bnBestChainTrust = 0; -CBigNum bnBestInvalidTrust = 0; + +uint256 nBestChainTrust = 0; +uint256 nBestInvalidTrust = 0; + uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; int64 nTimeBestReceived = 0; @@ -1190,24 +1192,24 @@ bool IsInitialBlockDownload() void static InvalidChainFound(CBlockIndex* pindexNew) { - if (pindexNew->bnChainTrust > bnBestInvalidTrust) + if (pindexNew->nChainTrust > nBestInvalidTrust) { - bnBestInvalidTrust = pindexNew->bnChainTrust; - CTxDB().WriteBestInvalidTrust(bnBestInvalidTrust); + nBestInvalidTrust = pindexNew->nChainTrust; + CTxDB().WriteBestInvalidTrust(CBigNum(nBestInvalidTrust)); uiInterface.NotifyBlocksChanged(); } - CBigNum bnBestInvalidBlockTrust = pindexNew->bnChainTrust - pindexNew->pprev->bnChainTrust; - CBigNum bnBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->bnChainTrust - pindexBest->pprev->bnChainTrust) : pindexBest->bnChainTrust; + uint256 nBestInvalidBlockTrust = pindexNew->nChainTrust - pindexNew->pprev->nChainTrust; + uint256 nBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->nChainTrust - pindexBest->pprev->nChainTrust) : pindexBest->nChainTrust; - printf("InvalidChainFound: invalid block=%s height=%d trust=%s blocktrust=%s date=%s\n", + printf("InvalidChainFound: invalid block=%s height=%d trust=%s blocktrust=%"PRI64d" date=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, - pindexNew->bnChainTrust.ToString().c_str(), bnBestInvalidBlockTrust.ToString().c_str(), + CBigNum(pindexNew->nChainTrust).ToString().c_str(), nBestInvalidBlockTrust.Get64(), DateTimeStrFormat("%x %H:%M:%S", pindexNew->GetBlockTime()).c_str()); - printf("InvalidChainFound: current best=%s height=%d trust=%s blocktrust=%s date=%s\n", - hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, - bnBestChainTrust.ToString().c_str(), - bnBestBlockTrust.ToString().c_str(), + printf("InvalidChainFound: current best=%s height=%d trust=%s blocktrust=%"PRI64d" date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, + CBigNum(pindexBest->nChainTrust).ToString().c_str(), + nBestBlockTrust.Get64(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); } @@ -1845,7 +1847,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // Reorganize is costly in terms of db load, as it works in a single db transaction. // Try to limit how much needs to be done inside - while (pindexIntermediate->pprev && pindexIntermediate->pprev->bnChainTrust > pindexBest->bnChainTrust) + while (pindexIntermediate->pprev && pindexIntermediate->pprev->nChainTrust > pindexBest->nChainTrust) { vpindexSecondary.push_back(pindexIntermediate); pindexIntermediate = pindexIntermediate->pprev; @@ -1894,15 +1896,16 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) pindexBest = pindexNew; pblockindexFBBHLast = NULL; nBestHeight = pindexBest->nHeight; - bnBestChainTrust = pindexNew->bnChainTrust; + nBestChainTrust = pindexNew->nChainTrust; nTimeBestReceived = GetTime(); nTransactionsUpdated++; - CBigNum bnBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->bnChainTrust - pindexBest->pprev->bnChainTrust) : pindexBest->bnChainTrust; + uint256 nBestBlockTrust = pindexBest->nHeight != 0 ? (pindexBest->nChainTrust - pindexBest->pprev->nChainTrust) : pindexBest->nChainTrust; - printf("SetBestChain: new best=%s height=%d trust=%s blocktrust=%s date=%s\n", - hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), - bnBestBlockTrust.ToString().c_str(), + printf("SetBestChain: new best=%s height=%d trust=%s blocktrust=%"PRI64d" date=%s\n", + hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, + CBigNum(nBestChainTrust).ToString().c_str(), + nBestBlockTrust.Get64(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); // Check the version of the last 100 blocks to see if we need to upgrade: @@ -2022,7 +2025,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } // ppcoin: compute chain trust score - pindexNew->bnChainTrust = (pindexNew->pprev ? pindexNew->pprev->bnChainTrust : 0) + pindexNew->GetBlockTrust(); + pindexNew->nChainTrust = (pindexNew->pprev ? pindexNew->pprev->nChainTrust : 0) + pindexNew->GetBlockTrust(); // ppcoin: compute stake entropy bit for stake modifier if (!pindexNew->SetStakeEntropyBit(GetStakeEntropyBit(pindexNew->nHeight))) @@ -2061,7 +2064,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) return false; // New best - if (pindexNew->bnChainTrust > bnBestChainTrust) + if (pindexNew->nChainTrust > nBestChainTrust) if (!SetBestChain(txdb, pindexNew)) return false; @@ -2279,7 +2282,7 @@ bool CBlock::AcceptBlock() return true; } -CBigNum CBlockIndex::GetBlockTrust() const +uint256 CBlockIndex::GetBlockTrust() const { CBigNum bnTarget; bnTarget.SetCompact(nBits); @@ -2289,27 +2292,29 @@ CBigNum CBlockIndex::GetBlockTrust() const /* Old protocol, will be removed later */ if (!fTestNet && GetBlockTime() < CHAINCHECKS_SWITCH_TIME) - return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); + return (IsProofOfStake()? ((CBigNum(1)<<256) / (bnTarget+1)).getuint256() : 1); /* New protocol */ // Calculate work amount for block - CBigNum bnPoWTrust = bnPoWBase / (bnTarget+1); + uint256 nPoWTrust = (CBigNum(nPoWBase) / (bnTarget+1)).getuint256(); - // Set bnPowTrust to 1 if we are checking PoS block or PoW difficulty is too low - bnPoWTrust = (IsProofOfStake() || bnPoWTrust < 1) ? 1 : bnPoWTrust; + // Set nPowTrust to 1 if we are checking PoS block or PoW difficulty is too low + nPoWTrust = (IsProofOfStake() || nPoWTrust < 1) ? 1 : nPoWTrust; - // Return bnPoWTrust for the first 12 blocks + // Return nPoWTrust for the first 12 blocks if (pprev == NULL || pprev->nHeight < 12) - return bnPoWTrust; + return nPoWTrust; const CBlockIndex* currentIndex = pprev; if(IsProofOfStake()) { + CBigNum bnNewTrust = (CBigNum(1)<<256) / (bnTarget+1); + // Return 1/3 of score if parent block is not the PoW block if (!pprev->IsProofOfWork()) - return (CBigNum(1)<<256) / (3 * (bnTarget+1)); + return (bnNewTrust / 3).getuint256(); int nPoWCount = 0; @@ -2323,15 +2328,17 @@ CBigNum CBlockIndex::GetBlockTrust() const // Return 1/3 of score if less than 3 PoW blocks found if (nPoWCount < 3) - return (CBigNum(1)<<256) / (3 * (bnTarget+1)); + return (bnNewTrust / 3).getuint256(); - return (CBigNum(1)<<256) / (bnTarget+1); + return bnNewTrust.getuint256(); } else { - // Return bnPoWTrust + 2/3 of previous block score if two parent blocks are not PoS blocks + CBigNum bnLastBlockTrust = CBigNum(pprev->nChainTrust - pprev->pprev->nChainTrust); + + // Return nPoWTrust + 2/3 of previous block score if two parent blocks are not PoS blocks if (!(pprev->IsProofOfStake() && pprev->pprev->IsProofOfStake())) - return bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3); + return nPoWTrust + (2 * bnLastBlockTrust / 3).getuint256(); int nPoSCount = 0; @@ -2343,17 +2350,19 @@ CBigNum CBlockIndex::GetBlockTrust() const currentIndex = currentIndex->pprev; } - // Return bnPoWTrust + 2/3 of previous block score if less than 7 PoS blocks found + // Return nPoWTrust + 2/3 of previous block score if less than 7 PoS blocks found if (nPoSCount < 7) - return bnPoWTrust + (2 * (pprev->bnChainTrust - pprev->pprev->bnChainTrust) / 3); + return nPoWTrust + (2 * bnLastBlockTrust / 3).getuint256(); bnTarget.SetCompact(pprev->nBits); if (bnTarget <= 0) return 0; - // Return bnPoWTrust + full trust score for previous block nBits - return bnPoWTrust + (CBigNum(1)<<256) / (bnTarget+1); + CBigNum bnNewTrust = (CBigNum(1)<<256) / (bnTarget+1); + + // Return nPoWTrust + full trust score for previous block nBits + return nPoWTrust + bnNewTrust.getuint256(); } } diff --git a/src/main.h b/src/main.h index 555a312..efc1ca2 100644 --- a/src/main.h +++ b/src/main.h @@ -67,8 +67,8 @@ extern CBlockIndex* pindexGenesisBlock; extern unsigned int nStakeMinAge; extern int nCoinbaseMaturity; extern int nBestHeight; -extern CBigNum bnBestChainTrust; -extern CBigNum bnBestInvalidTrust; +extern uint256 nBestChainTrust; +extern uint256 nBestInvalidTrust; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; @@ -1131,7 +1131,7 @@ public: CBlockIndex* pnext; unsigned int nFile; unsigned int nBlockPos; - CBigNum bnChainTrust; // ppcoin: trust score of block chain + uint256 nChainTrust; // ppcoin: trust score of block chain int nHeight; int64 nMint; @@ -1168,7 +1168,7 @@ public: nFile = 0; nBlockPos = 0; nHeight = 0; - bnChainTrust = 0; + nChainTrust = 0; nMint = 0; nMoneySupply = 0; nFlags = 0; @@ -1193,7 +1193,7 @@ public: nFile = nFileIn; nBlockPos = nBlockPosIn; nHeight = 0; - bnChainTrust = 0; + nChainTrust = 0; nMint = 0; nMoneySupply = 0; nFlags = 0; @@ -1242,7 +1242,7 @@ public: return (int64)nTime; } - CBigNum GetBlockTrust() const; + uint256 GetBlockTrust() const; bool IsInMainChain() const { diff --git a/src/uint256.h b/src/uint256.h index abd0b71..66e9b91 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -55,6 +55,16 @@ public: return ret; } + double getdouble() const + { + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; + } base_uint& operator=(uint64 b) { @@ -354,27 +364,23 @@ public: return pn[2*n] | (uint64)pn[2*n+1] << 32; } -// unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const unsigned int GetSerializeSize(int nType, int nVersion) const { return sizeof(pn); } template -// void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const void Serialize(Stream& s, int nType, int nVersion) const { s.write((char*)pn, sizeof(pn)); } template -// void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) void Unserialize(Stream& s, int nType, int nVersion) { s.read((char*)pn, sizeof(pn)); } - friend class uint160; friend class uint256; friend inline int Testuint256AdHoc(std::vector vArg); @@ -383,8 +389,6 @@ public: typedef base_uint<160> base_uint160; typedef base_uint<256> base_uint256; - - // // uint160 and uint256 could be implemented as templates, but to keep // compile errors and debugging cleaner, they're copy and pasted.